<commit_before>extern crate bytes;
extern crate env_logger;
extern crate mio;
#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;
extern crate failure;
extern crate slab;

use clap::{App, Arg};
use failure::Error;
use failure::ResultExt;
use mio::net::{TcpListener, TcpStream};
use slab::Slab;
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::ops;

#[derive(Debug)]
enum MiChatCommand {
    Broadcast(String),
    NewConnection(TcpStream),
}

struct MiChat {
    connections: Slab<EventHandler>,
}

trait RuleHandler {
    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready);
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error>;
    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error>;
    fn is_closed(&self) -> bool;
}

impl MiChat {
    fn new() -> MiChat {
        MiChat {
            connections: Slab::new(),
        }
    }

    fn listen(&mut self, event_loop: &mut mio::Poll, listener: TcpListener) -> Result<(), Error> {
        let token = {
            let e = self.connections.vacant_entry();
            let token = mio::Token(e.key());
            let l = EventHandler::Listener(Listener::new(listener, token));
            e.insert(l);
            token
        };
        &self.connections[token.into()].register(event_loop, token)?;
        Ok(())
    }

    fn process_action(&mut self, msg: MiChatCommand, event_loop: &mut mio::Poll) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            MiChatCommand::Broadcast(s) => self.process_broadcast(s),
            MiChatCommand::NewConnection(socket) => self.process_new_connection(event_loop, socket),
        }
    }

    fn process_broadcast(&mut self, s: String) {
        for c in self.client_connections_mut() {
            c.enqueue(&s);
        }
    }

    fn process_new_connection(&mut self, event_loop: &mut mio::Poll, socket: mio::tcp::TcpStream) {
        let token = {
            let e = self.connections.vacant_entry();
            let token = mio::Token(e.key());
            let l = EventHandler::Conn(Connection::new(socket, token));
            e.insert(l);
            token
        };
        &self.connections[token.into()].register(event_loop, token);
    }

    fn client_connections_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut Connection> + 'a {
        self.connections.iter_mut().filter_map(|(_, it)| match it {
            &mut EventHandler::Conn(ref mut c) => Some(c),
            _ => None,
        })
    }
}

#[derive(Debug)]
struct Connection {
    socket: TcpStream,
    sock_status: mio::Ready,
    token: mio::Token,
    read_buf: Vec<u8>,
    read_eof: bool,
    failed: bool,
    write_buf: Vec<u8>,
}

impl RuleHandler for Connection {
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .register(
                &self.socket,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("event loop register")?;
            Ok(())
    }

    // Event updates arrive here
    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready) {
        self.sock_status.insert(events);
        info!(
            "Connection::handle_event: {:?}; this time: {:?}; now: {:?}",
            self.socket.peer_addr(),
            events,
            self.sock_status
        );
    }

    // actions are processed here on down.

    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error> {
        if self.sock_status.is_readable() {
            self.sock_status.remove(mio::Ready::readable());
            self.read()?;
        }

        self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.sock_status.remove(mio::Ready::writable());
            self.write()?;
        }

        if !self.is_closed() {
            self.reregister(event_loop)?;
        }

        Ok(())
    }

    fn is_closed(&self) -> bool {
        self.failed || (self.read_eof && self.write_buf.is_empty())
    }
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token) -> Connection {
        Connection {
            socket: socket,
            sock_status: mio::Ready::empty(),
            token: token,
            read_buf: Vec::with_capacity(1024),
            write_buf: Vec::new(),
            read_eof: false,
            failed: false,
        }
    }
    fn process_buffer(&mut self, to_parent: &mut FnMut(MiChatCommand)) {
        let mut prev = 0;
        info!(
            "{:?}: Read buffer: {:?}",
            self.socket.peer_addr(),
            self.read_buf
        );
        for n in self.read_buf.iter().enumerate().filter_map(|(i, e)| {
            if *e == '\n' as u8 {
                Some(i)
            } else {
                None
            }
        }) {
            info!(
                "{:?}: Pos: {:?}; chunk: {:?}",
                self.socket.peer_addr(),
                n,
                &self.read_buf[prev..n]
            );
            let s = String::from_utf8_lossy(&self.read_buf[prev..n]).to_string();
            let cmd = MiChatCommand::Broadcast(s);
            info!("Send! {:?}", cmd);
            to_parent(cmd);
            prev = n + 1;
        }
        let remainder = self.read_buf[prev..].to_vec();
        info!(
            "{:?}: read Remainder: {}",
            self.socket.peer_addr(),
            remainder.len()
        );
        self.read_buf = remainder;
    }

    fn read(&mut self) -> Result<(), Error> {
        let mut abuf = vec![0; 1024];
        match self.socket.read(&mut abuf).context("Reading socket")? {
            0 => {
                info!("{:?}: EOF!", self.socket.peer_addr());
                self.read_eof = true;
                Ok(())
            }
            n => {
                info!("{:?}: Read {}bytes", self.socket.peer_addr(), n);
                self.read_buf.extend(&abuf[0..n]);
                Ok(())
            }
        }
    }

    fn write(&mut self) -> Result<(), Error> {
        let n = self
            .socket
            .write(&mut self.write_buf)
            .context("writing buffer")?;
        info!(
            "{:?}: Wrote {} of {} in buffer",
            self.socket.peer_addr(),
            n,
            self.write_buf.len()
        );
        self.write_buf = self.write_buf[n..].to_vec();
        info!(
            "{:?}: Now {:?}b",
            self.socket.peer_addr(),
            self.write_buf.len()
        );
        Ok(())
    }

    fn reregister(&mut self, event_loop: &mut mio::Poll) -> Result<(), Error> {
        let mut flags = mio::Ready::readable();
        if !self.write_buf.is_empty() {
            flags.insert(mio::Ready::writable());
        }
        info!("Registering {:?} with {:?}", self, flags);

        event_loop
            .reregister(&self.socket, self.token, flags, mio::PollOpt::oneshot())
            .context("EventLoop#reregister")?;

        Ok(())
    }

    fn enqueue(&mut self, s: &str) {
        self.write_buf.extend(s.as_bytes());
        self.write_buf.push('\n' as u8);
    }
}

#[derive(Debug)]
struct Listener {
    listener: TcpListener,
    sock_status: mio::Ready,
    token: mio::Token,
}

impl Listener {
    fn new(listener: TcpListener, token: mio::Token) -> Listener {
        Listener {
            listener: listener,
            sock_status: mio::Ready::empty(),
            token: token,
        }
    }
    fn reregister(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .reregister(
                &self.listener,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("Register listener")?;
            Ok(())
    }
}

impl RuleHandler for Listener {
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .register(
                &self.listener,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("Register listener")?;
            Ok(())
    }

    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready) {
        assert!(events.is_readable());
        self.sock_status.insert(events);
        info!(
            "Listener::handle_event: {:?}; this time: {:?}; now: {:?}",
            self.listener.local_addr(),
            events,
            self.sock_status
        );
    }
    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error> {
        if self.sock_status.is_readable() {
            info!("the listener socket is ready to accept a connection");
            self.sock_status.remove(mio::Ready::readable());
            match self.listener.accept().context("Accept listening socket")? {
                (socket, _client) => {
                    let cmd = MiChatCommand::NewConnection(socket);
                    to_parent(cmd);
                }
            }

            self.reregister(event_loop, self.token)?;
        }
        Ok(())
    }

    fn is_closed(&self) -> bool {
        false
    }
}

#[derive(Debug)]
enum EventHandler {
    Listener(Listener),
    Conn(Connection),
}

impl ops::Deref for EventHandler {
    type Target = RuleHandler;
    fn deref(&self) -> &Self::Target {
        match self {
            &EventHandler::Conn(ref conn) => conn,
            &EventHandler::Listener(ref listener) => listener,
        }
    }
}
impl ops::DerefMut for EventHandler {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            &mut EventHandler::Conn(ref mut conn) => conn,
            &mut EventHandler::Listener(ref mut listener) => listener,
        }
    }
}

impl MiChat {
    fn ready(&mut self, event_loop: &mut mio::Poll, token: mio::Token, events: mio::Ready) {
        info!("{:?}: {:?}", token, events);
        self.connections[token.into()].handle_event(event_loop, events);
        if self.connections[token.into()].is_closed() {
            info!("Removing; {:?}", token);
            self.connections.remove(token.into());
        }

        let mut parent_actions = VecDeque::new();
        let mut failed = Vec::new();
        loop {
            for (idx, conn) in self.connections.iter_mut() {
                if let Err(e) =
                    conn.process_rules(event_loop, &mut |action| parent_actions.push_back(action))
                {
                    failed.push(idx);
                    error!("Error on connection {:?}; Dropping: {:?}", idx, e);
                }
            }
            for idx in failed.drain(..) {
                self.connections.remove(idx);
            }
            // Anything left to process?
            if parent_actions.is_empty() {
                break;
            }

            for action in parent_actions.drain(..) {
                self.process_action(action, event_loop);
            }
        }
    }

    fn run(&mut self, event_loop: &mut mio::Poll) {
        loop {
            self.run_once(event_loop);
        }
    }
    fn run_once(&mut self, event_loop: &mut mio::Poll) {
        let mut events = mio::Events::with_capacity(1024);
        event_loop.poll(&mut events, None).expect("Poll");
        for ev in &events {
            self.ready(event_loop, ev.token(), ev.readiness())
        }
    }
}

fn main() {
    env_logger::init();
    let matches = App::new("michat")
        .arg(
            Arg::with_name("bind")
                .short("l")
                .takes_value(true)
                .required(true),
        ).get_matches();

    let address = value_t_or_exit!(matches.value_of("bind"), std::net::SocketAddr);
    let listener = TcpListener::bind(&address).expect("bind");

    let mut event_loop = mio::Poll::new().expect("Create event loop");
    let mut service = MiChat::new();

    service.listen(&mut event_loop, listener).expect("Starting listener");
    info!("running michat listener at: {:?}", address);
    service.run(&mut event_loop);
}
<commit_msg>Top-level errors in run loop.<commit_after>extern crate bytes;
extern crate env_logger;
extern crate mio;
#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;
extern crate failure;
extern crate slab;

