<commit_before>#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))]
#![cfg_attr(feature = "serde_macros", plugin(serde_macros))]
#![cfg_attr(feature = "benches", feature(test))]

extern crate mio;
extern crate bytes;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
extern crate spki_sexp;
extern crate time;

extern crate etcd;
extern crate tempdir;
extern crate rocksdb;
extern crate byteorder;

#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
extern crate env_logger;

#[cfg(feature = "benches")]
extern crate test;

use mio::tcp::*;
use mio::EventLoop;
use mio::util::Slab;
use std::collections::VecDeque;
use std::net::SocketAddr;

mod line_conn;
mod downstream_conn;
mod listener;
mod config;
mod event_handler;
mod data;
mod replication_log;
mod replica;

use line_conn::{SexpPeer, LineConn};
use downstream_conn::Downstream;
use listener::Listener;
use event_handler::EventHandler;

use data::{Seqno,Operation,OpResp, PeerMsg, NodeViewConfig};
use config::{ConfigurationView, Epoch};

pub use config::ConfigClient;
pub use replica::ReplModel;
pub use replication_log::RocksdbLog;
pub use data::Role;

#[derive(Debug)]
pub enum ChainReplMsg {
    Operation {
        source: mio::Token,
        epoch: Epoch,
        seqno: Seqno,
        op: Vec<u8>,
    },
    ClientOperation {
        source: mio::Token,
        op: Vec<u8>,
    },
    Commit {
        source: mio::Token,
        epoch: Epoch,
        seqno: Seqno,
    },
    DownstreamResponse(OpResp),
    NewClientConn(Role, TcpStream),
    ForwardDownstream(Epoch, PeerMsg),
}

#[derive(Debug)]
pub struct ChainRepl {
    connections: Slab<EventHandler>,
    downstream_slot: Option<mio::Token>,
    node_config: NodeViewConfig,
    new_view: Option<ConfigurationView<NodeViewConfig>>,
    model: ReplModel<RocksdbLog>,
}

impl ChainRepl {
    pub fn new(model: ReplModel<RocksdbLog>) -> ChainRepl {
        ChainRepl {
            connections: Slab::new(1024),
            downstream_slot: None,
            node_config: Default::default(),
            new_view: None,
            model: model,
        }
    }

    pub fn listen(&mut self,
                  event_loop: &mut mio::EventLoop<ChainRepl>,
                  addr: SocketAddr,
                  role: Role) {
        info!("Listen on {:?} for {:?}", addr, role);
        let &mut ChainRepl { ref mut connections, ref mut node_config, .. } = self;
        let token = connections.insert_with(|token| {
                                   let l = Listener::new(addr, token, role.clone());
                                   match role {
                                       Role::Upstream => {
                                           node_config.peer_addr = Some(format!("{}",
                                                                                l.listen_addr()))
                                       }
                                       Role::Client => {
                                           node_config.client_addr = Some(format!("{}",
                                                                                l.listen_addr()))
                                       }
                                   }

                                   EventHandler::Listener(l)
                               })
                               .expect("insert listener");
        connections[token].initialize(event_loop, token);
    }

    pub fn set_downstream(&mut self,
                          event_loop: &mut mio::EventLoop<ChainRepl>,
                          target: Option<SocketAddr>) {
        match (self.downstream_slot, target) {
            (Some(_), Some(target)) => self.downstream().expect("downstream").reconnect_to(target),
            (None, Some(target)) => {
                let token = self.connections
                                .insert_with(|token| {
                                    EventHandler::Downstream(Downstream::new(Some(target), token))
                                })
                                .expect("insert downstream");
                &self.connections[token].initialize(event_loop, token);
                self.downstream_slot = Some(token)
            }
            (Some(_), None) => self.downstream().expect("downstream").disconnect(),
            (None, None) => (),
        }
    }

    fn process_action(&mut self, msg: ChainReplMsg, event_loop: &mut mio::EventLoop<ChainRepl>) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            ChainReplMsg::Operation { source, seqno, epoch, op } => {
                if let Some(resp) = self.model.process_operation(source, seqno, epoch, &op) {
                    self.connections[source].response(resp);
                }
            }
            ChainReplMsg::ClientOperation { source, op } => {
                if let Some(resp) = self.model.process_client(source, &op) {
                    self.connections[source].response(resp);
                }
            }

            ChainReplMsg::Commit { seqno, .. } => {
                self.model.commit_observed(seqno);
            }

            ChainReplMsg::DownstreamResponse(reply) => self.process_downstream_response(reply),

            ChainReplMsg::NewClientConn(role, socket) => {
                self.process_new_client_conn(event_loop, role, socket)
            }
            ChainReplMsg::ForwardDownstream(epoch, msg) => {
                self.downstream().expect("Downstream").send_to_downstream(epoch, msg)
            }
        }
    }

    fn process_downstream_response(&mut self, reply: OpResp) {
        debug!("Downstream response: {:?}", reply);
        if let Some(waiter) = self.model.process_downstream_response(&reply) {
            if let Some(ref mut c) = self.connections.get_mut(waiter) {
                c.response(reply)
            }
        }
    }

    fn process_new_client_conn(&mut self,
                               event_loop: &mut mio::EventLoop<ChainRepl>,
                               role: Role,
                               socket: TcpStream) {
        let peer = socket.peer_addr().expect("peer address");
        let seqno = self.model.seqno();
        debug!("process_new_client_conn: {:?}@{:?}", role, peer);

        let token = self.connections
                        .insert_with(|token| {
                            match role {
                                Role::Client => EventHandler::Conn(LineConn::client(socket, token)),
                                Role::Upstream => {
                                    let mut conn = LineConn::upstream(socket, token);
                                    let msg = OpResp::HelloIWant(seqno);
                                    info!("Inform upstream about our current version, {:?}!", msg);
                                    conn.response(msg);
                                    EventHandler::Upstream(conn)
                                }
                            }
                        })
                        .expect("token insert");
        debug!("Client connection of {:?}/{:?} from {:?}",
               role,
               token,
               peer);
        &self.connections[token].initialize(event_loop, token);
    }

    fn process_rules<F: FnMut(ChainReplMsg)>(&mut self,
                                             event_loop: &mut mio::EventLoop<Self>,
                                             mut action: F)
                                             -> bool {
        let mut changed = false;

        if let Some(view) = self.new_view.take() {
            self.reconfigure(event_loop, view);
            changed |= true;
        }

        changed |= self.model.process_replication(|epoch, msg| {
            action(ChainReplMsg::ForwardDownstream(epoch, msg))
        });

        changed |= self.model.flush();

        changed
    }

    fn reconfigure(&mut self,
                   event_loop: &mut mio::EventLoop<Self>,
                   view: ConfigurationView<NodeViewConfig>) {
        info!("Reconfigure according to: {:?}", view);

        let listen_for_clients = view.should_listen_for_clients();
        info!("Listen for clients: {:?}", listen_for_clients);
        for p in self.listeners(Role::Client) {
            trace!("Active: {:?} -> {:?}", p, listen_for_clients);
            p.set_active(listen_for_clients);
        }

        let listen_for_upstreamp = view.should_listen_for_upstream();
        info!("Listen for upstreams: {:?}", listen_for_upstreamp);
        for p in self.listeners(Role::Upstream) {
            trace!("Active: {:?} -> {:?}", p, listen_for_clients);
            p.set_active(listen_for_upstreamp);
        }

        if let Some(ds) = view.should_connect_downstream() {
            info!("Push to downstream on {:?}", ds);
            let peer_addr = ds.peer_addr.as_ref().expect("Cannot reconnect to downstream with no peer listener");
            self.set_downstream(event_loop, Some(peer_addr.parse().expect("peer address")));
        } else {
            info!("Tail node!");
            self.set_downstream(event_loop, None);
        }

        info!("Reconfigure model: {:?}", view);
        self.model.reconfigure(&view)
    }

    fn downstream<'a>(&'a mut self) -> Option<&'a mut Downstream<SexpPeer>> {
        self.downstream_slot.map(move |slot| {
            match &mut self.connections[slot] {
                &mut EventHandler::Downstream(ref mut d) => d,
                other => {
                    panic!("Downstream slot not populated with a downstream instance: {:?}",
                           other)
                }
            }
        })
    }

    fn listeners<'a>(&'a mut self, role: Role) -> Vec<&'a mut Listener> {
        self.connections
            .iter_mut()
            .filter_map(|it| {
                match it {
                    &mut EventHandler::Listener(ref mut l) if l.role == role => Some(l),
                    _ => None,
                }
            })
            .collect()
    }

    fn converge_state(&mut self, event_loop: &mut mio::EventLoop<Self>) {
        let mut parent_actions = VecDeque::new();
        let mut changed = true;
        let mut iterations = 0;
        debug!("Converge begin");
        while changed {
            trace!("Iter: {:?}", iterations);
            changed = false;
            for conn in self.connections.iter_mut() {
                let changedp = conn.process_rules(event_loop,
                                                  &mut |item| parent_actions.push_back(item));
                if changedp {
                    trace!("Changed: {:?}", conn);
                };
                changed |= changedp;
            }

            let changedp = self.process_rules(event_loop,
                                              &mut |item| parent_actions.push_back(item));
            if changedp {
                trace!("Changed: {:?}", "Model");
            }
            changed |= changedp;

            debug!("Actions pending: {:?}", parent_actions.len());
            for action in parent_actions.drain(..) {
                debug!("Action: {:?}", action);
                self.process_action(action, event_loop);
            }
            iterations += 1;
        }
        debug!("Converged after {:?} iterations", iterations);
    }

    fn io_ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token) {
        self.converge_state(event_loop);
        if self.connections[token].should_close() && self.model.has_pending(token) {
            debug!("Close candidate: {:?}", token);
            let it = self.connections.remove(token);
            debug!("Removing; {:?}; {:?}", token, it);
            if Some(token) == self.downstream_slot {
                self.downstream_slot = None;
                self.model.reset();
            }
        }
    }

    fn handle_view_changed(&mut self, view: ConfigurationView<NodeViewConfig>) {
        self.new_view = Some(view)
    }

    fn committed_to(&mut self, seqno: Seqno) {
        info!("Committed upto: {:?}", seqno);
    }
    pub fn get_notifier(event_loop: &mut mio::EventLoop<Self>) -> Notifier {
        Notifier(event_loop.channel())
    }

    pub fn node_config(&self) -> NodeViewConfig {
        self.node_config.clone()
    }
}