use clap::{App, Arg};
use failure::Error;
use failure::ResultExt;
use mio::net::{TcpListener, TcpStream};
use slab::Slab;
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::ops;

#[derive(Debug)]
enum MiChatCommand {
    Broadcast(String),
    NewConnection(TcpStream),
}

struct MiChat {
    connections: Slab<EventHandler>,
}

trait RuleHandler {
    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready);
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error>;
    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error>;
    fn is_closed(&self) -> bool;
}

impl MiChat {
    fn new() -> MiChat {
        MiChat {
            connections: Slab::new(),
        }
    }

    fn listen(&mut self, event_loop: &mut mio::Poll, listener: TcpListener) -> Result<(), Error> {
        let token = {
            let e = self.connections.vacant_entry();
            let token = mio::Token(e.key());
            let l = EventHandler::Listener(Listener::new(listener, token));
            e.insert(l);
            token
        };
        &self.connections[token.into()].register(event_loop, token)?;
        Ok(())
    }

    fn process_action(&mut self, msg: MiChatCommand, event_loop: &mut mio::Poll) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            MiChatCommand::Broadcast(s) => self.process_broadcast(s),
            MiChatCommand::NewConnection(socket) => self.process_new_connection(event_loop, socket),
        }
    }

    fn process_broadcast(&mut self, s: String) {
        for c in self.client_connections_mut() {
            c.enqueue(&s);
        }
    }

    fn process_new_connection(&mut self, event_loop: &mut mio::Poll, socket: mio::tcp::TcpStream) {
        let token = {
            let e = self.connections.vacant_entry();
            let token = mio::Token(e.key());
            let l = EventHandler::Conn(Connection::new(socket, token));
            e.insert(l);
            token
        };
        &self.connections[token.into()].register(event_loop, token);
    }

    fn client_connections_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut Connection> + 'a {
        self.connections.iter_mut().filter_map(|(_, it)| match it {
            &mut EventHandler::Conn(ref mut c) => Some(c),
            _ => None,
        })
    }
}

#[derive(Debug)]
struct Connection {
    socket: TcpStream,
    sock_status: mio::Ready,
    token: mio::Token,
    read_buf: Vec<u8>,
    read_eof: bool,
    failed: bool,
    write_buf: Vec<u8>,
}

impl RuleHandler for Connection {
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .register(
                &self.socket,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("event loop register")?;
            Ok(())
    }

    // Event updates arrive here
    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready) {
        self.sock_status.insert(events);
        info!(
            "Connection::handle_event: {:?}; this time: {:?}; now: {:?}",
            self.socket.peer_addr(),
            events,
            self.sock_status
        );
    }

    // actions are processed here on down.

    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error> {
        if self.sock_status.is_readable() {
            self.sock_status.remove(mio::Ready::readable());
            self.read()?;
        }

        self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.sock_status.remove(mio::Ready::writable());
            self.write()?;
        }

        if !self.is_closed() {
            self.reregister(event_loop)?;
        }

        Ok(())
    }

    fn is_closed(&self) -> bool {
        self.failed || (self.read_eof && self.write_buf.is_empty())
    }
}

impl Connection {
    fn new(socket: TcpStream, token: mio::Token) -> Connection {
        Connection {
            socket: socket,
            sock_status: mio::Ready::empty(),
            token: token,
            read_buf: Vec::with_capacity(1024),
            write_buf: Vec::new(),
            read_eof: false,
            failed: false,
        }
    }
    fn process_buffer(&mut self, to_parent: &mut FnMut(MiChatCommand)) {
        let mut prev = 0;
        info!(
            "{:?}: Read buffer: {:?}",
            self.socket.peer_addr(),
            self.read_buf
        );
        for n in self.read_buf.iter().enumerate().filter_map(|(i, e)| {
            if *e == '\n' as u8 {
                Some(i)
            } else {
                None
            }
        }) {
            info!(
                "{:?}: Pos: {:?}; chunk: {:?}",
                self.socket.peer_addr(),
                n,
                &self.read_buf[prev..n]
            );
            let s = String::from_utf8_lossy(&self.read_buf[prev..n]).to_string();
            let cmd = MiChatCommand::Broadcast(s);
            info!("Send! {:?}", cmd);
            to_parent(cmd);
            prev = n + 1;
        }
        let remainder = self.read_buf[prev..].to_vec();
        info!(
            "{:?}: read Remainder: {}",
            self.socket.peer_addr(),
            remainder.len()
        );
        self.read_buf = remainder;
    }

    fn read(&mut self) -> Result<(), Error> {
        let mut abuf = vec![0; 1024];
        match self.socket.read(&mut abuf).context("Reading socket")? {
            0 => {
                info!("{:?}: EOF!", self.socket.peer_addr());
                self.read_eof = true;
                Ok(())
            }
            n => {
                info!("{:?}: Read {}bytes", self.socket.peer_addr(), n);
                self.read_buf.extend(&abuf[0..n]);
                Ok(())
            }
        }
    }

    fn write(&mut self) -> Result<(), Error> {
        let n = self
            .socket
            .write(&mut self.write_buf)
            .context("writing buffer")?;
        info!(
            "{:?}: Wrote {} of {} in buffer",
            self.socket.peer_addr(),
            n,
            self.write_buf.len()
        );
        self.write_buf = self.write_buf[n..].to_vec();
        info!(
            "{:?}: Now {:?}b",
            self.socket.peer_addr(),
            self.write_buf.len()
        );
        Ok(())
    }

    fn reregister(&mut self, event_loop: &mut mio::Poll) -> Result<(), Error> {
        let mut flags = mio::Ready::readable();
        if !self.write_buf.is_empty() {
            flags.insert(mio::Ready::writable());
        }
        info!("Registering {:?} with {:?}", self, flags);

        event_loop
            .reregister(&self.socket, self.token, flags, mio::PollOpt::oneshot())
            .context("EventLoop#reregister")?;

        Ok(())
    }

    fn enqueue(&mut self, s: &str) {
        self.write_buf.extend(s.as_bytes());
        self.write_buf.push('\n' as u8);
    }
}

#[derive(Debug)]
struct Listener {
    listener: TcpListener,
    sock_status: mio::Ready,
    token: mio::Token,
}

impl Listener {
    fn new(listener: TcpListener, token: mio::Token) -> Listener {
        Listener {
            listener: listener,
            sock_status: mio::Ready::empty(),
            token: token,
        }
    }
    fn reregister(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .reregister(
                &self.listener,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("Register listener")?;
            Ok(())
    }
}

impl RuleHandler for Listener {
    fn register(&self, event_loop: &mut mio::Poll, token: mio::Token) -> Result<(), Error> {
        event_loop
            .register(
                &self.listener,
                token,
                mio::Ready::readable(),
                mio::PollOpt::edge() | mio::PollOpt::oneshot(),
            ).context("Register listener")?;
            Ok(())
    }

    fn handle_event(&mut self, _event_loop: &mut mio::Poll, events: mio::Ready) {
        assert!(events.is_readable());
        self.sock_status.insert(events);
        info!(
            "Listener::handle_event: {:?}; this time: {:?}; now: {:?}",
            self.listener.local_addr(),
            events,
            self.sock_status
        );
    }
    fn process_rules(
        &mut self,
        event_loop: &mut mio::Poll,
        to_parent: &mut FnMut(MiChatCommand),
    ) -> Result<(), Error> {
        if self.sock_status.is_readable() {
            info!("the listener socket is ready to accept a connection");
            self.sock_status.remove(mio::Ready::readable());
            match self.listener.accept().context("Accept listening socket")? {
                (socket, _client) => {
                    let cmd = MiChatCommand::NewConnection(socket);
                    to_parent(cmd);
                }
            }

            self.reregister(event_loop, self.token)?;
        }
        Ok(())
    }

    fn is_closed(&self) -> bool {
        false
    }
}

#[derive(Debug)]
enum EventHandler {
    Listener(Listener),
    Conn(Connection),
}

impl ops::Deref for EventHandler {
    type Target = RuleHandler;
    fn deref(&self) -> &Self::Target {
        match self {
            &EventHandler::Conn(ref conn) => conn,
            &EventHandler::Listener(ref listener) => listener,
        }
    }
}
impl ops::DerefMut for EventHandler {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            &mut EventHandler::Conn(ref mut conn) => conn,
            &mut EventHandler::Listener(ref mut listener) => listener,
        }
    }
}

impl MiChat {
    fn ready(&mut self, event_loop: &mut mio::Poll, token: mio::Token, events: mio::Ready) {
        info!("{:?}: {:?}", token, events);
        self.connections[token.into()].handle_event(event_loop, events);
        if self.connections[token.into()].is_closed() {
            info!("Removing; {:?}", token);
            self.connections.remove(token.into());
        }

        let mut parent_actions = VecDeque::new();
        let mut failed = Vec::new();
        loop {
            for (idx, conn) in self.connections.iter_mut() {
                if let Err(e) =
                    conn.process_rules(event_loop, &mut |action| parent_actions.push_back(action))
                {
                    failed.push(idx);
                    error!("Error on connection {:?}; Dropping: {:?}", idx, e);
                }
            }
            for idx in failed.drain(..) {
                self.connections.remove(idx);
            }
            // Anything left to process?
            if parent_actions.is_empty() {
                break;
            }

            for action in parent_actions.drain(..) {
                self.process_action(action, event_loop);
            }
        }
    }

    fn run(&mut self, event_loop: &mut mio::Poll) -> Result<(), Error> {
        loop {
            self.run_once(event_loop)?;
        }
    }
    fn run_once(&mut self, event_loop: &mut mio::Poll) -> Result<(), Error> {
        let mut events = mio::Events::with_capacity(1024);
        event_loop.poll(&mut events, None)?;
        for ev in &events {
            self.ready(event_loop, ev.token(), ev.readiness())
        }

        Ok(())
    }
}

fn main() {
    env_logger::init();
    let matches = App::new("michat")
        .arg(
            Arg::with_name("bind")
                .short("l")
                .takes_value(true)
                .required(true),
        ).get_matches();

    let address = value_t_or_exit!(matches.value_of("bind"), std::net::SocketAddr);
    let listener = TcpListener::bind(&address).expect("bind");

    let mut event_loop = mio::Poll::new().expect("Create event loop");
    let mut service = MiChat::new();

    service.listen(&mut event_loop, listener).expect("Starting listener");
    info!("running michat listener at: {:?}", address);
    service.run(&mut event_loop).expect("run");
}
<|endoftext|>


<commit_before>extern crate libc;

use libc::funcs::posix88::unistd::execvp;
use std::c_str::CString;
use std::os::last_os_error;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(&std::os::args()) {
        Err(Usage) => {
            std::os::set_exit_status(1);
            print_usage(version);
        }
        Err(Help) =>
            print_usage(version),
        Err(Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                std::os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp_easy(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[deriving(Show)]
struct Options<'a> {
    chance: int,
    exe: Option<Exe<'a>>,
}

#[deriving(Show)]
struct Exe<'a> {
    name: &'a str,
    args: Box<Vec<String>>,
}

#[deriving(Show)]
enum Exit {
    Usage,
    Help,
    Version,
}

trait Uncons<'a, T> {
    fn uncons(&self) -> Option<(&'a T, &'a [T])>;
}

impl<'a, T> Uncons<'a, T> for &'a [T] {
    fn uncons(&self) -> Option<(&'a T, &'a [T])> {
        self.head().map(|x| (x, self.tail()))
    }
}

fn parse_args(args: &Vec<String>) -> ArgParse<Options> {
    args.as_slice().tail().uncons().map_or(Err(Usage), |(s, args)| {
        if "--help" == s.as_slice() || "-h" == s.as_slice() {
            Err(Help)
        } else if "--version" == s.as_slice() || "-v" == s.as_slice() {
            Err(Version)
        } else if "--chance" == s.as_slice() || "-c" == s.as_slice() {
            args.uncons().map_or(Err(Usage), |(s, args)| {
                from_str::<int>(s.as_slice()).map_or(Err(Usage), |val| {
                    args.uncons().map_or(Ok(Options { chance: val, exe: None }), |(exe, args)| {
                        if "--" == exe.as_slice() {
                            args.uncons().map_or(Ok(Options { chance: val, exe: None }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: box args.to_vec(),
                                    })
                                })
                            })
                        } else {
                            Ok(Options {
                                chance: val,
                                exe: Some(Exe {
                                    name: exe.as_slice(),
                                    args: box args.to_vec(),
                                })
                            })
                        }
                    })
                })
            })
        } else {
            Err(Usage)
        }
    })
}

fn whack(opts: &Options) -> bool {
    std::rand::task_rng().gen_range(0, 100) > std::cmp::min(std::cmp::max(opts.chance, 0), 100)
}

fn execvp_easy(name: &str, args: Box<Vec<String>>) {
    let c_name: CString = name.to_c_str();
    let c_args: Vec<CString> = args.iter().map(|tmp| tmp.to_c_str()).collect();
    with_argv(&c_name, c_args.as_slice(), proc(c_argv) -> () unsafe {
        execvp(*c_argv, c_argv);
        fail!("executing {}: {}", name, std::os::last_os_error());
    });
}

fn with_argv<T>(prog: &CString, args: &[CString], f: proc(*mut*const libc::c_char) -> T) -> T {
    let mut ptrs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 1);

    ptrs.push(prog.as_ptr());
    ptrs.extend(args.iter().map(|tmp| tmp.as_ptr()));
    ptrs.push(ptr::null());

    f(ptrs.as_mut_ptr())
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<commit_msg>Use vector slices whenever possible<commit_after>extern crate libc;

use libc::funcs::posix88::unistd::execvp;
use std::c_str::CString;
use std::os::last_os_error;
use std::ptr;
use std::rand::Rng;

fn main() {
    let version = "0.1.0";
    match parse_args(&std::os::args()) {
        Err(Usage) => {
            std::os::set_exit_status(1);
            print_usage(version);
        }
        Err(Help) =>
            print_usage(version),
        Err(Version) =>
            print_version(version),
        Ok(opts) => {
            if whack(&opts) {
                std::os::set_exit_status(1);
            } else {
                opts.exe.map_or((), |exe| {
                    execvp_easy(exe.name, exe.args)
                });
            }
        }
    }
}

type ArgParse<T> = Result<T, Exit>;

#[deriving(Show)]
struct Options<'a> {
    chance: int,
    exe: Option<Exe<'a>>,
}

#[deriving(Show)]
struct Exe<'a> {
    name: &'a str,
    args: &'a[String],
}

#[deriving(Show)]
enum Exit {
    Usage,
    Help,
    Version,
}

trait Uncons<'a, T> {
    fn uncons(&self) -> Option<(&'a T, &'a [T])>;
}

impl<'a, T> Uncons<'a, T> for &'a [T] {
    fn uncons(&self) -> Option<(&'a T, &'a [T])> {
        self.head().map(|x| (x, self.tail()))
    }
}

fn parse_args(args: &Vec<String>) -> ArgParse<Options> {
    args.as_slice().tail().uncons().map_or(Err(Usage), |(s, args)| {
        if "--help" == s.as_slice() || "-h" == s.as_slice() {
            Err(Help)
        } else if "--version" == s.as_slice() || "-v" == s.as_slice() {
            Err(Version)
        } else if "--chance" == s.as_slice() || "-c" == s.as_slice() {
            args.uncons().map_or(Err(Usage), |(s, args)| {
                from_str::<int>(s.as_slice()).map_or(Err(Usage), |val| {
                    args.uncons().map_or(Ok(Options { chance: val, exe: None }), |(exe, args)| {
                        if "--" == exe.as_slice() {
                            args.uncons().map_or(Ok(Options { chance: val, exe: None }), |(exe, args)| {
                                Ok(Options {
                                    chance: val,
                                    exe: Some(Exe {
                                        name: exe.as_slice(),
                                        args: args,
                                    })
                                })
                            })
                        } else {
                            Ok(Options {
                                chance: val,
                                exe: Some(Exe {
                                    name: exe.as_slice(),
                                    args: args,
                                })
                            })
                        }
                    })
                })
            })
        } else {
            Err(Usage)
        }
    })
}

fn whack(opts: &Options) -> bool {
    std::rand::task_rng().gen_range(0, 100) > std::cmp::min(std::cmp::max(opts.chance, 0), 100)
}

fn execvp_easy(name: &str, args: &[String]) {
    let c_name: CString = name.to_c_str();
    let c_args: Vec<CString> = args.iter().map(|tmp| tmp.to_c_str()).collect();
    with_argv(&c_name, c_args.as_slice(), proc(c_argv) -> () unsafe {
        execvp(*c_argv, c_argv);
        fail!("executing {}: {}", name, std::os::last_os_error());
    });
}

fn with_argv<T>(prog: &CString, args: &[CString], f: proc(*mut*const libc::c_char) -> T) -> T {
    let mut ptrs: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 1);

    ptrs.push(prog.as_ptr());
    ptrs.extend(args.iter().map(|tmp| tmp.as_ptr()));
    ptrs.push(ptr::null());

    f(ptrs.as_mut_ptr())
}

fn print_usage(version: &str) {
    print_version(version);
    println!("\n\
        Usage: whacky (-c PERCENTAGE|--chance PERCENTAGE) [[--] COMMAND]\n\
          whacky, yet another randomly failing program\n\
        \n\
        Available options:\n\
          -h,--help           show this help text\n\
          -c,--chance         set success chance");
}

fn print_version(version: &str) {
    println!("whacky {}", version);
}
<|endoftext|>


<commit_before>//use std::error::Error;

#[derive(Debug)]
enum DataType {
    UnsignedLong,
    String
}

#[derive(Debug)]
struct ColumnType {
    name: String,
    data_type: DataType,
    nullable: bool
}

#[derive(Debug)]
struct TupleType {
    columns: Vec<ColumnType>
}

enum Value {
    UnsignedLong(u64),
    String(String)
}

/// The tuple trait provides type-safe access to individual values within the tuple
trait Tuple {
    fn get_unsigned_long(index: u32) -> u64;
    fn get_string(index: u32) -> String;
}

enum Operator {
    Eq,
    NotEq,
    Lt,
    LtEq,
    Gt,
    GtEq,
}

enum Expr {
    /// index into a value within the tuple
    TupleValue(u32),
    /// literal value
    Literal(Value),
    /// binary expression e.g. "age > 21"
    BinaryExpr { left: Box<Expr>, op: Operator, right: Box<Expr> },
}

//enum PlanNode {
//    TableScan,
//    IndexScan,
//    Filter,
//    Sort,
//    Project,
//    Join
//}

fn main() {

    let tt = TupleType {
        columns: vec![
            ColumnType { name: String::from("id"), data_type: DataType::UnsignedLong, nullable: false },
            ColumnType { name: String::from("name"), data_type: DataType::String, nullable: false }
        ]
    };

    println!("Tuple type: {:?}", tt);

}
<commit_msg>implement basic expression evaluation against a tuple<commit_after>#![feature(box_patterns)]

use std::error::Error;

#[derive(Debug)]
enum DataType {
    UnsignedLong,
    String
}

#[derive(Debug)]
struct ColumnType {
    name: String,
    data_type: DataType,
    nullable: bool
}

#[derive(Debug)]
struct TupleType {
    columns: Vec<ColumnType>
}

#[derive(Debug,Clone)]
enum Value {
    UnsignedLong(u64),
    String(String),
    Boolean(bool)
}

/// The tuple trait provides type-safe access to individual values within the tuple
trait Tuple {
    fn get_value(&self, index: usize) -> Result<Value, Box<Error>>;
}

#[derive(Debug)]
struct SimpleTuple {
    values: Vec<Value>
}

impl Tuple for SimpleTuple {