#[derive(Debug)]
pub enum Notification {
    ViewChange(ConfigurationView<NodeViewConfig>),
    Shutdown,
    CommittedTo(Seqno),
}
pub struct Notifier(mio::Sender<Notification>);

impl Notifier {
    fn notify(&self, mut item: Notification) {
        use mio::NotifyError::*;
        use std::time::Duration;
        let mut backoff = Duration::from_millis(1);
        loop {
            item = match self.0.send(item) {
                Ok(_) => return,
                Err(Full(it)) => it,
                Err(e) => panic!("{:?}", e),
            };
            info!("Backoff: {:?}", backoff);
            std::thread::sleep(backoff);
            backoff = backoff * 2;
        }
    }

    pub fn view_changed(&self, view: ConfigurationView<NodeViewConfig>) {
        self.notify(Notification::ViewChange(view))
    }
    pub fn shutdown(&self) {
        self.notify(Notification::Shutdown)
    }
    pub fn committed_to(&self, seqno: Seqno) {
        self.notify(Notification::CommittedTo(seqno))
    }
}

impl mio::Handler for ChainRepl {
    // This is a bit wierd; we can pass a parent action back to enqueue some action.
    type Timeout = mio::Token;
    type Message = Notification;
    fn ready(&mut self,
             event_loop: &mut mio::EventLoop<Self>,
             token: mio::Token,
             events: mio::EventSet) {
        trace!("{:?}: {:?}", token, events);
        self.connections[token].handle_event(event_loop, events);
        self.io_ready(event_loop, token);
    }

    fn timeout(&mut self, event_loop: &mut EventLoop<Self>, token: mio::Token) {
        debug!("Timeout: {:?}", token);
        self.connections[token].handle_timeout();
        self.io_ready(event_loop, token);
    }

    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        debug!("Notified: {:?}", msg);
        match msg {
            Notification::ViewChange(view) => self.handle_view_changed(view),
            Notification::CommittedTo(seqno) => self.committed_to(seqno),
            Notification::Shutdown => {
                info!("Shutting down");
                event_loop.shutdown();
            }
        }
        self.converge_state(event_loop);
    }
}
<commit_msg>Tune down logging.<commit_after>#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))]
#![cfg_attr(feature = "serde_macros", plugin(serde_macros))]
#![cfg_attr(feature = "benches", feature(test))]

extern crate mio;
extern crate bytes;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
extern crate spki_sexp;
extern crate time;

extern crate etcd;
extern crate tempdir;
extern crate rocksdb;
extern crate byteorder;

#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
extern crate env_logger;

#[cfg(feature = "benches")]
extern crate test;

use mio::tcp::*;
use mio::EventLoop;
use mio::util::Slab;
use std::collections::VecDeque;
use std::net::SocketAddr;

mod line_conn;
mod downstream_conn;
mod listener;
mod config;
mod event_handler;
mod data;
mod replication_log;
mod replica;

use line_conn::{SexpPeer, LineConn};
use downstream_conn::Downstream;
use listener::Listener;
use event_handler::EventHandler;

use data::{Seqno,Operation,OpResp, PeerMsg, NodeViewConfig};
use config::{ConfigurationView, Epoch};

pub use config::ConfigClient;
pub use replica::ReplModel;
pub use replication_log::RocksdbLog;
pub use data::Role;

#[derive(Debug)]
pub enum ChainReplMsg {
    Operation {
        source: mio::Token,
        epoch: Epoch,
        seqno: Seqno,
        op: Vec<u8>,
    },
    ClientOperation {
        source: mio::Token,
        op: Vec<u8>,
    },
    Commit {
        source: mio::Token,
        epoch: Epoch,
        seqno: Seqno,
    },
    DownstreamResponse(OpResp),
    NewClientConn(Role, TcpStream),
    ForwardDownstream(Epoch, PeerMsg),
}

#[derive(Debug)]
pub struct ChainRepl {
    connections: Slab<EventHandler>,
    downstream_slot: Option<mio::Token>,
    node_config: NodeViewConfig,
    new_view: Option<ConfigurationView<NodeViewConfig>>,
    model: ReplModel<RocksdbLog>,
}

impl ChainRepl {
    pub fn new(model: ReplModel<RocksdbLog>) -> ChainRepl {
        ChainRepl {
            connections: Slab::new(1024),
            downstream_slot: None,
            node_config: Default::default(),
            new_view: None,
            model: model,
        }
    }

    pub fn listen(&mut self,
                  event_loop: &mut mio::EventLoop<ChainRepl>,
                  addr: SocketAddr,
                  role: Role) {
        info!("Listen on {:?} for {:?}", addr, role);
        let &mut ChainRepl { ref mut connections, ref mut node_config, .. } = self;
        let token = connections.insert_with(|token| {
                                   let l = Listener::new(addr, token, role.clone());
                                   match role {
                                       Role::Upstream => {
                                           node_config.peer_addr = Some(format!("{}",
                                                                                l.listen_addr()))
                                       }
                                       Role::Client => {
                                           node_config.client_addr = Some(format!("{}",
                                                                                l.listen_addr()))
                                       }
                                   }

                                   EventHandler::Listener(l)
                               })
                               .expect("insert listener");
        connections[token].initialize(event_loop, token);
    }

    pub fn set_downstream(&mut self,
                          event_loop: &mut mio::EventLoop<ChainRepl>,
                          target: Option<SocketAddr>) {
        match (self.downstream_slot, target) {
            (Some(_), Some(target)) => self.downstream().expect("downstream").reconnect_to(target),
            (None, Some(target)) => {
                let token = self.connections
                                .insert_with(|token| {
                                    EventHandler::Downstream(Downstream::new(Some(target), token))
                                })
                                .expect("insert downstream");
                &self.connections[token].initialize(event_loop, token);
                self.downstream_slot = Some(token)
            }
            (Some(_), None) => self.downstream().expect("downstream").disconnect(),
            (None, None) => (),
        }
    }

    fn process_action(&mut self, msg: ChainReplMsg, event_loop: &mut mio::EventLoop<ChainRepl>) {
        trace!("{:p}; got {:?}", self, msg);
        match msg {
            ChainReplMsg::Operation { source, seqno, epoch, op } => {
                if let Some(resp) = self.model.process_operation(source, seqno, epoch, &op) {
                    self.connections[source].response(resp);
                }
            }
            ChainReplMsg::ClientOperation { source, op } => {
                if let Some(resp) = self.model.process_client(source, &op) {
                    self.connections[source].response(resp);
                }
            }

            ChainReplMsg::Commit { seqno, .. } => {
                self.model.commit_observed(seqno);
            }

            ChainReplMsg::DownstreamResponse(reply) => self.process_downstream_response(reply),

            ChainReplMsg::NewClientConn(role, socket) => {
                self.process_new_client_conn(event_loop, role, socket)
            }
            ChainReplMsg::ForwardDownstream(epoch, msg) => {
                self.downstream().expect("Downstream").send_to_downstream(epoch, msg)
            }
        }
    }

    fn process_downstream_response(&mut self, reply: OpResp) {
        trace!("Downstream response: {:?}", reply);
        if let Some(waiter) = self.model.process_downstream_response(&reply) {
            if let Some(ref mut c) = self.connections.get_mut(waiter) {
                c.response(reply)
            }
        }
    }

    fn process_new_client_conn(&mut self,
                               event_loop: &mut mio::EventLoop<ChainRepl>,
                               role: Role,
                               socket: TcpStream) {
        let peer = socket.peer_addr().expect("peer address");
        let seqno = self.model.seqno();
        trace!("process_new_client_conn: {:?}@{:?}", role, peer);

        let token = self.connections
                        .insert_with(|token| {
                            match role {
                                Role::Client => EventHandler::Conn(LineConn::client(socket, token)),
                                Role::Upstream => {
                                    let mut conn = LineConn::upstream(socket, token);
                                    let msg = OpResp::HelloIWant(seqno);
                                    info!("Inform upstream about our current version, {:?}!", msg);
                                    conn.response(msg);
                                    EventHandler::Upstream(conn)
                                }
                            }
                        })
                        .expect("token insert");
        trace!("Client connection of {:?}/{:?} from {:?}",
               role,
               token,
               peer);
        &self.connections[token].initialize(event_loop, token);
    }