    fn get_value(&self, index: usize) -> Result<Value, Box<Error>> {
        Ok(self.values[index].clone())
    }

}

enum Operator {
    Eq,
    NotEq,
    Lt,
    LtEq,
    Gt,
    GtEq,
}

enum Expr {
    /// index into a value within the tuple
    TupleValue(usize),
    /// literal value
    Literal(Value),
    /// binary expression e.g. "age > 21"
    BinaryExpr { left: Box<Expr>, op: Operator, right: Box<Expr> },
}

enum PlanNode {
//    TableScan,
//    IndexScan,
    Filter(Expr),
//    Sort,
//    Project,
//    Join
}

fn evaluate(tuple: &Box<Tuple>, tt: &TupleType, expr: &Expr) -> Result<Value, Box<Error>> {

    match expr {
        &Expr::BinaryExpr { box ref left, ref op, box ref right } => {
            let left_value = evaluate(tuple, tt, left).unwrap();
            let right_value = evaluate(tuple, tt, right).unwrap();
            match op {
                &Operator::Eq => {
                    match left_value {
                        Value::UnsignedLong(l) => match right_value {
                            Value::UnsignedLong(r) => Ok(Value::Boolean(l == r)),
                            _ => Err(From::from("oops"))
                        },
                        _ => Err(From::from("oops"))
                    }
                },
                _ => Err(From::from("oops"))
            }
        },
        &Expr::TupleValue(index) => tuple.get_value(index),
        &Expr::Literal(ref value) => Ok(value.clone()),
    }

}

fn main() {

    let tt = TupleType {
        columns: vec![
            ColumnType { name: String::from("id"), data_type: DataType::UnsignedLong, nullable: false },
            ColumnType { name: String::from("name"), data_type: DataType::String, nullable: false }
        ]
    };

    println!("Tuple type: {:?}", tt);

    let data : Vec<Box<Tuple>> = vec![
        Box::new(SimpleTuple { values: vec![ Value::UnsignedLong(1), Value::String(String::from("Alice")) ] }),
        Box::new(SimpleTuple { values: vec![ Value::UnsignedLong(2), Value::String(String::from("Bob")) ] }),
    ];

    // create simple filter expression
    let filterExpr = Expr::BinaryExpr {
        left: Box::new(Expr::TupleValue(0)),
        op: Operator::Eq,
        right: Box::new(Expr::Literal(Value::UnsignedLong(2)))
    };

    //let plan = PlanNode::Filter(filterExpr);

    // iterate over tuples and evaluate the plan
    for tuple in &data {
        let x = evaluate(tuple, &tt, &filterExpr).unwrap();

        print!("filter expr evaluates to {:?}", x);
    }

}
<|endoftext|>


<commit_before>#![feature(custom_derive)]

extern crate websocket;

use std::thread;
use std::sync::{Arc, Mutex};
use std::fmt::format;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::os;
use std::env;
use std::io::Read;
use std::io::{Error,ErrorKind};
use std::string::*;
use std::collections::BTreeMap;

use std::net::UdpSocket;
use std::net::SocketAddr;

use websocket::{Server, Message, Sender, Receiver};
use websocket::header::WebSocketProtocol;
use websocket::stream::WebSocketStream;
use websocket::server::sender;

extern crate iron;

use iron::prelude::*;
use iron::status;
use iron::mime::Mime;

mod controls;
mod broadcaster;

extern crate tinyosc;
use tinyosc as osc;

extern crate serde_json;
use serde_json::Value;
use serde_json::ser;

macro_rules! try_opt {
  ($e: expr) => {
    match $e {
      Some(x) => x,
      None => return None
      }
  }
}

macro_rules! try_opt_res {
  ($e: expr, $s: expr) => {
    match $e {
      Some(x) => x,
      None => return Err(Error::new(ErrorKind::Other, $s))
      }
  }
}

fn loadString(file_name: &str) -> Option<String>
{
  let path = &Path::new(&file_name);
  let f = File::open(path);
  let mut result = String::new();
  match f {
    Ok(mut of) => {
      match of.read_to_string(&mut result) {
        Err(e) => {
          println!("err: {:?}", e);
          None
        },
        Ok(len) => {
          println!("read {} bytes", len);
          Some(result)
        },
      }
    },
    Err(e) => {
      println!("err: {:?}", e);
      None
    },
  }
}

fn main() {
  // read in the settings json.
  let args = env::args();
  let mut iter = args.skip(1); // skip the program name
  match iter.next() {
    Some(file_name) => {

      println!("loading config file: {}", file_name);
      let config = loadString(&file_name).unwrap();

      // read config file as json
      let data: Value = serde_json::from_str(&config[..]).unwrap();

      startserver(data)

    }
    None => {
      println!("no args!");
    }
  }
}

fn startserver(config: Value)
{
    let obj = config.as_object().unwrap();

    let htmlfilename =
      obj.get("htmlfile").unwrap().as_string().unwrap();
    let htmlstring = loadString(&htmlfilename[..]).unwrap();

    let guifilename =
      obj.get("guifile").unwrap().as_string().unwrap();
    let guistring = loadString(&guifilename[..]).unwrap();

    println!("config: {:?}", config);

    let ip = String::new() +
      obj.get("ip").unwrap().as_string().unwrap();

    let wip = String::new() +
      obj.get("wip").unwrap().as_string().unwrap();

    let oscrecvip = String::new() +
      obj.get("oscrecvip").unwrap().as_string().unwrap();

    let oscsendip = String::new() +
      obj.get("oscsendip").unwrap().as_string().unwrap();

    // deserialize the gui string into json.
    let guival: Value = serde_json::from_str(&guistring[..]).unwrap();
    let blah = controls::deserializeRoot(&guival).unwrap();

    println!("title: {} count: {} ",
      blah.title, blah.rootControl.controlType());
    println!("controls: {:?}", blah.rootControl);

    // from control tree, make a map of ids->controls.
    let mapp = controls::makeControlMap(&*blah.rootControl);
    let cnm = controls::controlMapToNameMap(&mapp);

    let cm = Arc::new(Mutex::new(mapp));

    let guijson = String::new() + &guistring[..];

    // let oscsocket = try!(UdpSocket::bind(&oscrecvip[..]));
    let oscsocket = UdpSocket::bind(&oscrecvip[..]).unwrap();
    let mut bc = broadcaster::Broadcaster::new();
    let wsos = oscsocket.try_clone().unwrap();
    let wscm = cm.clone();
    let wsbc = bc.clone();
    let wsoscsendip = oscsendip.clone();

    thread::spawn(move || {
      oscmain(oscsocket, oscsendip, bc, cm, cnm)
      });

    thread::spawn(move || {
      websockets_main(wip, guijson, wscm, wsbc, wsoscsendip, wsos);
      });

    Iron::new(move |req: &mut Request| {
        let content_type = "text/html".parse::<Mime>().unwrap();
        Ok(Response::with((content_type, status::Ok, &*htmlstring)))
    }).http(&ip[..]).unwrap();
}

fn websockets_main( ipaddr: String,
                    aSConfig: String,
                    cm: Arc<Mutex<controls::controlMap>>,
                    broadcaster: broadcaster::Broadcaster,
                    oscsendip: String,
                    oscsocket: UdpSocket )
{
	let server = Server::bind(&ipaddr[..]).unwrap();

	for connection in server {

    println!("new websockets connection!");
		// Spawn a new thread for each connection.
    let blah = String::new() + &aSConfig[..];

    let scm = cm.clone();

    let osock = oscsocket.try_clone().unwrap();
    let osend = oscsendip.clone();

    let mut broadcaster = broadcaster.clone();

    thread::spawn(move || {
      // Get the request
			let request = connection.unwrap().read_request().unwrap();
      // Keep the headers so we can check them
			let headers = request.headers.clone();

			request.validate().unwrap(); // Validate the request

			let mut response = request.accept(); // Form a response

			if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
				if protocols.contains(&("rust-websocket".to_string())) {
					// We have a protocol we want to use
					response.headers.set(WebSocketProtocol(vec!["rust-websocket".to_string()]));
				}
			}

			let mut client = response.send().unwrap(); // Send the response

			let ip = client.get_mut_sender()
				.get_mut()
				.peer_addr()
				.unwrap();

			println!("Connection from {}", ip);

      let message = Message::Text(blah);
			client.send_message(message.clone()).unwrap();

			let (sender, mut receiver) = client.split();

      let sendmeh = Arc::new(Mutex::new(sender));

      broadcaster.register(sendmeh.clone());

			for message in receiver.incoming_messages() {
				let message = message.unwrap();
        println!("message: {:?}", message);

        let replyy = Message::Text("replyyyblah".to_string());

				match message {
					Message::Close(_) => {
						let message = Message::Close(None);
            let mut sender = sendmeh.lock().unwrap();
						sender.send_message(message).unwrap();
						println!("Client {} disconnected", ip);
						return;
					}
					Message::Ping(data) => {
            println!("Message::Ping(data)");
						let message = Message::Pong(data);
            let mut sender = sendmeh.lock().unwrap();
						sender.send_message(message).unwrap();
					}
          Message::Text(texxt) => {
            let jsonval: Value = serde_json::from_str(&texxt[..]).unwrap();
            let s_um = controls::decodeUpdateMessage(&jsonval);
            match s_um {
              Some(updmsg) => {
                let mut scmun = scm.lock().unwrap();
                let cntrl = scmun.get_mut(controls::getUmId(&updmsg));
                match cntrl {
                  Some(x) => {
                    (*x).update(&updmsg);
                    println!("some x: {:?}", *x);
                    broadcaster.broadcast_others(&ip, Message::Text(texxt));
                    match ctrlUpdateToOsc(&updmsg, &**x) {
                      Ok(v) => osock.send_to(&v, &osend[..]),
                      _ => Err(Error::new(ErrorKind::Other, "meh"))
                    };
                    ()
                  },
                  None => println!("none"),
                }
              },
              _ => println!("uknown msg"),
            }
          },
					_ => {
            println!("sending replyy");
            let mut sender = sendmeh.lock().unwrap();
            sender.send_message(replyy).unwrap()
          }
				}
			}
		});
	}
}

fn ctrlUpdateToOsc(um: &controls::UpdateMsg, ctrl: &controls::Control) -> Result<Vec<u8>, Error>
{
  match um {
    &controls::UpdateMsg::Button { controlId: ref id
             , updateType: ref ut
             } => {
      // find the control in the map.
      let mut arghs = Vec::new();
      arghs.push (
        match ut {
          &controls::ButtonUpType::Pressed => osc::Argument::s("b_pressed"),
          &controls::ButtonUpType::Unpressed => osc::Argument::s("b_unpressed"),
        });
      let msg = osc::Message { path: ctrl.oscname(), arguments: arghs };
      msg.serialize()
    },
    &controls::UpdateMsg::Slider  { controlId: ref id
            , updateType: ref ut
            , location: ref loc
            } => {
      let mut arghs = Vec::new();
      arghs.push (
        match ut {
          &controls::SliderUpType::Pressed => osc::Argument::s("s_pressed"),
          &controls::SliderUpType::Moved => osc::Argument::s("s_moved"),
          &controls::SliderUpType::Unpressed => osc::Argument::s("s_unpressed"),
        });
      let l = *loc as f32;
      arghs.push(osc::Argument::f(l));
      let msg = osc::Message { path: ctrl.oscname(), arguments: arghs };
      msg.serialize()
    },
  }
}

fn oscToCtrlUpdate(om: &osc::Message, cnm: &controls::controlNameMap) -> Result<controls::UpdateMsg, Error>
{
  // find the control by name.
  let cid = try_opt_res!(cnm.get(om.path), "control name not found!");

  match om.arguments.len() {
    1 => {
      let evt = &om.arguments[0];
      match evt {
        &osc::Argument::s("b_pressed") => {
          // blah
          Ok(controls::UpdateMsg::Button
            { controlId: cid.clone(), updateType: controls::ButtonUpType::Pressed })
        },
        &osc::Argument::s("b_unpressed") => {
          Ok(controls::UpdateMsg::Button
            { controlId: cid.clone(), updateType: controls::ButtonUpType::Unpressed })
        },
        _ => Err(Error::new(ErrorKind::Other, "invalid button event")),
      }
    },
    2 => {
      match (&om.arguments[0], &om.arguments[1]) {
        (&osc::Argument::s("s_pressed"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Pressed,
              location: loc as f64 })
        },
        (&osc::Argument::s("s_moved"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Moved,
              location: loc as f64 })
        },
        (&osc::Argument::s("s_unpressed"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Unpressed,
              location: loc as f64 })
        },
        _ => Err(Error::new(ErrorKind::Other, "invalid slider event")),
      }
    },
    _ => Err(Error::new(ErrorKind::Other, "invalid slider event")),
  }
}

fn oscmain( socket: UdpSocket,
            oscsendip: String,
            mut bc: broadcaster::Broadcaster,
            cm: Arc<Mutex<controls::controlMap>>,
            cnm: controls::controlNameMap)
              -> Result<String, Error>
{
  let mut buf = [0; 1000];

  loop {
    let (amt, src) = try!(socket.recv_from(&mut buf));

    println!("length: {}", amt);
    let inmsg = match osc::Message::deserialize(&buf[.. amt]) {
      Ok(m) => m,
      Err(e) => {
          return Err(Error::new(ErrorKind::Other, "invalid osc message!"));
        },
      };

    match oscToCtrlUpdate(&inmsg, &cnm) {
      Ok(updmsg) => {
        let mut cmunlock = cm.lock().unwrap();
        match cmunlock.get_mut(controls::getUmId(&updmsg)) {
          Some(ctl) => {
            (*ctl).update(&updmsg);

            let val = controls::encodeUpdateMessage(&updmsg);
            println!("sending control update {:?}", val);
            match serde_json::ser::to_string(&val) {
              Ok(s) => bc.broadcast(Message::Text(s)),
              Err(_) => ()
            }
            ()
           },
          None => (),
        }
      },
      Err(e) => println!("osc decode error: {:?}", e),
    };

    println!("osc message received {} {:?}", inmsg.path, inmsg.arguments );
  }
}

<commit_msg>expunge some of the unwrap() calls<commit_after>#![feature(custom_derive)]

extern crate websocket;

use std::thread;
use std::sync::{Arc, Mutex};
use std::fmt::format;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::os;
use std::env;
use std::convert;

use std::io::Read;
use std::io::{Error,ErrorKind};
use std::error;
use std::string::*;
use std::collections::BTreeMap;

use std::net::UdpSocket;
use std::net::SocketAddr;

use websocket::{Server, Message, Sender, Receiver};
use websocket::header::WebSocketProtocol;
use websocket::stream::WebSocketStream;
use websocket::server::sender;

extern crate iron;

use iron::prelude::*;
use iron::status;
use iron::mime::Mime;

mod controls;
mod broadcaster;

extern crate tinyosc;
use tinyosc as osc;

extern crate serde_json;
use serde_json::Value;
use serde_json::ser;

macro_rules! try_opt {
  ($e: expr) => {
    match $e {
      Some(x) => x,
      None => return None
      }
  }
}

macro_rules! try_opt_resbox {

  ($e: expr, $s: expr) => {
    match $e {
      Some(x) => x,
      None => return Err(Box::new(Error::new(ErrorKind::Other, $s))),
      }
  }
}

macro_rules! try_opt_res {
  ($e: expr, $s: expr) =>
    (match $e {
      Some(val) => val,
      None => {
          let err = Error::new(ErrorKind::Other, $s) ;
          return Err(std::convert::From::from(err))
      },
    })
}

/*

hmmm not getting why this doesn't work... want it to be like the try! macro.

macro_rules! try_opt_res {
  ($e: expr, $s: expr) =>
    (match $e {
      Some(val) => val,
      None => {
          let err = Err(Error::new(ErrorKind::Other, $s)) ;
          return $crate::result::Result::Err($crate::convert::From::from(err))
      },
    })
}
*/

fn loadString(file_name: &str) -> Option<String>
{
  let path = &Path::new(&file_name);
  let f = File::open(path);
  let mut result = String::new();
  match f {
    Ok(mut of) => {
      match of.read_to_string(&mut result) {
        Err(e) => {
          println!("err: {:?}", e);
          None
        },
        Ok(len) => {
          println!("read {} bytes", len);
          Some(result)
        },
      }
    },
    Err(e) => {
      println!("err: {:?}", e);
      None
    },
  }
}

fn main() {
  // read in the settings json.
  let args = env::args();
  let mut iter = args.skip(1); // skip the program name
  match iter.next() {
    Some(file_name) => {

      match startserver(&file_name) {
        Err(e) => println!("error starting server: {:?}", e),
        _ => (),
      }

    }
    None => {
      println!("oscpad syntax: ");
      println!("oscpad <json config file>");
    }
  }
}

fn startserver(file_name: &String) -> Result<(), Box<std::error::Error> >
{
    println!("loading config file: {}", file_name);
    let configstring = try_opt_resbox!(loadString(&file_name),
                                       "error reading config file");

    // read config file as json
    let configval: Value = try!(serde_json::from_str(&configstring[..]));

    let obj = configval.as_object().unwrap();

    let htmlfilename =
      try_opt_resbox!(
        try_opt_resbox!(obj.get("htmlfile"),
                        "'htmlfile' not found in config file").as_string(),
        "failed to convert to string");
    let htmlstring =
        try_opt_resbox!(loadString(&htmlfilename[..]),
                       "error loading html file!");

    let guifilename =
      try_opt_resbox!(
        try_opt_resbox!(obj.get("guifile"),
                        "'guifile' not found in config file").as_string(),
        "failed to convert to string");
    let guistring = loadString(&guifilename[..]).unwrap();
        try_opt_resbox!(loadString(&guifilename[..]),
                       "error loading gui file!");

    let ip = String::new() +
      try_opt_resbox!(
        try_opt_resbox!(obj.get("ip"),
                       "'ip' not found!").as_string(),
        "'ip' not a string!");

    let wip = String::new() +
      try_opt_resbox!(
        try_opt_resbox!(obj.get("wip"),
                       "'wip' not found!").as_string(),
        "'wip' not a string!");

    let oscrecvip = String::new() +
      try_opt_resbox!(
        try_opt_resbox!(obj.get("oscrecvip"),
                       "'oscrecvip' not found!").as_string(),
        "'oscrecvip' not a string!");

    let oscsendip = String::new() +
      try_opt_resbox!(
        try_opt_resbox!(obj.get("oscsendip"),
                       "'oscsendip' not found!").as_string(),
        "'oscsendip' not a string!");

    // deserialize the gui string into json.
    let guival: Value = try!(serde_json::from_str(&guistring[..]));

    let blah = try_opt_resbox!(
      controls::deserializeRoot(&guival),
      "gui file is valid json, but failed to read controls.");

    println!("title: {} count: {} ",
      blah.title, blah.rootControl.controlType());
    println!("controls: {:?}", blah.rootControl);

    // from control tree, make a map of ids->controls.
    let mapp = controls::makeControlMap(&*blah.rootControl);
    let cnm = controls::controlMapToNameMap(&mapp);

    let cm = Arc::new(Mutex::new(mapp));

    let guijson = String::new() + &guistring[..];

    let oscsocket = try!(UdpSocket::bind(&oscrecvip[..]));
    let mut bc = broadcaster::Broadcaster::new();
    let wsos = try!(oscsocket.try_clone());
    let wscm = cm.clone();
    let wsbc = bc.clone();
    let wsoscsendip = oscsendip.clone();

    thread::spawn(move || {
      oscmain(oscsocket, oscsendip, bc, cm, cnm)
      });

    thread::spawn(move || {
      websockets_main(wip, guijson, wscm, wsbc, wsoscsendip, wsos);
      });

    try!(Iron::new(move |req: &mut Request| {
        let content_type = "text/html".parse::<Mime>().unwrap();
        Ok(Response::with((content_type, status::Ok, &*htmlstring)))
    }).http(&ip[..]));

    Ok(())
}