    fn process_rules<F: FnMut(ChainReplMsg)>(&mut self,
                                             event_loop: &mut mio::EventLoop<Self>,
                                             mut action: F)
                                             -> bool {
        let mut changed = false;

        if let Some(view) = self.new_view.take() {
            self.reconfigure(event_loop, view);
            changed |= true;
        }

        changed |= self.model.process_replication(|epoch, msg| {
            action(ChainReplMsg::ForwardDownstream(epoch, msg))
        });

        changed |= self.model.flush();

        changed
    }

    fn reconfigure(&mut self,
                   event_loop: &mut mio::EventLoop<Self>,
                   view: ConfigurationView<NodeViewConfig>) {
        info!("Reconfigure according to: {:?}", view);

        let listen_for_clients = view.should_listen_for_clients();
        info!("Listen for clients: {:?}", listen_for_clients);
        for p in self.listeners(Role::Client) {
            trace!("Active: {:?} -> {:?}", p, listen_for_clients);
            p.set_active(listen_for_clients);
        }

        let listen_for_upstreamp = view.should_listen_for_upstream();
        info!("Listen for upstreams: {:?}", listen_for_upstreamp);
        for p in self.listeners(Role::Upstream) {
            trace!("Active: {:?} -> {:?}", p, listen_for_clients);
            p.set_active(listen_for_upstreamp);
        }

        if let Some(ds) = view.should_connect_downstream() {
            info!("Push to downstream on {:?}", ds);
            let peer_addr = ds.peer_addr.as_ref().expect("Cannot reconnect to downstream with no peer listener");
            self.set_downstream(event_loop, Some(peer_addr.parse().expect("peer address")));
        } else {
            info!("Tail node!");
            self.set_downstream(event_loop, None);
        }

        info!("Reconfigure model: {:?}", view);
        self.model.reconfigure(&view)
    }

    fn downstream<'a>(&'a mut self) -> Option<&'a mut Downstream<SexpPeer>> {
        self.downstream_slot.map(move |slot| {
            match &mut self.connections[slot] {
                &mut EventHandler::Downstream(ref mut d) => d,
                other => {
                    panic!("Downstream slot not populated with a downstream instance: {:?}",
                           other)
                }
            }
        })
    }

    fn listeners<'a>(&'a mut self, role: Role) -> Vec<&'a mut Listener> {
        self.connections
            .iter_mut()
            .filter_map(|it| {
                match it {
                    &mut EventHandler::Listener(ref mut l) if l.role == role => Some(l),
                    _ => None,
                }
            })
            .collect()
    }

    fn converge_state(&mut self, event_loop: &mut mio::EventLoop<Self>) {
        let mut parent_actions = VecDeque::new();
        let mut changed = true;
        let mut iterations = 0;
        trace!("Converge begin");
        while changed {
            trace!("Iter: {:?}", iterations);
            changed = false;
            for conn in self.connections.iter_mut() {
                let changedp = conn.process_rules(event_loop,
                                                  &mut |item| parent_actions.push_back(item));
                if changedp {
                    trace!("Changed: {:?}", conn);
                };
                changed |= changedp;
            }

            let changedp = self.process_rules(event_loop,
                                              &mut |item| parent_actions.push_back(item));
            if changedp {
                trace!("Changed: {:?}", "Model");
            }
            changed |= changedp;

            trace!("Actions pending: {:?}", parent_actions.len());
            for action in parent_actions.drain(..) {
                trace!("Action: {:?}", action);
                self.process_action(action, event_loop);
            }
            iterations += 1;
        }
        trace!("Converged after {:?} iterations", iterations);
    }

    fn io_ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token) {
        self.converge_state(event_loop);
        if self.connections[token].should_close() && self.model.has_pending(token) {
            trace!("Close candidate: {:?}", token);
            let it = self.connections.remove(token);
            trace!("Removing; {:?}; {:?}", token, it);
            if Some(token) == self.downstream_slot {
                self.downstream_slot = None;
                self.model.reset();
            }
        }
    }

    fn handle_view_changed(&mut self, view: ConfigurationView<NodeViewConfig>) {
        self.new_view = Some(view)
    }

    fn committed_to(&mut self, seqno: Seqno) {
        info!("Committed upto: {:?}", seqno);
    }
    pub fn get_notifier(event_loop: &mut mio::EventLoop<Self>) -> Notifier {
        Notifier(event_loop.channel())
    }

    pub fn node_config(&self) -> NodeViewConfig {
        self.node_config.clone()
    }
}

#[derive(Debug)]
pub enum Notification {
    ViewChange(ConfigurationView<NodeViewConfig>),
    Shutdown,
    CommittedTo(Seqno),
}
pub struct Notifier(mio::Sender<Notification>);

impl Notifier {
    fn notify(&self, mut item: Notification) {
        use mio::NotifyError::*;
        use std::time::Duration;
        let mut backoff = Duration::from_millis(1);
        loop {
            item = match self.0.send(item) {
                Ok(_) => return,
                Err(Full(it)) => it,
                Err(e) => panic!("{:?}", e),
            };
            info!("Backoff: {:?}", backoff);
            std::thread::sleep(backoff);
            backoff = backoff * 2;
        }
    }

    pub fn view_changed(&self, view: ConfigurationView<NodeViewConfig>) {
        self.notify(Notification::ViewChange(view))
    }
    pub fn shutdown(&self) {
        self.notify(Notification::Shutdown)
    }
    pub fn committed_to(&self, seqno: Seqno) {
        self.notify(Notification::CommittedTo(seqno))
    }
}

impl mio::Handler for ChainRepl {
    // This is a bit wierd; we can pass a parent action back to enqueue some action.
    type Timeout = mio::Token;
    type Message = Notification;
    fn ready(&mut self,
             event_loop: &mut mio::EventLoop<Self>,
             token: mio::Token,
             events: mio::EventSet) {
        trace!("{:?}: {:?}", token, events);
        self.connections[token].handle_event(event_loop, events);
        self.io_ready(event_loop, token);
    }

    fn timeout(&mut self, event_loop: &mut EventLoop<Self>, token: mio::Token) {
        trace!("Timeout: {:?}", token);
        self.connections[token].handle_timeout();
        self.io_ready(event_loop, token);
    }

    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        trace!("Notified: {:?}", msg);
        match msg {
            Notification::ViewChange(view) => self.handle_view_changed(view),
            Notification::CommittedTo(seqno) => self.committed_to(seqno),
            Notification::Shutdown => {
                info!("Shutting down");
                event_loop.shutdown();
            }
        }
        self.converge_state(event_loop);
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Eq)]
struct GitStatus {
    object_id: String,
    branch: String,
    upstream: String,
    ahead: bool,
    behind: bool,
    staged: bool,
    unstaged: bool,
    untracked: bool,
}

impl GitStatus {
    fn new(status_txt: &str) -> Result<GitStatus, &'static str> {
        let mut s = GitStatus {
            object_id: String::new(),
            branch: String::new(),
            upstream: String::new(),
            ahead: false,
            behind: false,
            staged: false,
            unstaged: false,
            untracked: false,
        };
        for line in status_txt.lines() {
            if line.starts_with("# branch.oid") {
                let v: Vec<&str> = line.split(' ').collect();
                s.object_id = String::from(v[2]);
            } else if line.starts_with("# branch.head") {
                let v: Vec<&str> = line.split(' ').collect();
                s.branch = String::from(v[2]);
                continue;
            } else if line.starts_with("# branch.upstream") {
                let v: Vec<&str> = line.split(' ').collect();
                s.upstream = String::from(v[2]);
                continue;
            } else if line.starts_with("# branch.ab") {
                let v: Vec<&str> = line.split(' ').collect();
                if v[2] != "+0" {
                    s.ahead = true;
                }
                if v[3] != "-0" {
                    s.behind = true;
                }
            } else if line.starts_with("1 M.") {
                s.staged = true;
            } else if line.starts_with("1 .M") {
                s.unstaged = true;
            } else if line.starts_with("1 MM") {
                s.unstaged = true;
                s.staged = true;
            } else if line.starts_with("?") {
                s.untracked = true;
            }
        }
        Ok(s)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parse_dirty() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +1 -1
1 M. N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
1 .M N... 100644 100644 100644 5e8a8090976077ddf16252a560460a20dbbdd6a5 5e8a8090976077ddf16252a560460a20dbbdd6a5 gh-pages.sh
? foo.txt
";
        assert_eq!(
            GitStatus::new(&test_status).unwrap(),
            GitStatus {
                object_id: String::from("3845e7a3c3aadaaebb2d1b261bf07a9357d35a79"),
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: true,
                behind: true,
                staged: true,
                unstaged: true,
                untracked: true,
            }
        );
    }

    #[test]
    fn parse_clean() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