fn websockets_main( ipaddr: String,
                    aSConfig: String,
                    cm: Arc<Mutex<controls::controlMap>>,
                    broadcaster: broadcaster::Broadcaster,
                    oscsendip: String,
                    oscsocket: UdpSocket )
{
	let server = Server::bind(&ipaddr[..]).unwrap();

	for connection in server {

    println!("new websockets connection!");
		// Spawn a new thread for each connection.
    let blah = String::new() + &aSConfig[..];

    let scm = cm.clone();

    let osock = oscsocket.try_clone().unwrap();
    let osend = oscsendip.clone();

    let mut broadcaster = broadcaster.clone();

    thread::spawn(move || {
      // Get the request
			let request = connection.unwrap().read_request().unwrap();
      // Keep the headers so we can check them
			let headers = request.headers.clone();

			request.validate().unwrap(); // Validate the request

			let mut response = request.accept(); // Form a response

			if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
				if protocols.contains(&("rust-websocket".to_string())) {
					// We have a protocol we want to use
					response.headers.set(WebSocketProtocol(vec!["rust-websocket".to_string()]));
				}
			}

			let mut client = response.send().unwrap(); // Send the response

			let ip = client.get_mut_sender()
				.get_mut()
				.peer_addr()
				.unwrap();

			println!("Connection from {}", ip);

      let message = Message::Text(blah);
			client.send_message(message.clone()).unwrap();

			let (sender, mut receiver) = client.split();

      let sendmeh = Arc::new(Mutex::new(sender));

      broadcaster.register(sendmeh.clone());

			for message in receiver.incoming_messages() {
				let message = message.unwrap();
        println!("message: {:?}", message);

        let replyy = Message::Text("replyyyblah".to_string());

				match message {
					Message::Close(_) => {
						let message = Message::Close(None);
            let mut sender = sendmeh.lock().unwrap();
						sender.send_message(message).unwrap();
						println!("Client {} disconnected", ip);
						return;
					}
					Message::Ping(data) => {
            println!("Message::Ping(data)");
						let message = Message::Pong(data);
            let mut sender = sendmeh.lock().unwrap();
						sender.send_message(message).unwrap();
					}
          Message::Text(texxt) => {
            let jsonval: Value = serde_json::from_str(&texxt[..]).unwrap();
            let s_um = controls::decodeUpdateMessage(&jsonval);
            match s_um {
              Some(updmsg) => {
                let mut scmun = scm.lock().unwrap();
                let cntrl = scmun.get_mut(controls::getUmId(&updmsg));
                match cntrl {
                  Some(x) => {
                    (*x).update(&updmsg);
                    println!("some x: {:?}", *x);
                    broadcaster.broadcast_others(&ip, Message::Text(texxt));
                    match ctrlUpdateToOsc(&updmsg, &**x) {
                      Ok(v) => osock.send_to(&v, &osend[..]),
                      _ => Err(Error::new(ErrorKind::Other, "meh"))
                    };
                    ()
                  },
                  None => println!("none"),
                }
              },
              _ => println!("uknown msg"),
            }
          },
					_ => {
            println!("sending replyy");
            let mut sender = sendmeh.lock().unwrap();
            sender.send_message(replyy).unwrap()
          }
				}
			}
		});
	}
}

fn ctrlUpdateToOsc(um: &controls::UpdateMsg, ctrl: &controls::Control) -> Result<Vec<u8>, Error>
{
  match um {
    &controls::UpdateMsg::Button { controlId: ref id
             , updateType: ref ut
             } => {
      // find the control in the map.
      let mut arghs = Vec::new();
      arghs.push (
        match ut {
          &controls::ButtonUpType::Pressed => osc::Argument::s("b_pressed"),
          &controls::ButtonUpType::Unpressed => osc::Argument::s("b_unpressed"),
        });
      let msg = osc::Message { path: ctrl.oscname(), arguments: arghs };
      msg.serialize()
    },
    &controls::UpdateMsg::Slider  { controlId: ref id
            , updateType: ref ut
            , location: ref loc
            } => {
      let mut arghs = Vec::new();
      arghs.push (
        match ut {
          &controls::SliderUpType::Pressed => osc::Argument::s("s_pressed"),
          &controls::SliderUpType::Moved => osc::Argument::s("s_moved"),
          &controls::SliderUpType::Unpressed => osc::Argument::s("s_unpressed"),
        });
      let l = *loc as f32;
      arghs.push(osc::Argument::f(l));
      let msg = osc::Message { path: ctrl.oscname(), arguments: arghs };
      msg.serialize()
    },
  }
}

fn oscToCtrlUpdate(om: &osc::Message, cnm: &controls::controlNameMap) -> Result<controls::UpdateMsg, Box<std::error::Error> >
{
  // find the control by name.
  let cid = try_opt_res!(cnm.get(om.path), "control name not found!");

  match om.arguments.len() {
    1 => {
      let evt = &om.arguments[0];
      match evt {
        &osc::Argument::s("b_pressed") => {
          // blah
          Ok(controls::UpdateMsg::Button
            { controlId: cid.clone(), updateType: controls::ButtonUpType::Pressed })
        },
        &osc::Argument::s("b_unpressed") => {
          Ok(controls::UpdateMsg::Button
            { controlId: cid.clone(), updateType: controls::ButtonUpType::Unpressed })
        },
        _ => Err(Box::new(Error::new(ErrorKind::Other, "invalid button event"))),
      }
    },
    2 => {
      match (&om.arguments[0], &om.arguments[1]) {
        (&osc::Argument::s("s_pressed"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Pressed,
              location: loc as f64 })
        },
        (&osc::Argument::s("s_moved"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Moved,
              location: loc as f64 })
        },
        (&osc::Argument::s("s_unpressed"), &osc::Argument::f(loc))  => {
          Ok(controls::UpdateMsg::Slider
            { controlId: cid.clone(),
              updateType: controls::SliderUpType::Unpressed,
              location: loc as f64 })
        },
        _ => Err(Box::new(Error::new(ErrorKind::Other, "invalid slider event"))),
      }
    },
    _ => Err(Box::new(Error::new(ErrorKind::Other, "invalid osc message"))),
  }
}

fn oscmain( socket: UdpSocket,
            oscsendip: String,
            mut bc: broadcaster::Broadcaster,
            cm: Arc<Mutex<controls::controlMap>>,
            cnm: controls::controlNameMap)
              -> Result<String, Error>
{
  let mut buf = [0; 1000];

  loop {
    let (amt, src) = try!(socket.recv_from(&mut buf));

    println!("length: {}", amt);
    let inmsg = match osc::Message::deserialize(&buf[.. amt]) {
      Ok(m) => m,
      Err(e) => {
          return Err(Error::new(ErrorKind::Other, "invalid osc message!"));
        },
      };

    match oscToCtrlUpdate(&inmsg, &cnm) {
      Ok(updmsg) => {
        let mut cmunlock = cm.lock().unwrap();
        match cmunlock.get_mut(controls::getUmId(&updmsg)) {
          Some(ctl) => {
            (*ctl).update(&updmsg);

            let val = controls::encodeUpdateMessage(&updmsg);
            println!("sending control update {:?}", val);
            match serde_json::ser::to_string(&val) {
              Ok(s) => bc.broadcast(Message::Text(s)),
              Err(_) => ()
            }
            ()
           },
          None => (),
        }
      },
      Err(e) => println!("osc decode error: {:?}", e),
    };

    println!("osc message received {} {:?}", inmsg.path, inmsg.arguments );
  }
}

<|endoftext|>


<commit_before>use std::mem;
use std::collections::HashMap;
use std::mem::transmute;

struct Graph {
	vertices: HashMap<i64, Box<Vertex>>,
}

impl Graph {
	fn new() -> Box<Graph> {
		let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
		Box::new(Graph{vertices:vertices})
	}
	fn add_vertex(&mut self) -> VertexProxy {
		let new_id = 1;
		let vertex = Vertex{id:new_id};

		let mut v = Box::new(vertex);
		let ptr: *const Box<Vertex> = &v as *const Box<Vertex>;

		self.vertices.insert(new_id, v);

		// return the proxy which knows it's own id
		VertexProxy{id:new_id, v: ptr}
	}
}

struct Vertex {
	id: i64,
}

impl Vertex {
	fn query(self) {

	}
}

struct VertexProxy {
	id: i64,
	v: *const Box<Vertex>,
}

impl VertexProxy {
	fn add_edge() {

	}
}

struct Edge {
	id: i32,
	from_vertex: *const Vertex,
	to_vertex: *const Vertex
}

fn main() {
	let mut g = Graph::new();

    println!("Hello, world!");
}

#[test]
fn test_unsafe_vertex() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
	let mut v2 = g.add_vertex();

	v1.test()

}
<commit_msg>setting up add edge<commit_after>use std::mem;
use std::collections::HashMap;
use std::mem::transmute;

struct Graph {
	vertices: HashMap<i64, Box<Vertex>>,
}

impl Graph {
	fn new() -> Box<Graph> {
		let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
		Box::new(Graph{vertices:vertices})
	}
	fn add_vertex(&mut self) -> VertexProxy {
		let new_id = 1;
		let vertex = Vertex{id:new_id};

		let mut v = Box::new(vertex);
		let ptr: *const Box<Vertex> = &v as *const Box<Vertex>;

		self.vertices.insert(new_id, v);

		// return the proxy which knows it's own id
		VertexProxy{id:new_id, v: ptr}
	}
}

struct Vertex {
	id: i64,
}

impl Vertex {
	fn query(self) {

	}
}

struct VertexProxy {
	id: i64,
	v: *const Box<Vertex>,
}

impl VertexProxy {
	fn add_edge(&self, v2: &VertexProxy) {

	}
}

struct Edge {
	id: i32,
	from_vertex: *const Vertex,
	to_vertex: *const Vertex
}

fn main() {
	let mut g = Graph::new();

    println!("Hello, world!");
}