";
        assert_eq!(
            GitStatus::new(&test_status).unwrap(),
            GitStatus {
                object_id: String::from("3845e7a3c3aadaaebb2d1b261bf07a9357d35a79"),
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: false,
                behind: false,
                staged: false,
                unstaged: false,
                untracked: false,
            }
        );
    }

    #[test]
    fn parse_staged_and_unstaged_changes_on_same_file() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
1 MM N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
";
        assert_eq!(
            GitStatus::new(&test_status).unwrap(),
            GitStatus {
                object_id: String::from("3845e7a3c3aadaaebb2d1b261bf07a9357d35a79"),
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: false,
                behind: false,
                staged: true,
                unstaged: true,
                untracked: false,
            }
        );
    }
}
<commit_msg>Refactor to allow optional branch and upstream info<commit_after>#[derive(Debug, PartialEq, Eq)]
struct GitStatus {
    branch: Option<BranchInfo>,
    upstream: Option<UpstreamInfo>,
    staged: bool,
    unstaged: bool,
    untracked: bool,
    ignored: bool,
}

#[derive(Debug, PartialEq, Eq)]
struct BranchInfo {
    object_id: String,
    branch: Option<String>,
}

#[derive(Debug, PartialEq, Eq)]
struct UpstreamInfo {
    upstream: String,
    ahead: bool,
    behind: bool,
}

impl GitStatus {
    fn new(status_txt: &str) -> Result<GitStatus, &'static str> {
        let mut s = GitStatus {
            branch: None,
            upstream: None,
            staged: false,
            unstaged: false,
            untracked: false,
            ignored: false,
        };
        for line in status_txt.lines() {
            let words: Vec<&str> = line.split(' ').collect();
            if let Some(&first) = words.first() {
                match first {
                    "#" => {
                    },
                    "1" => {
                        s.staged = true;
                        s.unstaged = true;
                    },
                    "?" => {
                        s.untracked = true;
                    },
                    "!" => {
                        s.ignored = true;
                    },
                    _ => {},
                }
            }
        }
        Ok(s)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parse_clean() {
        let test_status = "\n";
        assert_eq!(
            GitStatus::new(test_status).unwrap(),
            GitStatus {
                branch: None,
                upstream: None,
                staged: false,
                unstaged: false,
                untracked: false,
                ignored: false,
            }
        );
    }

    #[test]
    fn parse_dirty() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +1 -1
1 M. N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
1 .M N... 100644 100644 100644 5e8a8090976077ddf16252a560460a20dbbdd6a5 5e8a8090976077ddf16252a560460a20dbbdd6a5 gh-pages.sh
? foo.txt
! ignored.txt
";
        assert_eq!(
            GitStatus::new(test_status).unwrap(),
            GitStatus {
                branch: Some(BranchInfo {
                    object_id: String::from("3845e7a3c3aadaaebb2d1b261bf07a9357d35a79"),
                    branch: Some(String::from("master")),
                }),
                upstream: Some(UpstreamInfo {
                    upstream: String::from("origin/master"),
                    ahead: true,
                    behind: true,
                }),
                staged: true,
                unstaged: true,
                untracked: true,
                ignored: true,
            }
        );
    }

    #[test]
    fn parse_branch() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
";
        assert_eq!(
            GitStatus::new(test_status).unwrap().branch,
            Some(BranchInfo {
                object_id: String::from("3845e7a3c3aadaaebb2d1b261bf07a9357d35a79"),
                branch: Some(String::from("master")),
            })
        );
    }

    #[test]
    fn parse_upstream() {
        let test_status = "\
# branch.upstream origin/master
# branch.ab +1 -1
";
        assert_eq!(
            GitStatus::new(test_status).unwrap().upstream,
            Some(UpstreamInfo {
                upstream: String::from("origin/master"),
                ahead: true,
                behind: true,
            })
        );
    }

    #[test]
    fn parse_staged_and_unstaged_on_same_file() {
        let test_status = "\
1 MM N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
";
        let s = GitStatus::new(test_status).unwrap();
        assert!(s.staged);
        assert!(s.unstaged);
    }

    #[test]
    fn parse_detached_head() {
        let test_status = "\
# branch.oid 2a7bb916bba69a5fc9d428acc80b1bce64e3e0bc
# branch.head (detached)
";
        assert_eq!(
            GitStatus::new(test_status).unwrap().branch,
            Some(BranchInfo {
                object_id: String::from("2a7bb916bba69a5fc9d428acc80b1bce64e3e0bc"),
                branch: None
            })
        );
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]
#![feature(map_first_last)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(let_else)]
#![feature(io_error_more)]
#![feature(yeet_expr)]
#![feature(is_some_with)]
#![feature(nonzero_ops)]
#![feature(local_key_cell_methods)]
// Configure clippy and other lints
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq,
    clippy::derive_hash_xor_eq,
    clippy::too_many_arguments
)]
#![warn(
    rust_2018_idioms,
    clippy::cast_possible_wrap, // unsigned -> signed
    clippy::cast_sign_loss, // signed -> unsigned
    clippy::cast_lossless,
    clippy::cast_possible_truncation,
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod sync;
mod thread;
mod vector_clock;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::concurrency::data_race::{
    AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd,
    EvalContextExt as DataRaceEvalContextExt,
};
pub use crate::diagnostics::{
    register_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
    NonHaltingDiagnostic, TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt, MiriMemoryKind,
    Provenance, ProvenanceExtra, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, Stack, Stacks,
};
pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId};
pub use crate::thread::{
    EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
};
pub use crate::vector_clock::{VClock, VTimestamp, VectorIdx};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
];
<commit_msg>really, clippy?!?<commit_after>#![feature(rustc_private)]
#![feature(map_first_last)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(let_else)]
#![feature(io_error_more)]
#![feature(yeet_expr)]
#![feature(is_some_with)]
#![feature(nonzero_ops)]
#![feature(local_key_cell_methods)]
// Configure clippy and other lints
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq,
    clippy::derive_hash_xor_eq,
    clippy::too_many_arguments,
    clippy::type_complexity
)]
#![warn(
    rust_2018_idioms,
    clippy::cast_possible_wrap, // unsigned -> signed
    clippy::cast_sign_loss, // signed -> unsigned
    clippy::cast_lossless,
    clippy::cast_possible_truncation,
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod sync;
mod thread;
mod vector_clock;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::concurrency::data_race::{
    AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd,
    EvalContextExt as DataRaceEvalContextExt,
};
pub use crate::diagnostics::{
    register_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
    NonHaltingDiagnostic, TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt, MiriMemoryKind,
    Provenance, ProvenanceExtra, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, Stack, Stacks,
};
pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId};
pub use crate::thread::{
    EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
};
pub use crate::vector_clock::{VClock, VTimestamp, VectorIdx};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
];
<|endoftext|>


<commit_before>#![feature(asm, libc)]
#![allow(dead_code, raw_pointer_derive)]

#[macro_use]
extern crate syscall;
extern crate libc;

mod clone;
mod futex;
mod mutex;
#[macro_use]
mod thread;
mod stack;

#[test]
fn it_works() {
    use libc;
    use std::ptr;
    use std::mem;
    use thread::Thread;
    use stack::Stack;

    extern fn test(a: *mut libc::c_void) -> libc::c_int {
        println!("Hello! I am a thread");

        let thd: *const Thread = unsafe { std::mem::transmute(a) };
        unsafe {println!("here's my arg {:?} ", *thd);}

        let x = offset_of!(Thread, tid);
        println!("tid offset = {}", x);

        unsafe {
            let thd = thread::get_current_thread();
            println!("hello, TLS from child {:?} ", thd);

            thread::set_tls_mem(x, 123456);

            let thd = thread::get_current_thread();
            println!("i should have set tid = {:?}", thd.tid );
        }

        0
    }

    let mut stack = Stack::new();
    let mut thd = stack.install_thread_block();

    let id = unsafe {
        clone::clone(test,
                     stack.stack_top,
                     clone::flags::COMMON,
                     thd as *mut _ as *mut _,
                     &mut thd.pid,
                     std::ptr::null_mut(),
                     &mut thd.tid)
    };

    println!("child id = {}, {}, {}", id, thd.tid, thd.pid);
    println!("stack is valid? {}", stack.is_valid());

    loop {}
}
<commit_msg>Clean up test a bit<commit_after>#![feature(asm, libc)]
#![allow(dead_code, raw_pointer_derive)]

#[macro_use]
extern crate syscall;
extern crate libc;

mod clone;
mod futex;
mod mutex;
#[macro_use]
mod thread;
mod stack;

#[test]
fn it_works() {
    use libc;
    use std::ptr;
    use std::mem;
    use thread::Thread;
    use stack::Stack;

    extern fn test(arg: *mut libc::c_void) -> libc::c_int {
        println!("Hello! I am a thread");

        unsafe {
            let thd: *const Thread = std::mem::transmute(arg);
            println!("Arg to child: 0x{:x} ", (*thd).magic);
        }

        let offset = offset_of!(Thread, tid);
        println!("tid offset = {}", offset);

        unsafe {
            let thd = thread::get_current_thread();
            println!("Child TLS: {:?} ", thd);

            thread::set_tls_mem(offset, 123456);

            let thd = thread::get_current_thread();
            println!("i should have set tid = {:?}", thd.tid );
        }

        0
    }

    let stack = Stack::new();
    let mut thd = stack.install_thread_block();
    thd.magic = 0x55005500;

    let id = unsafe {
        clone::clone(test,
                     stack.stack_top,
                     clone::flags::COMMON,
                     thd as *mut _ as *mut _,
                     &mut thd.pid,
                     std::ptr::null_mut(),
                     &mut thd.tid)
    };

    println!("child id = {}, {}, {}", id, thd.tid, thd.pid);
    println!("stack is valid? {}", stack.is_valid());

    loop {}
}
<|endoftext|>