#[test]
fn test_unsafe_vertex() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
	let mut v2 = g.add_vertex();

	v1.test()

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate clap;
extern crate image;
extern crate cgmath;
extern crate time;

use glium::glutin::{WindowBuilder, VirtualKeyCode};
use glium::DisplayBuild;
use glium::backend::glutin_backend::GlutinFacade;

use std::path::Path;
use std::collections::HashSet;

use time::precise_time_ns;

use clap::{Arg, App, ArgMatches};

use cgmath::{Matrix3, Vector3, vec3};

use std::fmt;

mod render;
mod shaders;

#[allow(dead_code)]
mod settings {
    pub const NAME: &'static str = "gr-trace";
    pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
}

fn main() {
    let args = arg_handle();
    let display = build_display().build_glium().unwrap();

    let renderer = render::Renderer::new(&display, &args);

    let mut camera = Camera{
        pos: vec3(0.0, 0.0, -10.0f32),
        facing: Matrix3::look_at(vec3(0., 0., 1.), vec3(0., 1., 0.)),
    };

    let start = precise_time_ns();
    let mut prev = precise_time_ns();
    let mut keys = HashSet::new();
    loop {
        use time::precise_time_ns;

        let time = (precise_time_ns() - start) as f32 / 1000000000.0f32;
        renderer.render(display.draw(), &camera, time);
        display.finish();

        let time = precise_time_ns();
        let dt = (time - prev) as f32 / 1000000000.0f32;
        prev = time;

        for ev in display.poll_events() {
            use glium::glutin::Event::*;
            match ev {
                Closed => return,
                KeyboardInput(s, _, o) => {
                    if let Some(k) = o {
                        use glium::glutin::ElementState;
                        match s {
                            ElementState::Pressed => keys.insert(k),
                            ElementState::Released => keys.remove(&k),
                        };
                    }
                },
				_ => ()
			}
		}

        camera.update(&keys, dt);
        println!("dt: {}ms cam: {}", dt * 1000.0f32, camera);

        if keys.contains(&VirtualKeyCode::Q) &&
            keys.contains(&VirtualKeyCode::LWin) {

            break
        }
	}
}

pub struct Camera {
    pos: Vector3<f32>,
    facing: Matrix3<f32>,
}

impl Camera {
    fn update(&mut self, keys: &HashSet<VirtualKeyCode>, dt: f32) {
        use cgmath::Rad;
        use cgmath::Angle;
        use cgmath::SquareMatrix;

        let ang = Rad::new(1f32 * dt);
        let mut dist = 0.2f32;

        let mut vert = 0.0;
        let mut hori = 0.0;
        let mut depth = 0.0;
        let mut yaw = Rad::zero();
        let mut pitch = Rad::zero();
        let mut roll = Rad::zero();
        for &k in keys {
            match k {
                VirtualKeyCode::W => vert += 1.0,
                VirtualKeyCode::S => vert -= 1.0,
                VirtualKeyCode::A => hori -= 1.0,
                VirtualKeyCode::D => hori += 1.0,
                VirtualKeyCode::Q => depth -= 1.0,
                VirtualKeyCode::E => depth += 1.0,
                VirtualKeyCode::LShift => dist = 2f32,
                VirtualKeyCode::I => pitch = pitch + ang,
                VirtualKeyCode::K => pitch = pitch - ang,
                VirtualKeyCode::J => yaw = yaw - ang,
                VirtualKeyCode::L => yaw = yaw + ang,
                VirtualKeyCode::U => roll = roll + ang,
                VirtualKeyCode::O => roll = roll - ang,
                _ => (),
            }
        }

        let mov = self.facing.invert().unwrap() * vec3(hori, vert, depth);
        let rot = Matrix3::from_euler(pitch, yaw, roll);

        self.pos = self.pos + mov * dist * dt;
        self.facing = (self.facing.invert().unwrap() * rot).invert().unwrap();
    }
}

impl fmt::Display for Camera {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let pos = self.pos;
        let fw = self.facing.z;
        let up = self.facing.y;
        write!(f, "pos: {:?} dir: {:?} up: {:?}", pos, fw, up)
    }
}

fn build_display<'a>() -> WindowBuilder<'a> {
    WindowBuilder::new()
		.with_dimensions(1024, 768)
        //.with_visibility(false)
		.with_title(format!("gr-trace"))
}

fn arg_handle<'a>() -> ArgMatches<'a> {
    App::new(settings::NAME)
        .version(settings::VERSION)
        .author("Sean Purcell <iburinoc@gmail.com>")
        .about("GPU General Relativity Ray Tracer")
        .arg(Arg::with_name("flat")
            .short("f")
            .long("flat")
            .help("Turns off relativistic distortion"))
        .arg(Arg::with_name("iter")
            .short("i")
            .long("iter")
            .help("Sets the number of iterations to raytrace")
            .takes_value(true)
            .value_name("ITER_NUM")
            .default_value("1000"))
        .arg(Arg::with_name("timestep")
            .short("t")
            .long("timestep")
            .help("Sets the length of each time step (where c = 1)")
            .takes_value(true)
            .value_name("TIME_STEP")
            .default_value("0.64"))
        .arg(Arg::with_name("method")
            .short("m")
            .long("method")
            .help("Sets the integration method to use")
            .takes_value(true)
            .value_name("METHOD")
            .default_value("rk4")
                .possible_value("rk4")
                .possible_value("verlet")
                .possible_value("flat"))
        .arg(Arg::with_name("bg")
            .short("b")
            .long("bg")
            .help("Sets the type of background used")
            .takes_value(true)
            .value_name("TYPE")
            .default_value("img")
                .possible_value("black")
                .possible_value("img"))
        .arg(Arg::with_name("accdisk")
            .short("d")
            .long("disk")
            .help("Sets the type of accretion disk used")
            .takes_value(true)
            .value_name("TYPE")
            .default_value("dyno")
                .possible_value("none")
                .possible_value("white")
                .possible_value("img")
                .possible_value("dyno"))
        .arg(Arg::with_name("iradius")
            .long("ir")
            .help("Sets the inner radius of the accretion disk")
            .takes_value(true)
            .value_name("RADIUS")
            .default_value("3"))
        .arg(Arg::with_name("oradius")
            .long("or")
            .help("Sets the outer radius of the accretion disk")
            .takes_value(true)
            .value_name("RADIUS")
            .default_value("15"))
        .arg(Arg::with_name("fov")
            .long("fov")
            .help("Sets the horizontal field of view (in degrees)")
            .takes_value(true)
            .value_name("FOV")
            .default_value("90"))
        .arg(Arg::with_name("bgrat")
            .long("bgratio")
            .help("Sets the factor by which the background is dimmed")
            .takes_value(true)
            .value_name("FACTOR")
            .default_value("0.5"))
        .arg(Arg::with_name("out")
            .short("O")
            .long("out")
            .help("Sets the output file")
            .value_name("FILE")
            .takes_value(true)
            .default_value("out.png"))
        .get_matches()
}

#[allow(dead_code)]
fn write_img(display: &GlutinFacade, path: &str) {
    let image: glium::texture::RawImage2d<u8> = display.read_front_buffer();
    let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
    let image = image::DynamicImage::ImageRgba8(image);
    let mut output = std::fs::File::create(&Path::new(path)).unwrap();
    image.save(&mut output, image::ImageFormat::PNG).unwrap();
}

<commit_msg>fixed name string<commit_after>#[macro_use]
extern crate glium;
extern crate clap;
extern crate image;
extern crate cgmath;
extern crate time;

use glium::glutin::{WindowBuilder, VirtualKeyCode};
use glium::DisplayBuild;
use glium::backend::glutin_backend::GlutinFacade;

use std::path::Path;
use std::collections::HashSet;

use time::precise_time_ns;

use clap::{Arg, App, ArgMatches};

use cgmath::{Matrix3, Vector3, vec3};

use std::fmt;

mod render;
mod shaders;

#[allow(dead_code)]
mod settings {
    pub const NAME: &'static str = "gr_trace";
    pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
}

fn main() {
    let args = arg_handle();
    let display = build_display().build_glium().unwrap();

    let renderer = render::Renderer::new(&display, &args);

    let mut camera = Camera{
        pos: vec3(0.0, 0.0, -10.0f32),
        facing: Matrix3::look_at(vec3(0., 0., 1.), vec3(0., 1., 0.)),
    };

    let start = precise_time_ns();
    let mut prev = precise_time_ns();
    let mut keys = HashSet::new();
    loop {
        use time::precise_time_ns;

        let time = (precise_time_ns() - start) as f32 / 1000000000.0f32;
        renderer.render(display.draw(), &camera, time);
        display.finish();

        let time = precise_time_ns();
        let dt = (time - prev) as f32 / 1000000000.0f32;
        prev = time;

        for ev in display.poll_events() {
            use glium::glutin::Event::*;
            match ev {
                Closed => return,
                KeyboardInput(s, _, o) => {
                    if let Some(k) = o {
                        use glium::glutin::ElementState;
                        match s {
                            ElementState::Pressed => keys.insert(k),
                            ElementState::Released => keys.remove(&k),
                        };
                    }
                },
				_ => ()
			}
		}

        camera.update(&keys, dt);
        println!("dt: {}ms cam: {}", dt * 1000.0f32, camera);

        if keys.contains(&VirtualKeyCode::Q) &&
            keys.contains(&VirtualKeyCode::LWin) {

            break
        }
	}
}

pub struct Camera {
    pos: Vector3<f32>,
    facing: Matrix3<f32>,
}