<commit_before>// struct Printer {
// 	indent:1, // # of tabs added for each additional recursive level
// 	width:80,
// 	depth:Option::None
// 	// stream:Option::None // Object is a stream
// }

#![allow(dead_code)]

extern crate serde;

struct PPrinter {
	indent:u16,
	width:u16,
	depth:Option<u16>,
	stream:Option<bool>
}

impl PPrinter {
	fn width(&mut self, width : u16) -> &mut PPrinter {
		self.width = width;
		return self;
	}

	fn indent(&mut self, indent : u16) -> &mut PPrinter {
		self.indent = indent;
		return self;
	}

	fn depth(&mut self, depth : Option<u16>) -> &mut PPrinter {
		self.depth = depth;
		return self;
	}

	fn stream(&mut self, stream : Option<bool>) -> &mut PPrinter {
		self.stream = stream;
		return self;
	}
}

macro_rules! PPrint {
	( $( $x:expr ),* ) => {
		{

		}
	};
}

#[test]
fn it_works() {
}
<commit_msg> testing more<commit_after>// struct Printer {
// 	indent:1, // # of tabs added for each additional recursive level
// 	width:80,
// 	depth:Option::None
// 	// stream:Option::None // Object is a stream
// }

#![allow(dead_code)]

extern crate serde;
use serde::json;

struct PPrinter {
	indent:u16,
	width:u16,
	depth:Option<u16>,
	stream:Option<bool>
}

impl PPrinter {
	fn width(&mut self, width : u16) -> &mut PPrinter {
		self.width = width;
		return self;
	}

	fn indent(&mut self, indent : u16) -> &mut PPrinter {
		self.indent = indent;
		return self;
	}

	fn depth(&mut self, depth : Option<u16>) -> &mut PPrinter {
		self.depth = depth;
		return self;
	}

	fn stream(&mut self, stream : Option<bool>) -> &mut PPrinter {
		self.stream = stream;
		return self;
	}
}

macro_rules! PPrint {
	( $( $x:expr ),* ) => {
		{

		}
	};
}

// to_string_pretty
struct Point {
    x: i32,
    y: i32,
}

#[test]
fn it_works() {
	// let point : json::value::Value = Point { x: 1, y: 2 };
	let a = json::value::Value::Object(Point { x: 1, y: 2 });
	let serialized_point = json::to_string_pretty(&a).unwrap();

	println!("{}", serialized_point); // prints: {"x":1,"y":2}
}
<|endoftext|>


<commit_before>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.json_paths()
            .iter()
            .find(|path| path.file_name().unwrap().to_str().unwrap().eq_ignore_ascii_case(crate_name))
            .map(Crate::from_index_path)
    }

    // TODO: this should be crate_iter that returns an Iterator
    pub fn crates(&self) -> Vec<Crate> {
        self.json_paths()
            .iter()
            .map(Crate::from_index_path)
            .collect::<Vec<_>>()
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for crate_ in self.crates().iter() {
            let version = crate_.latest_version();
            let mut deps_names = version.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(crate_info.name, deps_names);
        }

        map
    }
}

pub struct Crate {
    infos: Vec<CrateInfo>,
}

impl Crate {
    pub fn from_index_path(index_path: &PathBuf) -> Crate {
        let mut infos = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let info: CrateInfo = rustc_serialize::json::decode(&line.unwrap()).unwrap();
            infos.push(info);
        }
        Crate {infos: infos}
    }

    pub fn latest_version(&self) -> &CrateInfo {
        &self.infos[self.infos.len()]
    }
}

#[test]
fn test_dependencies() {
    let index = CratesIndex::new("_test".into());
    if !index.exists() {
        index.clone().unwrap();
    }
}
<commit_msg>Fix borrow issue<commit_after>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.json_paths()
            .iter()
            .find(|path| path.file_name().unwrap().to_str().unwrap().eq_ignore_ascii_case(crate_name))
            .map(Crate::from_index_path)
    }

    // TODO: this should be crate_iter that returns an Iterator
    pub fn crates(&self) -> Vec<Crate> {
        self.json_paths()
            .iter()
            .map(Crate::from_index_path)
            .collect::<Vec<_>>()
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for crate_ in self.crates().iter() {
            let version = crate_.latest_version();
            let mut deps_names = version.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(version.name.clone(), deps_names);
        }

        map
    }
}

pub struct Crate {
    infos: Vec<CrateInfo>,
}

impl Crate {
    pub fn from_index_path(index_path: &PathBuf) -> Crate {
        let mut infos = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let info: CrateInfo = rustc_serialize::json::decode(&line.unwrap()).unwrap();
            infos.push(info);
        }
        Crate {infos: infos}
    }

    pub fn latest_version(&self) -> &CrateInfo {
        &self.infos[self.infos.len()]
    }
}