impl Camera {
    fn update(&mut self, keys: &HashSet<VirtualKeyCode>, dt: f32) {
        use cgmath::Rad;
        use cgmath::Angle;
        use cgmath::SquareMatrix;

        let ang = Rad::new(1f32 * dt);
        let mut dist = 0.2f32;

        let mut vert = 0.0;
        let mut hori = 0.0;
        let mut depth = 0.0;
        let mut yaw = Rad::zero();
        let mut pitch = Rad::zero();
        let mut roll = Rad::zero();
        for &k in keys {
            match k {
                VirtualKeyCode::W => vert += 1.0,
                VirtualKeyCode::S => vert -= 1.0,
                VirtualKeyCode::A => hori -= 1.0,
                VirtualKeyCode::D => hori += 1.0,
                VirtualKeyCode::Q => depth -= 1.0,
                VirtualKeyCode::E => depth += 1.0,
                VirtualKeyCode::LShift => dist = 2f32,
                VirtualKeyCode::I => pitch = pitch + ang,
                VirtualKeyCode::K => pitch = pitch - ang,
                VirtualKeyCode::J => yaw = yaw - ang,
                VirtualKeyCode::L => yaw = yaw + ang,
                VirtualKeyCode::U => roll = roll + ang,
                VirtualKeyCode::O => roll = roll - ang,
                _ => (),
            }
        }

        let mov = self.facing.invert().unwrap() * vec3(hori, vert, depth);
        let rot = Matrix3::from_euler(pitch, yaw, roll);

        self.pos = self.pos + mov * dist * dt;
        self.facing = (self.facing.invert().unwrap() * rot).invert().unwrap();
    }
}

impl fmt::Display for Camera {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let pos = self.pos;
        let fw = self.facing.z;
        let up = self.facing.y;
        write!(f, "pos: {:?} dir: {:?} up: {:?}", pos, fw, up)
    }
}

fn build_display<'a>() -> WindowBuilder<'a> {
    WindowBuilder::new()
		.with_dimensions(1024, 768)
        //.with_visibility(false)
		.with_title(format!("gr-trace"))
}

fn arg_handle<'a>() -> ArgMatches<'a> {
    App::new(settings::NAME)
        .version(settings::VERSION)
        .author("Sean Purcell <iburinoc@gmail.com>")
        .about("GPU General Relativity Ray Tracer")
        .arg(Arg::with_name("flat")
            .short("f")
            .long("flat")
            .help("Turns off relativistic distortion"))
        .arg(Arg::with_name("iter")
            .short("i")
            .long("iter")
            .help("Sets the number of iterations to raytrace")
            .takes_value(true)
            .value_name("ITER_NUM")
            .default_value("1000"))
        .arg(Arg::with_name("timestep")
            .short("t")
            .long("timestep")
            .help("Sets the length of each time step (where c = 1)")
            .takes_value(true)
            .value_name("TIME_STEP")
            .default_value("0.64"))
        .arg(Arg::with_name("method")
            .short("m")
            .long("method")
            .help("Sets the integration method to use")
            .takes_value(true)
            .value_name("METHOD")
            .default_value("rk4")
                .possible_value("rk4")
                .possible_value("verlet")
                .possible_value("flat"))
        .arg(Arg::with_name("bg")
            .short("b")
            .long("bg")
            .help("Sets the type of background used")
            .takes_value(true)
            .value_name("TYPE")
            .default_value("img")
                .possible_value("black")
                .possible_value("img"))
        .arg(Arg::with_name("accdisk")
            .short("d")
            .long("disk")
            .help("Sets the type of accretion disk used")
            .takes_value(true)
            .value_name("TYPE")
            .default_value("dyno")
                .possible_value("none")
                .possible_value("white")
                .possible_value("img")
                .possible_value("dyno"))
        .arg(Arg::with_name("iradius")
            .long("ir")
            .help("Sets the inner radius of the accretion disk")
            .takes_value(true)
            .value_name("RADIUS")
            .default_value("3"))
        .arg(Arg::with_name("oradius")
            .long("or")
            .help("Sets the outer radius of the accretion disk")
            .takes_value(true)
            .value_name("RADIUS")
            .default_value("15"))
        .arg(Arg::with_name("fov")
            .long("fov")
            .help("Sets the horizontal field of view (in degrees)")
            .takes_value(true)
            .value_name("FOV")
            .default_value("90"))
        .arg(Arg::with_name("bgrat")
            .long("bgratio")
            .help("Sets the factor by which the background is dimmed")
            .takes_value(true)
            .value_name("FACTOR")
            .default_value("0.5"))
        .arg(Arg::with_name("out")
            .short("O")
            .long("out")
            .help("Sets the output file")
            .value_name("FILE")
            .takes_value(true)
            .default_value("out.png"))
        .get_matches()
}

#[allow(dead_code)]
fn write_img(display: &GlutinFacade, path: &str) {
    let image: glium::texture::RawImage2d<u8> = display.read_front_buffer();
    let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
    let image = image::DynamicImage::ImageRgba8(image);
    let mut output = std::fs::File::create(&Path::new(path)).unwrap();
    image.save(&mut output, image::ImageFormat::PNG).unwrap();
}

<|endoftext|>


<commit_before>extern crate hyper;
extern crate chrono;

use std::env;
use std::io::Read;
use chrono::*;
use hyper::Client;
use hyper::header::Connection;

static WEEKDAY_WEBSITE: &'static str = "http://www.hvilkenukeerdet.no";

fn print_help() {
    println!("`uke` gives the current week number.
              `uke <number>` gives you the range for that week number");
}

fn is_leap_year(year: i32) -> bool {
    return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)
}

fn find_num_of_weeks_this_year(year: i32) -> usize {
    let last_day_of_year = UTC.ymd(year, 12, 31);
    return match last_day_of_year.weekday() {
        Weekday::Thu | Weekday::Fri if is_leap_year(year) => 53,
        _ => 52,
    };
}

fn show_week_period_for_week_number(w: usize, year: i32) {
    let mut start_date = UTC.ymd(year, 1, 1);

    /* week 1 is defined by the first week with a thursday in a year */

    let jan_1_week_day = start_date.weekday().number_from_monday();
    if jan_1_week_day > 4 {
        /* this week has no thursday */
        /* the calculation will give the date of monday in the first week */
        start_date = UTC.ymd(year, 1, (1 + 8-jan_1_week_day));
    } else {
        /* start at this week's first day */
        start_date = UTC.ymd(year-1, 12, (31 - (jan_1_week_day - 2)));
    }

    start_date = start_date + Duration::weeks((w as i64) - 1);

    let end_date = start_date + Duration::days(6);

    println!("Week {}, {} is from \"{}\" to \"{}\"",
             w,
             year,
             start_date.format("%d %b"),
             end_date.format("%d %b")
            );
}

fn main() {
    let year = Local::now().year();

    if let Some(arg1) = env::args().nth(1) {
        let num_of_weeks_this_year = find_num_of_weeks_this_year(year);
        match arg1.parse::<usize>() {
            Ok(week_number) =>
                if week_number >= 1 && week_number <= num_of_weeks_this_year {
                    show_week_period_for_week_number(week_number, year);
                    return;
                },
            _ => {} ,
        }

        print_help();
    } else {
        let client = Client::new();

        let mut res = client
                        .get(WEEKDAY_WEBSITE)
                        .header(Connection::close())
                        .send()
                        .unwrap_or_else(|why| {
                            panic!("Error fetching week number, make sure you have an internet connection");
                        });

        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        let body_index = body.find("\n").unwrap() + "\n".len();
        let break_index = body.find("
").unwrap();

        let week_number = &body[body_index..break_index];
        println!("{}", week_number);
    }
}
<commit_msg>Move week number parsing to separate function<commit_after>extern crate hyper;
extern crate chrono;

use std::env;
use std::io::Read;
use chrono::*;
use hyper::Client;
use hyper::header::Connection;

static WEEKDAY_WEBSITE: &'static str = "http://www.hvilkenukeerdet.no";

fn print_help() {
    println!("`uke` gives the current week number.
              `uke <number>` gives you the range for that week number");
}

fn is_leap_year(year: i32) -> bool {
    return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)
}

fn find_num_of_weeks_this_year(year: i32) -> usize {
    let last_day_of_year = UTC.ymd(year, 12, 31);
    return match last_day_of_year.weekday() {
        Weekday::Thu | Weekday::Fri if is_leap_year(year) => 53,
        _ => 52,
    };
}

fn show_week_period_for_week_number(w: usize, year: i32) {
    let mut start_date = UTC.ymd(year, 1, 1);

    /* week 1 is defined by the first week with a thursday in a year */

    let jan_1_week_day = start_date.weekday().number_from_monday();
    if jan_1_week_day > 4 {
        /* this week has no thursday */
        /* the calculation will give the date of monday in the first week */
        start_date = UTC.ymd(year, 1, (1 + 8-jan_1_week_day));
    } else {
        /* start at this week's first day */
        start_date = UTC.ymd(year-1, 12, (31 - (jan_1_week_day - 2)));
    }

    start_date = start_date + Duration::weeks((w as i64) - 1);

    let end_date = start_date + Duration::days(6);

    println!("Week {}, {} is from \"{}\" to \"{}\"",
             w,
             year,
             start_date.format("%d %b"),
             end_date.format("%d %b")
            );
}

fn get_week_number() -> isize {
    let client = Client::new();

    let mut res = client
                    .get(WEEKDAY_WEBSITE)
                    .header(Connection::close())
                    .send()
                    .unwrap_or_else(|why| {
                        panic!("Error fetching week number, make sure you have an internet connection");
                    });

    let mut body = String::new();
    res.read_to_string(&mut body).unwrap();

    let body_index = body.find("\n").unwrap() + "\n".len();
    let break_index = body.find("
").unwrap();
    let week_number = &body[body_index..break_index];

    return match week_number.parse::<isize>() {
        Ok(num) => num,
        _ => -1,
    };
}

fn main() {
    let year = Local::now().year();

    if let Some(arg1) = env::args().nth(1) {
        let num_of_weeks_this_year = find_num_of_weeks_this_year(year);
        match arg1.parse::<usize>() {
            Ok(week_number) =>
                if week_number >= 1 && week_number <= num_of_weeks_this_year {
                    show_week_period_for_week_number(week_number, year);
                    return;
                },
            _ => {} ,
        }

        print_help();
    } else {
        println!("{}", get_week_number());
    }
}
<|endoftext|>