#[test]
fn test_dependencies() {
    let index = CratesIndex::new("_test".into());
    if !index.exists() {
        index.clone().unwrap();
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;

mod api;
mod commands;
mod common;
mod errors;
mod services;

use api::anoncreds::AnoncredsAPI;
use api::sovrin::SovrinAPI;
use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;

pub struct SovrinClient {
    anoncreds: AnoncredsAPI,
    sovrin: SovrinAPI
}

impl SovrinClient {
    pub fn new() -> SovrinClient {
        let command_executor = Arc::new(CommandExecutor::new());
        SovrinClient {
            anoncreds: AnoncredsAPI::new(command_executor.clone()),
            sovrin: SovrinAPI::new(command_executor.clone())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use common::SovrinIdentity;

    use std::sync::mpsc::channel;

    #[test]
    fn sovrin_client_can_be_created() {
        let sovrin_client = SovrinClient::new();
        assert! (true, "No crashes on SovrinClient::new");
    }

    #[test]
    fn sovrin_client_can_be_dropped() {
        fn drop_test() {
            let sovrin_client = SovrinClient::new();
        }

        drop_test();
        assert! (true, "No crashes on SovrinClient::drop");
    }

    #[test]
    fn sovrin_set_did_method_can_be_called() {
        let (sender, receiver) = channel();

        let cb = Box::new(move |result| {
            match result {
                Ok(val) => sender.send("OK"),
                Err(err) => sender.send("ERROR")
            };
        });

        let sovrin_identity = SovrinIdentity::new("DID0", None, Some("PK0"));
        let sovrin_client = SovrinClient::new();
        sovrin_client.sovrin.send_nym_tx(&sovrin_identity, "DID1", None, None, None, None, cb);

        match receiver.recv() {
            Ok(result) => {
                assert_eq! ("OK", result);
            }
            Err(err) => {
                panic!("Error on result recv: {:?}", err);
            }
        }
    }
}<commit_msg>* Added crypto and wallet members to SovrinClient struct<commit_after>#[macro_use]
extern crate log;

mod api;
mod commands;
mod common;
mod errors;
mod services;

use api::anoncreds::AnoncredsAPI;
use api::crypto::CryptoAPI;
use api::sovrin::SovrinAPI;
use api::wallet::WalletAPI;

use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;

pub struct SovrinClient {
    anoncreds: AnoncredsAPI,
    crypto: CryptoAPI,
    sovrin: SovrinAPI,
    wallet: WalletAPI
}

impl SovrinClient {
    pub fn new() -> SovrinClient {
        let command_executor = Arc::new(CommandExecutor::new());
        SovrinClient {
            anoncreds: AnoncredsAPI::new(command_executor.clone()),
            crypto: CryptoAPI::new(command_executor.clone()),
            sovrin: SovrinAPI::new(command_executor.clone()),
            wallet: WalletAPI::new(command_executor.clone())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use common::SovrinIdentity;

    use std::sync::mpsc::channel;

    #[test]
    fn sovrin_client_can_be_created() {
        let sovrin_client = SovrinClient::new();
        assert! (true, "No crashes on SovrinClient::new");
    }

    #[test]
    fn sovrin_client_can_be_dropped() {
        fn drop_test() {
            let sovrin_client = SovrinClient::new();
        }

        drop_test();
        assert! (true, "No crashes on SovrinClient::drop");
    }

    #[test]
    fn sovrin_set_did_method_can_be_called() {
        let (sender, receiver) = channel();

        let cb = Box::new(move |result| {
            match result {
                Ok(val) => sender.send("OK"),
                Err(err) => sender.send("ERROR")
            };
        });

        let sovrin_identity = SovrinIdentity::new("DID0", None, Some("PK0"));
        let sovrin_client = SovrinClient::new();
        sovrin_client.sovrin.send_nym_tx(&sovrin_identity, "DID1", None, None, None, None, cb);

        match receiver.recv() {
            Ok(result) => {
                assert_eq! ("OK", result);
            }
            Err(err) => {
                panic!("Error on result recv: {:?}", err);
            }
        }
    }
}<|endoftext|>


<commit_before>//! Rust implementation of the NIfTI-1 file format.
//!
//! # Example
//!
//! ```no_run
//! use nifti::{NiftiObject, InMemNiftiObject, NiftiVolume};
//! # use nifti::error::Result;
//!
//! # fn run() -> Result<()> {
//! let obj = InMemNiftiObject::from_file("myvolume.nii.gz")?;
//! // use obj
//! let header = obj.header();
//! let volume = obj.volume();
//! let dims = volume.dim();
//! # Ok(())
//! # }
//! ```
//!
//! The library will automatically look for the respective volume when
//! specifying just the header file:
//!
//! ```no_run
//! use nifti::{NiftiObject, InMemNiftiObject};
//! # use nifti::error::Result;
//! # fn run() -> Result<()> {
//! let obj = InMemNiftiObject::from_file("myvolume.hdr.gz")?;
//! # Ok(())
//! # }
//! ```
//!
//! You can also convert a volume to an [`ndarray::Array`](https://docs.rs/ndarray)
//! and work from there:
//!
//! ```no_run
//! # #![cfg(feature = "ndarray_volumes")]
//! # use nifti::error::Result;
//! # fn run() -> Result<()> {
//! use nifti::{NiftiObject, InMemNiftiObject, IntoNdArray};
//! # let obj = InMemNiftiObject::from_file("myvolume.hdr.gz").unwrap();
//! let volume = obj.into_volume().to_ndarray::<f32>()?;
//! # Ok(())
//! # }
//! ```
//!
#![deny(missing_debug_implementations)]
#![warn(missing_docs, unused_extern_crates, trivial_casts, unused_results)]

#[macro_use] extern crate quick_error;
#[macro_use] extern crate num_derive;
#[macro_use] extern crate derive_builder;
#[cfg(feature = "ndarray_volumes")] extern crate ndarray;

#[cfg(ndarray_volumes)]
extern crate ndarray;

extern crate num;
extern crate byteorder;
extern crate flate2;

pub mod extension;
pub mod header;
pub mod object;
pub mod volume;
pub mod error;
pub mod typedef;
mod util;

pub use error::{NiftiError, Result};
pub use object::{NiftiObject, InMemNiftiObject};
pub use extension::{Extender, Extension, ExtensionSequence};
pub use header::{NiftiHeader, NiftiHeaderBuilder};
pub use volume::{NiftiVolume, InMemNiftiVolume, Sliceable};
#[cfg(feature = "ndarray_volumes")] pub use volume::ndarray::IntoNdArray;
pub use typedef::{NiftiType, Unit, Intent, XForm, SliceOrder};
pub use util::Endianness;
<commit_msg>Fix issue in ndarray example in lib.rs<commit_after>//! Rust implementation of the NIfTI-1 file format.
//!
//! # Example
//!
//! ```no_run
//! use nifti::{NiftiObject, InMemNiftiObject, NiftiVolume};
//! # use nifti::error::Result;
//!
//! # fn run() -> Result<()> {
//! let obj = InMemNiftiObject::from_file("myvolume.nii.gz")?;
//! // use obj
//! let header = obj.header();
//! let volume = obj.volume();
//! let dims = volume.dim();
//! # Ok(())
//! # }
//! ```
//!
//! The library will automatically look for the respective volume when
//! specifying just the header file:
//!
//! ```no_run
//! use nifti::{NiftiObject, InMemNiftiObject};
//! # use nifti::error::Result;
//! # fn run() -> Result<()> {
//! let obj = InMemNiftiObject::from_file("myvolume.hdr.gz")?;
//! # Ok(())
//! # }
//! ```
//!
//! You can also convert a volume to an [`ndarray::Array`](https://docs.rs/ndarray)
//! and work from there:
//!
//! ```no_run
//! # #[cfg(feature = "ndarray_volumes")]
//! # use nifti::error::Result;
//! # #[cfg(feature = "ndarray_volumes")]
//! # fn run() -> Result<()> {
//! # use nifti::{NiftiObject, InMemNiftiObject};
//! use nifti::IntoNdArray;
//! # let obj = InMemNiftiObject::from_file("myvolume.hdr.gz").unwrap();
//! let volume = obj.into_volume().to_ndarray::<f32>()?;
//! # Ok(())
//! # }
//! ```
//!
#![deny(missing_debug_implementations)]
#![warn(missing_docs, unused_extern_crates, trivial_casts, unused_results)]

#[macro_use] extern crate quick_error;
#[macro_use] extern crate num_derive;
#[macro_use] extern crate derive_builder;
#[cfg(feature = "ndarray_volumes")] extern crate ndarray;

#[cfg(ndarray_volumes)]
extern crate ndarray;

extern crate num;
extern crate byteorder;
extern crate flate2;

pub mod extension;
pub mod header;
pub mod object;
pub mod volume;
pub mod error;
pub mod typedef;
mod util;

pub use error::{NiftiError, Result};
pub use object::{NiftiObject, InMemNiftiObject};
pub use extension::{Extender, Extension, ExtensionSequence};
pub use header::{NiftiHeader, NiftiHeaderBuilder};
pub use volume::{NiftiVolume, InMemNiftiVolume, Sliceable};
#[cfg(feature = "ndarray_volumes")] pub use volume::ndarray::IntoNdArray;
pub use typedef::{NiftiType, Unit, Intent, XForm, SliceOrder};
pub use util::Endianness;
<|endoftext|>


<commit_before>pub fn quicksort<T: PartialEq + PartialOrd>(vec: &mut [T]) -> &mut [T] {
    if vec.len() <= 1 {
        return vec;
    }
    let pivot: usize = 0;
    let mut first_opened = Vec::new();
    let mut last_closed: usize = 0;

    for i in 1..vec.len() {
        first_opened.push(i);
        if vec[i] < vec[pivot] {
            let to = first_opened.remove(0);
            vec.swap(i, to);
            last_closed = to;
        }
    }

    vec.swap(pivot, last_closed);
    quicksort(&mut vec[0..last_closed]);
    quicksort(&mut vec[last_closed+1..]);
    vec
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vec_of_u64() {
        let sorted: Vec<u64> = vec![1, 1, 2, 3, 3, 4, 5, 5, 6, 9];
        let mut unsorted: Vec<u64> = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
        quicksort(&mut unsorted);

        assert_eq!(unsorted, sorted.as_slice());
    }

    #[test]
    fn test_vec_of_u8() {
        let sorted = "        Tabcdeeefghhijklmnoooopqrrstuuvwxyz".to_string().into_bytes();
        let mut unsorted = "The quick brown fox jumps over the lazy dog".to_string().into_bytes();
        quicksort(&mut unsorted);

        assert_eq!(sorted, unsorted);
    }

    #[test]
    fn test_array_of_u8() {
        let sorted: [u8; 10] = [1, 2, 3, 4, 5, 5, 5, 7, 9, 10];
        let mut unsorted: [u8; 10] = [7, 5, 3, 2, 5, 1, 4, 5, 9, 10];
        quicksort(&mut unsorted);

        assert_eq!(sorted, unsorted);
    }
}
<commit_msg>Drop redundant PartialEq trait constraint<commit_after>pub fn quicksort<T: PartialOrd>(vec: &mut [T]) -> &mut [T] {
    if vec.len() <= 1 {
        return vec;
    }
    let pivot: usize = 0;
    let mut first_opened = Vec::new();
    let mut last_closed: usize = 0;

    for i in 1..vec.len() {
        first_opened.push(i);
        if vec[i] < vec[pivot] {
            let to = first_opened.remove(0);
            vec.swap(i, to);
            last_closed = to;
        }
    }

    vec.swap(pivot, last_closed);
    quicksort(&mut vec[0..last_closed]);
    quicksort(&mut vec[last_closed+1..]);
    vec
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vec_of_u64() {
        let sorted: Vec<u64> = vec![1, 1, 2, 3, 3, 4, 5, 5, 6, 9];
        let mut unsorted: Vec<u64> = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
        quicksort(&mut unsorted);

        assert_eq!(unsorted, sorted.as_slice());
    }

    #[test]
    fn test_vec_of_u8() {
        let sorted = "        Tabcdeeefghhijklmnoooopqrrstuuvwxyz".to_string().into_bytes();
        let mut unsorted = "The quick brown fox jumps over the lazy dog".to_string().into_bytes();
        quicksort(&mut unsorted);

        assert_eq!(sorted, unsorted);
    }

    #[test]
    fn test_array_of_u8() {
        let sorted: [u8; 10] = [1, 2, 3, 4, 5, 5, 5, 7, 9, 10];
        let mut unsorted: [u8; 10] = [7, 5, 3, 2, 5, 1, 4, 5, 9, 10];
        quicksort(&mut unsorted);

        assert_eq!(sorted, unsorted);
    }
}
<|endoftext|>


<commit_before>//! ## Examples
//!
//! ```rust,norun
//!
//! extern crate iron_tera;
//! use iron_tera::{TeraEngine, Template, TemplateMode};
//!
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/user", user_handler, "user");
//!
//!     let mut chain = Chain::new(router);
//!     // TeraEngine will panic here if parsing fails, it's part of the Tera library
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//! // Building a template from a context.
//! fn user_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//!
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```

#![feature(proc_macro)]
#![allow(dead_code)]

extern crate serde_json;

#[macro_use] extern crate tera;

extern crate iron;

extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> TemplateMode {
        TemplateMode::Serialized(to_value(serialized))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice or preferably a `&str`
    pub fn new<S: AsRef<str>>(dir: &S) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir.as_ref()) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};

    #[derive(Serialize)]
    struct Product {
        name: String,
        value: i32,
    }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name.unwrap(), "users/profile.html".to_string());
                assert_eq!(h.value
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<commit_msg>remove line<commit_after>//! ## Examples
//!
//! ```rust
//! extern crate iron_tera;
//! use iron_tera::{TeraEngine, Template, TemplateMode};
//!
//! fn main() {
//!     let mut router = Router::new();
//!     router.get("/user", user_handler, "user");
//!
//!     let mut chain = Chain::new(router);
//!     // TeraEngine will panic here if parsing fails, it's part of the Tera library
//!     let teng = TeraEngine::new("src/examples/templates/**/*");
//!     chain.link_after(teng);
//!
//!     Iron::new(chain).http("localhost:5000").unwrap();
//! }
//! // Building a template from a context.
//! fn user_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     let mut context = Context::new();
//!     context.add("username", &"Bob");
//!     context.add("numbers", &vec![1, 2, 3]);
//!     context.add("bio", &"<script>alert('pwnd');</script>");
//!
//!     resp.set_mut(Template::new("users/profile.html", TemplateMode::from_context(context)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! // The following uses serde's Serialize
//! #[derive(Serialize)]
//! struct Product {
//!     name: String,
//!     value: i32,
//! }
//!
//! fn produce_handler(_: &mut Request) -> IronResult<Response> {
//!     let mut resp = Response::new();
//!
//!     // Using serialized values
//!     let product = Product {
//!         name: "Foo".into(),
//!         value: 42,
//!     };
//!     resp.set_mut(Template::new("product.html", TemplateMode::from_serial(&product)))
//!         .set_mut(status::Ok);
//!     Ok(resp)
//! }
//! ```

#![feature(proc_macro)]
#![allow(dead_code)]

extern crate serde_json;

#[macro_use] extern crate tera;

extern crate iron;

extern crate serde;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap, status};
use iron::modifier::Modifier;
use iron::headers::ContentType;

use tera::{Tera, Context};

use serde::Serialize;
use serde_json::{Value, to_value};

/// There are 2 main ways to pass data to generate a template.
#[derive(Clone)]
pub enum TemplateMode {
    /// TeraContext constructor takes a `Context`
    TeraContext(Context),
    /// Serialized constructor takes a `Value` from `serde_json`
    Serialized(Value),
}

/// TemplateMode should only ever be created from these smart constructors,
/// not with the enums type constructors.
impl TemplateMode {
    pub fn from_context(context: Context) -> TemplateMode {
        TemplateMode::TeraContext(context)
    }
    pub fn from_serial<S: Serialize>(serialized: S) -> TemplateMode {
        TemplateMode::Serialized(to_value(serialized))
    }
}

/// Our template holds a name (path to template) and a mode (constructed with `from_context` or `from_serial`)
#[derive(Clone)]
pub struct Template {
    mode: TemplateMode,
    name: String,
}

impl Template {
    pub fn new(name: &str, mode: TemplateMode) -> Template {
        Template {
            name: name.into(),
            mode: mode,
        }
    }
}

/// TeraEngine holds the Tera struct so that it can be used by many handlers without explicitly passing
pub struct TeraEngine {
    pub tera: Tera,
}

/// `compile_templates!` is used to parse the contents of a dir for all templates.
impl TeraEngine {
    /// Take a `String` and convert to a slice or preferably a `&str`
    pub fn new<S: AsRef<str>>(dir: &S) -> TeraEngine {
        TeraEngine { tera: compile_templates!(dir.as_ref()) }
    }
}

impl typemap::Key for TeraEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<TeraEngine>(self);
    }
}

/// The middleware implementation for TeraEngine
impl AfterMiddleware for TeraEngine {
    /// This is where all the magic happens. We extract `TeraEngine` from Iron's `Response`,
    /// determine what `TemplateMode` we should render in, and pass the appropriate values to
    /// tera's render methods.
    fn after(&self, _: &mut Request, mut resp: Response) -> IronResult<Response> {
        let wrapper = resp.extensions.remove::<TeraEngine>().and_then(|t| {
            match t.mode {
                TemplateMode::TeraContext(context) => Some(self.tera.render(&t.name, context)),
                TemplateMode::Serialized(value) => Some(self.tera.value_render(&t.name, &value)),
            }
        });
        match wrapper {
            Some(result) => {
                result.map_err(|e| IronError::new(e, status::InternalServerError))
                    .and_then(|page| {
                        if !resp.headers.has::<ContentType>() {
                            resp.headers.set(ContentType::html());
                        }
                        resp.set_mut(page);
                        Ok(resp)
                    })
            }
            None => Ok(resp),
        }
    }

    fn catch(&self, req: &mut Request, mut err: IronError) -> IronResult<Response> {
        err.response = self.after(req, err.response)?;
        Err(err)
    }
}

#[cfg(test)]
mod tests {
    use super::{TeraEngine, Template, TemplateMode};
    use iron::prelude::*;
    use tera::{Tera, Context};

    #[derive(Serialize)]
    struct Product {
        name: String,
        value: i32,
    }

    fn test_resp() -> IronResult<Response> {
        let resp = Response::new();

        let mut context = Context::new();
        context.add("username", &"Foo");
        context.add("bio", &"Bar");
        context.add("numbers", &vec![1, 2, 3]);

        Ok(resp.set(Template::new("users/foo.html", TemplateMode::from_context(context))))
    }

    #[test]
    fn example() {
        let mut resp = test_resp().ok().expect("response expected");

        match resp.get::<TeraEngine>() {
            Ok(h) => {
                assert_eq!(h.name.unwrap(), "users/profile.html".to_string());
                assert_eq!(h.value
                               .as_object()
                               .unwrap()
                               .get(&"Foo".to_string())
                               .unwrap()
                               .as_string()
                               .unwrap(),
                           "Bar");
            }
            _ => panic!("template expected"),
        }
        // let teng = TeraEngine::new("src/test_template/**/*");
        // // Context option 1
        // let mut context = Context::new();
        // context.add("firstname", &"Foo");
        // context.add("lastname", &"Bar");
        //
        // let t = Template::new("index", TemplateMode::TeraContext(context));
        //
        // // Context option 2
        // let mut c2 = Context::new();
        // c2.add("firstname", &"Foo");
        // c2.add("lastname", &"Bar");
        //
        // let t4 = Template::new("index", TemplateMode::from_context(c2));
        //
        // // Using serialized values
        // let product = Product {
        //     name: "Foo".into(),
        //     value: 42,
        // };
        // // option 2
        // let t2 = Template::new("index", TemplateMode::from_serial(&product));
    }
}
<|endoftext|>


<commit_before>//! This is an implementation of variadic templates using recursive generics.
//! It functions something like a TypeMap, but the optimizer should make getting
//! and adding values much faster.

use std::any::{Any, TypeId};
use std::mem;

/// Something that
pub trait RecursiveVariadic {
    // would be nice to have a
    // type Data<T> = T
    fn get<N: Any>(&self) -> Option<&N>;
    fn get_mut<N: Any>(&mut self) -> Option<&mut N>;
    fn and<N: Any>(self, val: N) -> Entry<N, Self> where Self: Sized {
        Entry {
            data: val,
            parent: self,
        }
    }
}

pub type Empty = ();
impl RecursiveVariadic for Empty {
    fn get<N: Any>(&self) -> Option<&N> { None }
    fn get_mut<N: Any>(&mut self) -> Option<&mut N> { None }
}

pub struct Entry<T, R> {
    data: T,
    parent: R,
}

impl<T: Any, R: RecursiveVariadic> RecursiveVariadic for Entry<T, R> {
    fn get<N: Any>(&self) -> Option<&N> {
        if TypeId::of::<N>() == TypeId::of::<T>() {
            Some(unsafe { mem::transmute(&self.data) })
        } else {
            self.parent.get()
        }
    }
    fn get_mut<N: Any>(&mut self) -> Option<&mut N> {
        if TypeId::of::<N>() == TypeId::of::<T>() {
            Some(unsafe { mem::transmute(&mut self.data) })
        } else {
            self.parent.get_mut()
        }
    }
}

/// This macro is a standin for the way this would be implemented
/// with Higher Kinded Types. It creates a wrapper struct that for every N
/// puts an entry in the RecursiveVariadic it wraps for a Output<N>.
///
/// # Examples
///
/// This example creates a wrapper that gets a thing.
///
/// ```rust
///     #[macro_use]
///     extern crate recursive_variadic;
///
///     use recursive_variadic::*;
///
///     create_wrapper!(VecHolder, N => Vec<N>);
///
///     fn vec_variadic() {
///         // this struct maps types to a vector of that type.
///         let mut my_vecs = VecHolder::new()
///             .and_default::<usize>()
///             .and_default::<bool>()
///             .and::<u32>(Vec::new()); // if you want to provide a value
///         my_vecs.get_mut::<usize>().unwrap().push(2);
///         my_vecs.get_mut::<bool>().unwrap().push(false);
///         my_vecs.get_mut::<u32>().unwrap().push(0);
///
///         assert!(my_vecs.get::<String>().is_none());
///     }
///
///     fn main() { vec_variadic() }
/// ```
///
/// Using an creating a wrapper around an Id type is redundant,
/// but better shows what this macro does.
///
/// ```rust
///     #[macro_use]
///     extern crate recursive_variadic;
///
///     use recursive_variadic::*;
///
///     type Id<N> = N;
///
///     fn id_variadic() {
///         create_wrapper!(IdVariadic, N => Id<N>, PRIV);
///         let mut my_things = IdVariadic::new()
///             .and_default::<usize>()
///             .and(23i32);
///
///         *my_things.get_mut::<i32>().unwrap() += 1;
///         assert!(my_things.get::<usize>().is_some());
///     }
///
///     fn main() { id_variadic() }
/// ```

#[macro_export]
macro_rules! create_wrapper {
    ($name:ident, N => $output:ident<N>) => {
        create_wrapper!($name, $output, pub);
    };

    ($name:ident, N => $output:ident<N>, PRIV) => {
        create_wrapper!($name, $output, );
    };

    ($name:ident, $output:ident, $($vis:tt)*) => {
        use std::any::Any;
        create_wrapper!(
            $($vis)* struct $name<R> {
                data: R,
            }
        );

        create_wrapper!(
            impl $name<()> {
                $($vis)* fn new() -> Self {
                    $name {
                        data: ()
                    }
                }
            }
        );

        create_wrapper!(
            impl<R: RecursiveVariadic> $name<R> {
                $($vis)* fn get<N>(&self) -> Option<&$output<N>>
                where $output<N>: Any {
                    self.data.get()
                }

                $($vis)* fn get_mut<N>(&mut self) -> Option<&mut $output<N>>
                where $output<N>: Any {
                    self.data.get_mut()
                }

                $($vis)* fn and<N: Any>(self, val: $output<N>) -> $name<Entry<$output<N>, R>>
                where $output<N>: Any {
                    $name {
                        data: self.data.and(val)
                    }
                }

                $($vis)* fn and_default<N: Any>(self) -> $name<Entry<$output<N>, R>>
                where $output<N>: Any + Default {
                    $name {
                        data: self.data.and(Default::default())
                    }
                }
            }
        );
    };

    ($i:item) => {$i};
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let thing = ().and(23).and(0usize).and("Hello!");
        assert!(thing.get::<i32>().is_some());
        assert!(thing.get::<usize>().is_some());
        assert!(thing.get::<&'static str>().is_some());
        assert!(thing.get::<bool>().is_none());
    }

    create_wrapper!(VecHolder, N => Vec<N>);

    #[test]
    fn vec_variadic() {
        // this struct will hold a vector of usize, bool, and u32.
        let mut my_vecs = VecHolder::new()
            .and_default::<usize>()
            .and_default::<bool>()
            .and::<u32>(Vec::new()); // just to prove they're the same.
        my_vecs.get_mut::<usize>().unwrap().push(2);
        my_vecs.get_mut::<bool>().unwrap().push(false);
        my_vecs.get_mut::<u32>().unwrap().push(0);

        assert!(my_vecs.get::<String>().is_none());
    }
}<commit_msg>Improved docs<commit_after>//! This is an implementation of variadic templates using recursive generics.
//! It functions something like a TypeMap, but the optimizer should make getting
//! and adding values much faster.

use std::any::{Any, TypeId};
use std::mem;

/// The building block trait for recursive variadics.
pub trait RecursiveVariadic {
    /// Try to get the field of type N.
    fn get<N: Any>(&self) -> Option<&N>;
    /// Try to get the field of type N mutably.
    fn get_mut<N: Any>(&mut self) -> Option<&mut N>;
    /// Add a field of type N to this.
    fn and<N: Any>(self, val: N) -> Entry<N, Self> where Self: Sized {
        Entry {
            data: val,
            parent: self,
        }
    }
}

/// The base case for recursive variadics: no fields.
pub type Empty = ();
impl RecursiveVariadic for Empty {
    fn get<N: Any>(&self) -> Option<&N> { None }
    fn get_mut<N: Any>(&mut self) -> Option<&mut N> { None }
}

/// Wraps some field data and a parent, which is either another Entry or Empty
pub struct Entry<T, R> {
    data: T,
    parent: R,
}

impl<T: Any, R: RecursiveVariadic> RecursiveVariadic for Entry<T, R> {
    fn get<N: Any>(&self) -> Option<&N> {
        if TypeId::of::<N>() == TypeId::of::<T>() {
            Some(unsafe { mem::transmute(&self.data) })
        } else {
            self.parent.get()
        }
    }
    fn get_mut<N: Any>(&mut self) -> Option<&mut N> {
        if TypeId::of::<N>() == TypeId::of::<T>() {
            Some(unsafe { mem::transmute(&mut self.data) })
        } else {
            self.parent.get_mut()
        }
    }
}

/// This macro is a standin for the way this would be implemented
/// with Higher Kinded Types. It creates a wrapper struct that for every N
/// puts an entry in the RecursiveVariadic it wraps for a Output<N>.
///
/// # Examples
///
/// This example creates a wrapper that gets a thing.
///
/// ```rust
///     #[macro_use]
///     extern crate recursive_variadic;
///
///     use recursive_variadic::*;
///
///     create_wrapper!(VecHolder, N => Vec<N>);
///
///     fn vec_variadic() {
///         // this struct maps types to a vector of that type.
///         let mut my_vecs = VecHolder::new()
///             .and_default::<usize>()
///             .and_default::<bool>()
///             .and::<u32>(Vec::new()); // if you want to provide a value
///         my_vecs.get_mut::<usize>().unwrap().push(2);
///         my_vecs.get_mut::<bool>().unwrap().push(false);
///         my_vecs.get_mut::<u32>().unwrap().push(0);
///
///         assert!(my_vecs.get::<String>().is_none());
///     }
///
///     fn main() { vec_variadic() }
/// ```
///
/// Using an creating a wrapper around an Id type is redundant,
/// but better shows what this macro does.
///
/// ```rust
///     #[macro_use]
///     extern crate recursive_variadic;
///
///     use recursive_variadic::*;
///
///     type Id<N> = N;
///
///     fn id_variadic() {
///         create_wrapper!(IdVariadic, N => Id<N>, PRIV);
///         let mut my_things = IdVariadic::new()
///             .and_default::<usize>()
///             .and(23i32);
///
///         *my_things.get_mut::<i32>().unwrap() += 1;
///         assert!(my_things.get::<usize>().is_some());
///     }
///
///     fn main() { id_variadic() }
/// ```

#[macro_export]
macro_rules! create_wrapper {
    ($name:ident, N => $output:ident<N>) => {
        create_wrapper!($name, $output, pub);
    };

    ($name:ident, N => $output:ident<N>, PRIV) => {
        create_wrapper!($name, $output, );
    };

    ($name:ident, $output:ident, $($vis:tt)*) => {
        use std::any::Any;
        create_wrapper!(
            $($vis)* struct $name<R> {
                data: R,
            }
        );

        create_wrapper!(
            impl $name<()> {
                $($vis)* fn new() -> Self {
                    $name {
                        data: ()
                    }
                }
            }
        );

        create_wrapper!(
            impl<R: RecursiveVariadic> $name<R> {
                $($vis)* fn get<N>(&self) -> Option<&$output<N>>
                where $output<N>: Any {
                    self.data.get()
                }

                $($vis)* fn get_mut<N>(&mut self) -> Option<&mut $output<N>>
                where $output<N>: Any {
                    self.data.get_mut()
                }

                $($vis)* fn and<N: Any>(self, val: $output<N>) -> $name<Entry<$output<N>, R>>
                where $output<N>: Any {
                    $name {
                        data: self.data.and(val)
                    }
                }

                $($vis)* fn and_default<N: Any>(self) -> $name<Entry<$output<N>, R>>
                where $output<N>: Any + Default {
                    $name {
                        data: self.data.and(Default::default())
                    }
                }
            }
        );
    };

    ($i:item) => {$i};
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let thing = ().and(23).and(0usize).and("Hello!");
        assert!(thing.get::<i32>().is_some());
        assert!(thing.get::<usize>().is_some());
        assert!(thing.get::<&'static str>().is_some());
        assert!(thing.get::<bool>().is_none());
    }

    create_wrapper!(VecHolder, N => Vec<N>);

    #[test]
    fn vec_variadic() {
        // this struct will hold a vector of usize, bool, and u32.
        let mut my_vecs = VecHolder::new()
            .and_default::<usize>()
            .and_default::<bool>()
            .and::<u32>(Vec::new()); // just to prove they're the same.
        my_vecs.get_mut::<usize>().unwrap().push(2);
        my_vecs.get_mut::<bool>().unwrap().push(false);
        my_vecs.get_mut::<u32>().unwrap().push(0);

        assert!(my_vecs.get::<String>().is_none());
    }
}<|endoftext|>