<commit_before>extern crate mio;
extern crate bytes;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
extern crate spki_sexp;

extern crate etcd;

use mio::tcp::*;
use mio::EventLoop;
use mio::util::Slab;
use std::collections::{VecDeque,BTreeMap};
use std::net::SocketAddr;
use std::cmp;

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

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

pub use data::*;
pub use config::*;

const REPLICATION_CREDIT : u64 = 1024;

pub type PeerMsg = (u64, u64, Operation);

#[derive(Debug)]
enum ChainReplMsg {
    Operation { source: mio::Token, epoch: Option<u64>, seqno: Option<u64>, op: Operation },
    DownstreamResponse(OpResp),
    NewClientConn(Role, TcpStream),
}

#[derive(Debug)]
pub struct ChainRepl {
    connections: Slab<EventHandler>,
    downstream_slot: Option<mio::Token>,
    // "Model" fields
    last_sent_downstream: Option<u64>,
    last_acked_downstream: Option<u64>,
    pending_operations: BTreeMap<u64, mio::Token>,
    log: BTreeMap<u64, Operation>,
    state: String,
    new_view: Option<ConfigurationView<NodeViewConfig>>,
    node_config: NodeViewConfig,
    current_epoch: u64,
}

impl ChainRepl {
    pub fn new() -> ChainRepl {
        ChainRepl {
            connections: Slab::new(1024),
            downstream_slot: None,
            last_sent_downstream: None,
            last_acked_downstream: None,
            log: BTreeMap::new(),
            pending_operations: BTreeMap::new(),
            state: String::new(),
            new_view: None,
            node_config: Default::default(),
            current_epoch: Default::default(),
        }
    }

    pub fn listen(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>, addr: SocketAddr, role: Role) {
        info!("Listen on {:?} for {:?}", addr, role);
        let l = Listener::new(addr, role.clone());
        match role {
            Role::Upstream => self.node_config.peer_addr = Some(format!("{}", l.listen_addr())),
            Role::Client => self.node_config.client_addr = Some(format!("{}", l.listen_addr())),
        }
        let token = self.connections.insert(EventHandler::Listener(l)).expect("insert listener");
        &self.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 seqno(&self) -> u64 {
        self.log.len() as u64
    }

    fn next_seqno(&self) -> u64 {
        self.seqno()
    }

    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 } => {
                let seqno = seqno.unwrap_or_else(|| self.next_seqno());
                // assert!(seqno == 0 || self.log.get(&(seqno-1)).is_some());

                let epoch = epoch.unwrap_or_else(|| self.current_epoch);

               if epoch != self.current_epoch {
                    warn!("Operation epoch ({}) differers from our last observed configuration: ({})",
                        epoch, self.current_epoch);
                    let resp = OpResp::Err(epoch, seqno, format!("BadEpoch: {}; last seen config: {}", epoch, self.current_epoch));
                    self.connections[source].response(resp);
                    return;
                }

                if !(seqno == 0 || self.log.get(&(seqno-1)).is_some()) {
                    warn!("Hole in history: saw {}/{}; have: {:?}", epoch, seqno, self.log.keys().collect::<Vec<_>>());
                    let resp = OpResp::Err(epoch, seqno, format!("Bad sequence number; previous: {:?}, saw: {:?}",
                        self.log.keys().rev().next(), seqno));
                    self.connections[source].response(resp);
                    return;
                }

                let prev = self.log.insert(seqno, op.clone());
                debug!("Log entry {:?}: {:?}", seqno, op);
                if let Some(prev) = prev {
                    panic!("Unexpectedly existing log entry for item {}: {:?}", seqno, prev);
                }

                if let Some(_) = self.downstream_slot {
                    self.pending_operations.insert(seqno, source);
                    // Replication mechanism should handle the push to downstream.
                } else {
                    info!("Terminus! {:?}/{:?}", seqno, op);
                    let resp = match op {
                        Operation::Set(s) => {
                            self.state = s;
                            OpResp::Ok(epoch, seqno, None)
                        },
                        Operation::Get => OpResp::Ok(epoch, seqno, Some(self.state.clone()))
                    };
                    self.connections[source].response(resp)
                }
            },

            ChainReplMsg::DownstreamResponse(reply) => {
                debug!("Downstream response: {:?}", reply);
                match reply {
                    OpResp::Ok(epoch, seqno, _) | OpResp::Err(epoch, seqno, _) => {
                        if let Some(token) = self.pending_operations.remove(&seqno) {
                            info!("Found in-flight op {:?} for client token {:?}", seqno, token);
                            if let Some(ref mut c)  = self.connections.get_mut(token) {
                                c.response(reply)
                            }
                            self.last_acked_downstream = Some(seqno)
                        } else {
                            warn!("Unexpected response for seqno: {:?}", seqno);
                        }
                    },
                    OpResp::HelloIWant(last_sent_downstream) => {
                        info!("Downstream has {:?}", last_sent_downstream);
                        assert!(last_sent_downstream <= self.seqno());
                        self.last_sent_downstream = Some(last_sent_downstream);
                    },
                };
            },

            ChainReplMsg::NewClientConn(role, socket) => {
                let peer = socket.peer_addr().expect("peer address");
                let seqno = self.seqno();
                assert!(self.log.get(&seqno).is_none());
                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(&mut self, event_loop: &mut mio::EventLoop<Self>) -> bool {
        debug!("pre  Repl: Ours: {:?}; downstream sent: {:?}; acked: {:?}",
            self.seqno(), self.last_sent_downstream, self.last_acked_downstream);
        let mut changed = false;
        if let Some(send_next) = self.last_sent_downstream {
            if send_next < self.seqno() {
                let max_to_push_now = cmp::min(self.last_acked_downstream.unwrap_or(0) + REPLICATION_CREDIT, self.seqno());
                debug!("Window push {:?} - {:?}; waiting: {:?}", send_next, max_to_push_now, self.seqno() - max_to_push_now);
                let epoch = self.current_epoch;
                for i in send_next..max_to_push_now {
                    debug!("Log item: {:?}: {:?}", i, self.log.get(&i));
                    let op = self.log[&i].clone();
                    debug!("Queueing epoch:{:?}; seq:{:?}/{:?}; ds/seqno: {:?}", epoch, i, op, self.last_sent_downstream);
                    self.downstream().expect("Downstream").send_to_downstream(epoch, i, op);
                    self.last_sent_downstream = Some(i+1);
                    changed = true
                }
            }
            debug!("post Repl: Ours: {:?}; downstream sent: {:?}; acked: {:?}",
                self.seqno(), self.last_sent_downstream, self.last_acked_downstream);
        }

        // Cases:
        // Head(nextNode)
        // Middle(nextNode)
        // Tail
        if let Some(view) = self.new_view.take() {
            info!("Reconfigure according to: {:?}", view);
            if !view.in_configuration() {
                warn!("I am not in this configuration; shutting down: {:?}", view);
                event_loop.shutdown();
            }

            let listen_for_clients = view.should_listen_for_clients();
            info!("Listen for clients: {:?}", listen_for_clients);
            for p in self.listeners(Role::Client) {
                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) {
                p.set_active(listen_for_upstreamp);
            }
            if let Some(ds) = view.should_connect_downstream() {
                info!("Push to downstream on {:?}", ds);
                if let Some(peer_addr) = ds.peer_addr {
                    self.set_downstream(event_loop, Some(peer_addr.parse().expect("peer address")));
                } else {
                    panic!("Cannot reconnect to downstream with no peer listener: {:?}", ds);
                }
            } else {
                info!("Tail node!");
                self.set_downstream(event_loop, None);
            }

            self.current_epoch = view.epoch;

            changed = true;
        }

        changed
    }

    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 { debug!("Changed: {:?}", conn); };
                changed |= changedp;
            }

            let changedp = self.process_rules(event_loop);
            if changedp { debug!("Changed: {:?}", "Model"); }
            changed |= changedp;

            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].is_closed() && self.pending_operations.values().all(|tok| tok != &token) {
            debug!("Close candidate: {:?}: pending: {:?}",
                token, self.pending_operations.values().filter(|tok| **tok == token).count());
            let it = self.connections.remove(token);
            debug!("Removing; {:?}; {:?}", token, it);
            if Some(token) == self.downstream_slot {
                self.downstream_slot = None;
                self.last_sent_downstream = None
            }
        }
    }

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

    pub fn get_notifier(&self, event_loop: &mut mio::EventLoop<Self>) -> Notifier {
        Notifier(event_loop.channel())
    }

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

pub struct Notifier(mio::Sender<ConfigurationView<NodeViewConfig>>);

impl Notifier {
    pub fn notify(&self, view: ConfigurationView<NodeViewConfig>) {
        use mio::NotifyError::*;
        let mut item = view;
        let mut backoff_ms = 1;
        loop {
            item = match self.0.send(item) {
                Ok(_) => return,
                Err(Full(it)) => it,
                Err(e) => panic!("{:?}", e),
            };
            info!("Backoff: {}ms", backoff_ms);
            std::thread::sleep_ms(backoff_ms);
            backoff_ms *= 2;
        }
    }
}

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 = ConfigurationView<NodeViewConfig>;
    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: ConfigurationView<NodeViewConfig>) {
        debug!("Notified: {:?}", msg);
        self.handle_view_changed(msg);
        self.converge_state(event_loop);
    }
}
<commit_msg>Refactor a little.<commit_after>extern crate mio;
extern crate bytes;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
extern crate spki_sexp;

extern crate etcd;

use mio::tcp::*;
use mio::EventLoop;
use mio::util::Slab;
use std::collections::{VecDeque,BTreeMap};
use std::net::SocketAddr;
use std::cmp;

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

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

pub use data::*;
pub use config::*;

const REPLICATION_CREDIT : u64 = 1024;

pub type PeerMsg = (u64, u64, Operation);

#[derive(Debug)]
enum ChainReplMsg {
    Operation { source: mio::Token, epoch: Option<u64>, seqno: Option<u64>, op: Operation },
    DownstreamResponse(OpResp),
    NewClientConn(Role, TcpStream),
}

#[derive(Debug)]
pub struct ChainRepl {
    connections: Slab<EventHandler>,
    downstream_slot: Option<mio::Token>,
    // "Model" fields
    last_sent_downstream: Option<u64>,
    last_acked_downstream: Option<u64>,
    pending_operations: BTreeMap<u64, mio::Token>,
    log: BTreeMap<u64, Operation>,
    state: String,
    new_view: Option<ConfigurationView<NodeViewConfig>>,
    node_config: NodeViewConfig,
    current_epoch: u64,
}

impl ChainRepl {
    pub fn new() -> ChainRepl {
        ChainRepl {
            connections: Slab::new(1024),
            downstream_slot: None,
            last_sent_downstream: None,
            last_acked_downstream: None,
            log: BTreeMap::new(),
            pending_operations: BTreeMap::new(),
            state: String::new(),
            new_view: None,
            node_config: Default::default(),
            current_epoch: Default::default(),
        }
    }

    pub fn listen(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>, addr: SocketAddr, role: Role) {
        info!("Listen on {:?} for {:?}", addr, role);
        let l = Listener::new(addr, role.clone());
        match role {
            Role::Upstream => self.node_config.peer_addr = Some(format!("{}", l.listen_addr())),
            Role::Client => self.node_config.client_addr = Some(format!("{}", l.listen_addr())),
        }
        let token = self.connections.insert(EventHandler::Listener(l)).expect("insert listener");
        &self.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 seqno(&self) -> u64 {
        self.log.len() as u64
    }

    fn next_seqno(&self) -> u64 {
        self.seqno()
    }

    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 } => {
                self.process_operation(source, seqno, epoch, op)
            },

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

            ChainReplMsg::NewClientConn(role, socket) => {
                self.process_new_client_conn(event_loop, role, socket)
            }
        }
    }

    fn process_operation(&mut self, source: mio::Token, seqno: Option<u64>, epoch: Option<u64>, op: Operation){
        let seqno = seqno.unwrap_or_else(|| self.next_seqno());
        // assert!(seqno == 0 || self.log.get(&(seqno-1)).is_some());

        let epoch = epoch.unwrap_or_else(|| self.current_epoch);

       if epoch != self.current_epoch {
            warn!("Operation epoch ({}) differers from our last observed configuration: ({})",
                epoch, self.current_epoch);
            let resp = OpResp::Err(epoch, seqno, format!("BadEpoch: {}; last seen config: {}", epoch, self.current_epoch));
            self.connections[source].response(resp);
            return;
        }

        if !(seqno == 0 || self.log.get(&(seqno-1)).is_some()) {
            warn!("Hole in history: saw {}/{}; have: {:?}", epoch, seqno, self.log.keys().collect::<Vec<_>>());
            let resp = OpResp::Err(epoch, seqno, format!("Bad sequence number; previous: {:?}, saw: {:?}",
                self.log.keys().rev().next(), seqno));
            self.connections[source].response(resp);
            return;
        }

        let prev = self.log.insert(seqno, op.clone());
        debug!("Log entry {:?}: {:?}", seqno, op);
        if let Some(prev) = prev {
            panic!("Unexpectedly existing log entry for item {}: {:?}", seqno, prev);
        }

        if let Some(_) = self.downstream_slot {
            self.pending_operations.insert(seqno, source);
            // Replication mechanism should handle the push to downstream.
        } else {
            info!("Terminus! {:?}/{:?}", seqno, op);
            let resp = match op {
                Operation::Set(s) => {
                    self.state = s;
                    OpResp::Ok(epoch, seqno, None)
                },
                Operation::Get => OpResp::Ok(epoch, seqno, Some(self.state.clone()))
            };
            self.connections[source].response(resp)
        }

    }

    fn process_downstream_response(&mut self, reply: OpResp) {
        debug!("Downstream response: {:?}", reply);
        match reply {
            OpResp::Ok(epoch, seqno, _) | OpResp::Err(epoch, seqno, _) => {
                if let Some(token) = self.pending_operations.remove(&seqno) {
                    info!("Found in-flight op {:?} for client token {:?}", seqno, token);
                    if let Some(ref mut c)  = self.connections.get_mut(token) {
                        c.response(reply)
                    }
                    self.last_acked_downstream = Some(seqno)
                } else {
                    warn!("Unexpected response for seqno: {:?}", seqno);
                }
            },
            OpResp::HelloIWant(last_sent_downstream) => {
                info!("Downstream has {:?}", last_sent_downstream);
                assert!(last_sent_downstream <= self.seqno());
                self.last_sent_downstream = Some(last_sent_downstream);
            },
        };
    }
    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.seqno();
        assert!(self.log.get(&seqno).is_none());
        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(&mut self, event_loop: &mut mio::EventLoop<Self>) -> bool {
        debug!("pre  Repl: Ours: {:?}; downstream sent: {:?}; acked: {:?}",
            self.seqno(), self.last_sent_downstream, self.last_acked_downstream);
        let mut changed = false;
        if let Some(send_next) = self.last_sent_downstream {
            if send_next < self.seqno() {
                let max_to_push_now = cmp::min(self.last_acked_downstream.unwrap_or(0) + REPLICATION_CREDIT, self.seqno());
                debug!("Window push {:?} - {:?}; waiting: {:?}", send_next, max_to_push_now, self.seqno() - max_to_push_now);
                let epoch = self.current_epoch;
                for i in send_next..max_to_push_now {
                    debug!("Log item: {:?}: {:?}", i, self.log.get(&i));
                    let op = self.log[&i].clone();
                    debug!("Queueing epoch:{:?}; seq:{:?}/{:?}; ds/seqno: {:?}", epoch, i, op, self.last_sent_downstream);
                    self.downstream().expect("Downstream").send_to_downstream(epoch, i, op);
                    self.last_sent_downstream = Some(i+1);
                    changed = true
                }
            }
            debug!("post Repl: Ours: {:?}; downstream sent: {:?}; acked: {:?}",
                self.seqno(), self.last_sent_downstream, self.last_acked_downstream);
        }

        // Cases:
        // Head(nextNode)
        // Middle(nextNode)
        // Tail
        if let Some(view) = self.new_view.take() {
            info!("Reconfigure according to: {:?}", view);
            if !view.in_configuration() {
                warn!("I am not in this configuration; shutting down: {:?}", view);
                event_loop.shutdown();
            }

            let listen_for_clients = view.should_listen_for_clients();
            info!("Listen for clients: {:?}", listen_for_clients);
            for p in self.listeners(Role::Client) {
                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) {
                p.set_active(listen_for_upstreamp);
            }
            if let Some(ds) = view.should_connect_downstream() {
                info!("Push to downstream on {:?}", ds);
                if let Some(peer_addr) = ds.peer_addr {
                    self.set_downstream(event_loop, Some(peer_addr.parse().expect("peer address")));
                } else {
                    panic!("Cannot reconnect to downstream with no peer listener: {:?}", ds);
                }
            } else {
                info!("Tail node!");
                self.set_downstream(event_loop, None);
            }

            self.current_epoch = view.epoch;

            changed = true;
        }

        changed
    }

    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 { debug!("Changed: {:?}", conn); };
                changed |= changedp;
            }

            let changedp = self.process_rules(event_loop);
            if changedp { debug!("Changed: {:?}", "Model"); }
            changed |= changedp;

            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].is_closed() && self.pending_operations.values().all(|tok| tok != &token) {
            debug!("Close candidate: {:?}: pending: {:?}",
                token, self.pending_operations.values().filter(|tok| **tok == token).count());
            let it = self.connections.remove(token);
            debug!("Removing; {:?}; {:?}", token, it);
            if Some(token) == self.downstream_slot {
                self.downstream_slot = None;
                self.last_sent_downstream = None
            }
        }
    }

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

    pub fn get_notifier(&self, event_loop: &mut mio::EventLoop<Self>) -> Notifier {
        Notifier(event_loop.channel())
    }

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

pub struct Notifier(mio::Sender<ConfigurationView<NodeViewConfig>>);

impl Notifier {
    pub fn notify(&self, view: ConfigurationView<NodeViewConfig>) {
        use mio::NotifyError::*;
        let mut item = view;
        let mut backoff_ms = 1;
        loop {
            item = match self.0.send(item) {
                Ok(_) => return,
                Err(Full(it)) => it,
                Err(e) => panic!("{:?}", e),
            };
            info!("Backoff: {}ms", backoff_ms);
            std::thread::sleep_ms(backoff_ms);
            backoff_ms *= 2;
        }
    }
}

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 = ConfigurationView<NodeViewConfig>;
    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: ConfigurationView<NodeViewConfig>) {
        debug!("Notified: {:?}", msg);
        self.handle_view_changed(msg);
        self.converge_state(event_loop);
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	pub fn clear(&mut self) {
		self.cont.clear()
	}

	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) {
		self.cont.push((kv1, kv2));
	}

	pub fn iter<'a>(&'a self) -> slice::Iter<'a, (Kv1, Kv2)> {
		self.cont.iter()
	}

	pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	//TODO: maybe implement keys() and values() as first_row() and second_row()?

	pub fn len(&self) -> usize {
		self.cont.len()
	}

	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	pub fn get<'q, Q>(&self, key: &'q Q) -> Option<&Kv2>
		where Kv1  : Borrow<Q>,
		      &'q Q: PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| key == kvs.0).map(|ref kvs| &kvs.1)
	}

	pub fn contains_key<'q, Q>(&self, key: &'q Q) -> bool
		where Kv1  : Borrow<Q>,
		      &'q Q: PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| key == kvs.0)
	}

	//TODO: implement get_mut
	/*pub fn get_mut<'q, Q>(&mut self, key: &'q Q) -> Option<&mut Kv2>
		where Kv1  : Borrow<Q>,
		      &'q Q: PartialEq<Kv1>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.0).map(|&mut kvs| &mut kvs.1)
	}*/

	pub fn remove<'q, Q>(&mut self, key: &'q Q) -> Option<Kv1>
		where Kv2  : Borrow<Q>,
		      &'q Q: PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| key == kvs.1).map(|idx| self.cont.swap_remove(idx).0)
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	pub fn get<'q, Q>(&self, key: &'q Q) -> Option<&Kv1>
		where Kv2  : Borrow<Q>,
		      &'q Q: PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| key == kvs.1).map(|ref kvs| &kvs.0)
	}

	pub fn contains_key<'q, Q>(&self, key: &'q Q) -> bool
		where Kv2  : Borrow<Q>,
		      &'q Q: PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| key == kvs.1)
	}

	//TODO: implement get_mut
	/*pub fn get_mut<'q, Q>(&mut self, key: &'q Q) -> Option<&mut Kv1>
		where Kv2  : Borrow<Q>,
		      &'q Q: PartialEq<Kv2>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.1).map(|&mut kvs| &mut kvs.0)
	}*/

	pub fn remove<'q, Q>(&mut self, key: &'q Q) -> Option<Kv2>
		where Kv1  : Borrow<Q>,
		      &'q Q: PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| key == kvs.0).map(|idx| self.cont.swap_remove(idx).1)
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

	fn into_iter(self) -> Self::IntoIter {
		return self.cont.into_iter()
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}
<commit_msg>Don't do impl-magic, instead provide different functions for looking from back and front. Add function documentation<commit_after>use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	/// Clears the map, removing all entries.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.clear();
	/// assert!(a.is_empty());
	/// ```
	pub fn clear(&mut self) {
		self.cont.clear()
	}

	/// Inserts a K/V-K/V pair into the map.
	///
	/// If the map did not have this K/V-K/V pair present, `None` is returned.
	///
	/// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
		let retval =
			if self.contains_first_key(&kv1) {
				self.remove_by_first(&kv1)
			} else if self.contains_second_key(&kv2) {
				self.remove_by_second(&kv2)
			} else {
				None
			};

		self.cont.push((kv1, kv2));

		retval
	}

	/// Gets an iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// map.insert(2, "b");
	/// map.insert(3, "c");
	///
	/// for kv in map.iter() {
	/// 	println!("{}: {}", kv.0, kv.1);
	/// }
	///
	/// let first = map.iter().next().unwrap();
	/// assert_eq!(*first, (1, "a"));
	/// ```
	pub fn iter<'a>(&'a self) -> slice::Iter<'a, (Kv1, Kv2)> {
		self.cont.iter()
	}

	/// Gets a mutable iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert("a", 1);
	/// map.insert("b", 2);
	/// map.insert("c", 3);
	///
	/// // add 10 to the value if the key isn't "a"
	/// for kv in map.iter_mut() {
	/// 	if &kv.0 != &"a" {
	/// 		kv.1 += 10;
	/// 	}
	/// }
	/// ```
	pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	//TODO: maybe implement keys() and values() as first_row() and second_row()?

	/// Returns the number of elements in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert_eq!(a.len(), 0);
	/// a.insert(1, "a");
	/// assert_eq!(a.len(), 1);
	/// ```
	pub fn len(&self) -> usize {
		self.cont.len()
	}

	/// Returns true if the map contains no elements.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert!(a.is_empty());
	/// a.insert(1, "a");
	/// assert!(!a.is_empty());
	/// ```
	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_first(&1), Some(&"a"));
	/// assert_eq!(map.get_by_first(&2), None);
	/// ```
	pub fn get_by_first<Q>(&self, key: &Q) -> Option<&Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_second(&"a"), Some(&1));
	/// assert_eq!(map.get_by_second(&"b"), None);
	/// ```
	pub fn get_by_second<Q>(&self, key: &Q) -> Option<&Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
	}

	/// Check if the map contains the first K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_first_key(&1), true);
	/// assert_eq!(map.contains_first_key(&2), false);
	/// ```
	pub fn contains_first_key<Q>(&self, key: &Q) -> bool
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.0)
	}

	/// Check if the map contains the second K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map: BidirMap<i32, &'static str> = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_second_key(&"a"), true);
	/// assert_eq!(map.contains_second_key(&"b"), false);
	/// ```
	pub fn contains_second_key<Q>(&self, key: &Q) -> bool
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.1)
	}

	//TODO: implement get_mut
	/*pub fn get_mut_by_first<Q>(&mut self, key: &Q) -> Option<&mut Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.0).map(|&mut kvs| &mut kvs.1)
	}
	pub fn get_mut_by_second<Q>(&mut self, key: &Q) -> Option<&mut Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter_mut().find(|&mut kvs| key == kvs.1).map(|&mut kvs| &mut kvs.0)
	}*/

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
	/// assert_eq!(map.remove_by_first(&1), None);
	/// ```
	pub fn remove_by_first<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
	/// assert_eq!(map.remove_by_second(&"b"), None);
	/// ```
	pub fn remove_by_second<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

	fn into_iter(self) -> Self::IntoIter {
		return self.cont.into_iter()
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}
<|endoftext|>


<commit_before>
pub fn puzzle(input: &str) -> usize {
    0
}

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

}
<commit_msg>Make some failing tests<commit_after>
pub fn puzzle(input: &str) -> usize {
    decompressed_length(input)
}

pub fn decompressed_length(input: &str) -> usize {
    0
}

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

    #[test]
    fn no_change() {
        assert_eq!(decompressed_length("ADVENT"), 6);
    }

    #[test]
    fn one_char() {
        assert_eq!(decompressed_length("A(1x5)BC"), 7);
    }

    #[test]
    fn three_chars() {
        assert_eq!(decompressed_length("(3x3)XYZ"), 9);
    }

    #[test]
    fn two_chars_twice() {
        assert_eq!(decompressed_length("A(2x2)BCD(2x2)EFG"), 11);
    }
    #[test]
    fn no_double_processing() {
        assert_eq!(decompressed_length("(6x1)(1x3)A"), 6);
    }
    #[test]
    fn another_no_double_processing() {
        assert_eq!(decompressed_length("X(8x2)(3x3)ABCY"), 18);
    }
}
<|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.

//! Library for retrieving and interacting with the [crates.io index].
//!
//! [crates.io index]: https://github.com/rust-lang/crates.io-index
//!
//! ## Examples
//!
//! ```rust
//! extern crate crates_index;
//!
//! let index = crates_index::Index::new("_index");
//! if !index.exists() {
//!    index.retrieve().expect("Could not fetch crates.io index");
//! }
//! for crate_ in index.crates() {
//!    let latest_version = crate_.latest_version();
//!    println!("crate name: {}", latest_version.name());
//!    println!("crate version: {}", latest_version.version());
//! }
//! ```

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
use std::io::{BufRead, BufReader};
use std::iter;
use std::path::{Path, PathBuf};

#[macro_use]
extern crate error_chain;
extern crate git2;
extern crate glob;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;
extern crate home;

error_chain! {
    foreign_links {
        Git(git2::Error);
    }
}

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

/// A single version of a crate published to the index
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Version {
    name: String,
    vers: String,
    deps: Vec<Dependency>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

impl Version {
    /// Name of the crate
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Name of this version
    pub fn version(&self) -> &str {
        &self.vers
    }

    /// Dependencies for this version
    pub fn dependencies(&self) -> &[Dependency] {
        &self.deps
    }

    /// Checksum of the package for this version
    pub fn checksum(&self) -> &str {
        &self.cksum
    }

    pub fn features(&self) -> &HashMap<String, Vec<String>> {
        &self.features
    }

    /// Whether this version was [yanked](http://doc.crates.io/crates-io.html#cargo-yank) from the
    /// index
    pub fn is_yanked(&self) -> bool {
        self.yanked
    }
}

/// A single dependency of a specific crate version
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Dependency {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>,
    package: Option<String>,
}

impl Dependency {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn requirement(&self) -> &str {
        &self.req
    }

    pub fn features(&self) -> &[String] {
        &self.features
    }

    pub fn is_optional(&self) -> bool {
        self.optional
    }

    pub fn has_default_features(&self) -> bool {
        self.default_features
    }

    pub fn target(&self) -> Option<&str> {
        match self.target {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn kind(&self) -> Option<&str> {
        match self.kind {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn package(&self) -> Option<&str> {
        match self.package {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    /// Returns the name of the crate providing the dependency.
    /// This is equivalent to `name()` unless `self.package()`
    /// is not `None`, in which case it's equal to `self.package()`.
    ///
    /// Basically, you can define a dependency in your `Cargo.toml`
    /// like this:
    ///
    /// ```toml
    /// serde_lib = {version = "1", package = "serde"}
    /// ```
    ///
    /// ...which means that it uses the crate `serde` but imports
    /// it under the name `serde_lib`.
    pub fn crate_name(&self) -> &str {
        match self.package {
            Some(ref s) => s,
            None => self.name(),
        }
    }
}

/// Constructed from `Index::crates`
pub struct Crates(CrateIndexPaths);

impl Iterator for Crates {
    type Item = Crate;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|p| Crate::new(&p))
    }
}

/// Constructed from `Index::crate_index_paths`
pub struct CrateIndexPaths(iter::Chain<glob::Paths, glob::Paths>);

impl CrateIndexPaths {
    fn new<P: AsRef<Path>>(path: P) -> CrateIndexPaths {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;
        let path = path.as_ref();

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

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

        CrateIndexPaths(index_paths1.chain(index_paths2))
    }
}

impl Iterator for CrateIndexPaths {
    type Item = PathBuf;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|glob_result| glob_result.unwrap())
    }
}

/// Wrapper around managing the crates.io-index git repository
#[derive(Debug, Clone, PartialEq)]
pub struct Index {
    path: PathBuf,
}

impl Index {
    /// Construct a new Index supplying a path where the index lives or should live
    pub fn new<P: Into<PathBuf>>(path: P) -> Index {
        Index { path: path.into() }
    }

    /// Use Cargo's own index in `CARGO_HOME` (`~/.cargo/registry/index`)
    pub fn new_cargo_default() -> Index {
        let cargo_home = home::cargo_home().unwrap_or_default();
        Self::new(cargo_home.join("registry").join("index").join("github.com-1ecc6299db9ec823"))
    }

    /// Determines if a crates.io repository exists at `self.path`
    pub fn exists(&self) -> bool {
        git2::Repository::discover(&self.path)
            .map(|repository| {
                repository
                    .find_remote("origin").ok()
                    // Cargo creates a checkout without an origin set,
                    // so default to true in case of missing origin
                    .map_or(true, |remote| remote.url().map_or(true, |url| url == INDEX_GIT_URL))
            })
            .unwrap_or(false)
    }

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

    /// Assumes the index already exists at `self.path`, and updates it
    pub fn update(&self) -> Result<()> {
        debug_assert!(self.exists());
        let repo = git2::Repository::discover(&self.path)?;
        let mut origin_remote = repo.find_remote("origin")
            .or_else(|_| repo.remote_anonymous(INDEX_GIT_URL))?;
        origin_remote.fetch(&["master"], None, None)?;
        let oid = repo.refname_to_id("FETCH_HEAD")?;
        let object = repo.find_object(oid, None).unwrap();
        repo.reset(&object, git2::ResetType::Hard, None)?;
        Ok(())
    }

    /// Downloads the index to the path specified from the constructor
    pub fn retrieve_or_update(&self) -> Result<()> {
        if self.exists() {
            self.update()
        } else {
            self.retrieve()
        }
    }

    /// Retrieve a single crate by name (case insensitive) from the index
    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.crate_index_paths()
            .find(|path| {
                      path.file_name()
                          .and_then(OsStr::to_str)
                          .map(|file_name| file_name.eq_ignore_ascii_case(crate_name))
                          .unwrap_or(false)
                  })
            .map(|p| Crate::new(&p))
    }

    /// Retrieve an iterator over all the crates in the index
    pub fn crates(&self) -> Crates {
        Crates(self.crate_index_paths())
    }

    /// Returns all the crate index file paths in the index
    pub fn crate_index_paths(&self) -> CrateIndexPaths {
        CrateIndexPaths::new(self.path.clone()) // TODO: remove this clone
    }

    /// Get the index directory.
    pub fn path(&self) -> &Path {
        &self.path
    }
}

/// A single crate that contains many published versions
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Crate {
    versions: Vec<Version>,
}

impl Crate {
    pub fn new<P: AsRef<Path>>(index_path: P) -> Crate {
        let index_path = index_path.as_ref();
        let mut versions = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let version: Version = serde_json::from_str(&line.unwrap()).unwrap();
            versions.push(version);
        }
        Crate { versions: versions }
    }

    /// Published versions of this crate sorted chronologically by date published
    pub fn versions(&self) -> &[Version] {
        &self.versions
    }

    pub fn earliest_version(&self) -> &Version {
        &self.versions[0]
    }

    pub fn latest_version(&self) -> &Version {
        &self.versions[self.versions.len() - 1]
    }

    pub fn name(&self) -> &str {
        self.latest_version().name()
    }
}

#[cfg(test)]
mod test {
    use super::Index;
    extern crate tempdir;
    use self::tempdir::TempDir;

    #[test]
    fn test_dependencies() {
        let tmp_dir = TempDir::new("test1").unwrap();

        let index = Index::new(tmp_dir.path());
        index.retrieve_or_update().expect("could not fetch crates io index");
        // let crate_ = index.crates().nth(0).expect("could not find a crate in the index");
        let crate_ = index.crate_("sval").expect("Could not find the crate libnotify in the index");
        let _ = format!("supports debug {:?}", crate_);

        let version = crate_.versions().iter().find(|v| v.version() == "0.0.1")
            .expect("Version 0.0.1 of sval does not exist?");
        let dep_with_package_name = version.dependencies().iter().find(|d| d.name() == "serde_lib")
            .expect("sval does not have expected dependency?");
        assert_ne!(dep_with_package_name.name(), dep_with_package_name.package().unwrap());
        assert_eq!(dep_with_package_name.crate_name(), dep_with_package_name.package().unwrap());
    }

    #[test]
    fn test_retrieve_or_update() {
        let tmp_dir = TempDir::new("test2").unwrap();

        let index = Index::new(tmp_dir.path());
        index.retrieve_or_update().expect("could not fetch crates io index");
        assert!(index.exists());
        index.retrieve_or_update().expect("could not fetch crates io index");
        assert!(index.exists());
    }

    #[test]
    fn test_cargo_default_updates() {
        let index = Index::new_cargo_default();
        index.update().map_err(|e| format!("could not fetch cargo's index in {}: {}", index.path().display(), e)).unwrap();
    }

    #[test]
    fn test_exists() {
        let tmp_dir = TempDir::new("test3").unwrap();

        let index = Index::new(tmp_dir.path());
        assert!(!index.exists());
        index.retrieve().unwrap();
        assert!(index.exists());
    }
}
<commit_msg>Check that the index works<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.

//! Library for retrieving and interacting with the [crates.io index].
//!
//! [crates.io index]: https://github.com/rust-lang/crates.io-index
//!
//! ## Examples
//!
//! ```rust
//! extern crate crates_index;
//!
//! let index = crates_index::Index::new("_index");
//! if !index.exists() {
//!    index.retrieve().expect("Could not fetch crates.io index");
//! }
//! for crate_ in index.crates() {
//!    let latest_version = crate_.latest_version();
//!    println!("crate name: {}", latest_version.name());
//!    println!("crate version: {}", latest_version.version());
//! }
//! ```

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
use std::io::{BufRead, BufReader};
use std::iter;
use std::path::{Path, PathBuf};

#[macro_use]
extern crate error_chain;
extern crate git2;
extern crate glob;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde;
extern crate home;

error_chain! {
    foreign_links {
        Git(git2::Error);
    }
}

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

/// A single version of a crate published to the index
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Version {
    name: String,
    vers: String,
    deps: Vec<Dependency>,
    cksum: String,
    features: HashMap<String, Vec<String>>,
    yanked: bool,
}

impl Version {
    /// Name of the crate
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Name of this version
    pub fn version(&self) -> &str {
        &self.vers
    }

    /// Dependencies for this version
    pub fn dependencies(&self) -> &[Dependency] {
        &self.deps
    }

    /// Checksum of the package for this version
    pub fn checksum(&self) -> &str {
        &self.cksum
    }

    pub fn features(&self) -> &HashMap<String, Vec<String>> {
        &self.features
    }

    /// Whether this version was [yanked](http://doc.crates.io/crates-io.html#cargo-yank) from the
    /// index
    pub fn is_yanked(&self) -> bool {
        self.yanked
    }
}

/// A single dependency of a specific crate version
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Dependency {
    name: String,
    req: String,
    features: Vec<String>,
    optional: bool,
    default_features: bool,
    target: Option<String>,
    kind: Option<String>,
    package: Option<String>,
}

impl Dependency {
    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn requirement(&self) -> &str {
        &self.req
    }

    pub fn features(&self) -> &[String] {
        &self.features
    }

    pub fn is_optional(&self) -> bool {
        self.optional
    }

    pub fn has_default_features(&self) -> bool {
        self.default_features
    }

    pub fn target(&self) -> Option<&str> {
        match self.target {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn kind(&self) -> Option<&str> {
        match self.kind {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    pub fn package(&self) -> Option<&str> {
        match self.package {
            Some(ref s) => Some(s),
            None => None,
        }
    }

    /// Returns the name of the crate providing the dependency.
    /// This is equivalent to `name()` unless `self.package()`
    /// is not `None`, in which case it's equal to `self.package()`.
    ///
    /// Basically, you can define a dependency in your `Cargo.toml`
    /// like this:
    ///
    /// ```toml
    /// serde_lib = {version = "1", package = "serde"}
    /// ```
    ///
    /// ...which means that it uses the crate `serde` but imports
    /// it under the name `serde_lib`.
    pub fn crate_name(&self) -> &str {
        match self.package {
            Some(ref s) => s,
            None => self.name(),
        }
    }
}

/// Constructed from `Index::crates`
pub struct Crates(CrateIndexPaths);

impl Iterator for Crates {
    type Item = Crate;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|p| Crate::new(&p))
    }
}

/// Constructed from `Index::crate_index_paths`
pub struct CrateIndexPaths(iter::Chain<glob::Paths, glob::Paths>);

impl CrateIndexPaths {
    fn new<P: AsRef<Path>>(path: P) -> CrateIndexPaths {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;
        let path = path.as_ref();

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

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

        CrateIndexPaths(index_paths1.chain(index_paths2))
    }
}

impl Iterator for CrateIndexPaths {
    type Item = PathBuf;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|glob_result| glob_result.unwrap())
    }
}

/// Wrapper around managing the crates.io-index git repository
#[derive(Debug, Clone, PartialEq)]
pub struct Index {
    path: PathBuf,
}

impl Index {
    /// Construct a new Index supplying a path where the index lives or should live
    pub fn new<P: Into<PathBuf>>(path: P) -> Index {
        Index { path: path.into() }
    }

    /// Use Cargo's own index in `CARGO_HOME` (`~/.cargo/registry/index`)
    pub fn new_cargo_default() -> Index {
        let cargo_home = home::cargo_home().unwrap_or_default();
        Self::new(cargo_home.join("registry").join("index").join("github.com-1ecc6299db9ec823"))
    }

    /// Determines if a crates.io repository exists at `self.path`
    pub fn exists(&self) -> bool {
        git2::Repository::discover(&self.path)
            .map(|repository| {
                repository
                    .find_remote("origin").ok()
                    // Cargo creates a checkout without an origin set,
                    // so default to true in case of missing origin
                    .map_or(true, |remote| remote.url().map_or(true, |url| url == INDEX_GIT_URL))
            })
            .unwrap_or(false)
    }

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

    /// Assumes the index already exists at `self.path`, and updates it
    pub fn update(&self) -> Result<()> {
        debug_assert!(self.exists());
        let repo = git2::Repository::discover(&self.path)?;
        let mut origin_remote = repo.find_remote("origin")
            .or_else(|_| repo.remote_anonymous(INDEX_GIT_URL))?;
        origin_remote.fetch(&["master"], None, None)?;
        let oid = repo.refname_to_id("FETCH_HEAD")?;
        let object = repo.find_object(oid, None).unwrap();
        repo.reset(&object, git2::ResetType::Hard, None)?;
        Ok(())
    }

    /// Downloads the index to the path specified from the constructor
    pub fn retrieve_or_update(&self) -> Result<()> {
        if self.exists() {
            self.update()
        } else {
            self.retrieve()
        }
    }

    /// Retrieve a single crate by name (case insensitive) from the index
    pub fn crate_(&self, crate_name: &str) -> Option<Crate> {
        self.crate_index_paths()
            .find(|path| {
                      path.file_name()
                          .and_then(OsStr::to_str)
                          .map(|file_name| file_name.eq_ignore_ascii_case(crate_name))
                          .unwrap_or(false)
                  })
            .map(|p| Crate::new(&p))
    }

    /// Retrieve an iterator over all the crates in the index
    pub fn crates(&self) -> Crates {
        Crates(self.crate_index_paths())
    }

    /// Returns all the crate index file paths in the index
    pub fn crate_index_paths(&self) -> CrateIndexPaths {
        CrateIndexPaths::new(self.path.clone()) // TODO: remove this clone
    }

    /// Get the index directory.
    pub fn path(&self) -> &Path {
        &self.path
    }
}

/// A single crate that contains many published versions
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Crate {
    versions: Vec<Version>,
}

impl Crate {
    pub fn new<P: AsRef<Path>>(index_path: P) -> Crate {
        let index_path = index_path.as_ref();
        let mut versions = vec![];
        let file = fs::File::open(&index_path).unwrap();
        for line in BufReader::new(file).lines() {
            let version: Version = serde_json::from_str(&line.unwrap()).unwrap();
            versions.push(version);
        }
        Crate { versions: versions }
    }

    /// Published versions of this crate sorted chronologically by date published
    pub fn versions(&self) -> &[Version] {
        &self.versions
    }

    pub fn earliest_version(&self) -> &Version {
        &self.versions[0]
    }

    pub fn latest_version(&self) -> &Version {
        &self.versions[self.versions.len() - 1]
    }

    pub fn name(&self) -> &str {
        self.latest_version().name()
    }
}

#[cfg(test)]
mod test {
    use super::Index;
    extern crate tempdir;
    use self::tempdir::TempDir;

    #[test]
    fn test_dependencies() {
        let tmp_dir = TempDir::new("test1").unwrap();

        let index = Index::new(tmp_dir.path());
        index.retrieve_or_update().expect("could not fetch crates io index");
        // let crate_ = index.crates().nth(0).expect("could not find a crate in the index");
        let crate_ = index.crate_("sval").expect("Could not find the crate libnotify in the index");
        let _ = format!("supports debug {:?}", crate_);

        let version = crate_.versions().iter().find(|v| v.version() == "0.0.1")
            .expect("Version 0.0.1 of sval does not exist?");
        let dep_with_package_name = version.dependencies().iter().find(|d| d.name() == "serde_lib")
            .expect("sval does not have expected dependency?");
        assert_ne!(dep_with_package_name.name(), dep_with_package_name.package().unwrap());
        assert_eq!(dep_with_package_name.crate_name(), dep_with_package_name.package().unwrap());
    }

    #[test]
    fn test_retrieve_or_update() {
        let tmp_dir = TempDir::new("test2").unwrap();

        let index = Index::new(tmp_dir.path());
        index.retrieve_or_update().expect("could not fetch crates io index");
        assert!(index.exists());
        index.retrieve_or_update().expect("could not fetch crates io index");
        assert!(index.exists());
    }

    #[test]
    fn test_cargo_default_updates() {
        let index = Index::new_cargo_default();
        index.update().map_err(|e| format!("could not fetch cargo's index in {}: {}", index.path().display(), e)).unwrap();
        assert!(index.crate_("crates-index").is_some());
        assert!(index.crate_("toml").is_some());
    }

    #[test]
    fn test_exists() {
        let tmp_dir = TempDir::new("test3").unwrap();

        let index = Index::new(tmp_dir.path());
        assert!(!index.exists());
        index.retrieve().unwrap();
        assert!(index.exists());
    }
}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://docs.rs/hyper/0.13.4")]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, deny(rust_2018_idioms))]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]

//! # hyper
//!
//! hyper is a **fast** and **correct** HTTP implementation written in and for Rust.
//!
//! ## Features
//!
//! - HTTP/1 and HTTP/2
//! - Asynchronous design
//! - Leading in performance
//! - Tested and **correct**
//! - Extensive production use
//! - [Client](client/index.html) and [Server](server/index.html) APIs
//!
//! If just starting out, **check out the [Guides](https://hyper.rs/guides)
//! first.**
//!
//! ## "Low-level"
//!
//! hyper is a lower-level HTTP library, meant to be a building block
//! for libaries and applications.
//!
//! If looking for just a convenient HTTP client, consider the
//! [reqwest](https://crates.io/crates/reqwest) crate.
//!
//! # Optional Features
//!
//! The following optional features are available:
//!
//! - `runtime` (*enabled by default*): Enables convenient integration with
//!   `tokio`, providing connectors and acceptors for TCP, and a default
//!   executor.
//! - `tcp` (*enabled by default*): Enables convenient implementations over
//!   TCP (using tokio).
//! - `stream` (*enabled by default*): Provides `futures::Stream` capabilities.

#[doc(hidden)]
pub use http;
#[macro_use]
extern crate log;

#[cfg(all(test, feature = "nightly"))]
extern crate test;

pub use http::{header, HeaderMap, Method, Request, Response, StatusCode, Uri, Version};

pub use crate::body::Body;
pub use crate::client::Client;
pub use crate::error::{Error, Result};
pub use crate::server::Server;

#[macro_use]
mod common;
pub mod body;
pub mod client;
#[doc(hidden)] // Mistakenly public...
pub mod error;
mod headers;
#[cfg(test)]
mod mock;
mod proto;
pub mod rt;
pub mod server;
pub mod service;
pub mod upgrade;
<commit_msg>docs(lib): fix misspelling<commit_after>#![doc(html_root_url = "https://docs.rs/hyper/0.13.4")]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, deny(rust_2018_idioms))]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]

//! # hyper
//!
//! hyper is a **fast** and **correct** HTTP implementation written in and for Rust.
//!
//! ## Features
//!
//! - HTTP/1 and HTTP/2
//! - Asynchronous design
//! - Leading in performance
//! - Tested and **correct**
//! - Extensive production use
//! - [Client](client/index.html) and [Server](server/index.html) APIs
//!
//! If just starting out, **check out the [Guides](https://hyper.rs/guides)
//! first.**
//!
//! ## "Low-level"
//!
//! hyper is a lower-level HTTP library, meant to be a building block
//! for libraries and applications.
//!
//! If looking for just a convenient HTTP client, consider the
//! [reqwest](https://crates.io/crates/reqwest) crate.
//!
//! # Optional Features
//!
//! The following optional features are available:
//!
//! - `runtime` (*enabled by default*): Enables convenient integration with
//!   `tokio`, providing connectors and acceptors for TCP, and a default
//!   executor.
//! - `tcp` (*enabled by default*): Enables convenient implementations over
//!   TCP (using tokio).
//! - `stream` (*enabled by default*): Provides `futures::Stream` capabilities.

#[doc(hidden)]
pub use http;
#[macro_use]
extern crate log;

#[cfg(all(test, feature = "nightly"))]
extern crate test;

pub use http::{header, HeaderMap, Method, Request, Response, StatusCode, Uri, Version};

pub use crate::body::Body;
pub use crate::client::Client;
pub use crate::error::{Error, Result};
pub use crate::server::Server;

#[macro_use]
mod common;
pub mod body;
pub mod client;
#[doc(hidden)] // Mistakenly public...
pub mod error;
mod headers;
#[cfg(test)]
mod mock;
mod proto;
pub mod rt;
pub mod server;
pub mod service;
pub mod upgrade;
<|endoftext|>


<commit_before>/*!

*/

/*!

*/
#![feature(specialization)]

mod deps;
pub mod extension;

use std::any::Any;
use std::fmt;
pub use deps::{ Deps, Features, Scope };

pub struct Collection<T> {
    items: Vec<T>,
}

impl<T> fmt::Debug for Collection<T> where T: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.items.iter()).finish()
    }
}

impl<T> Collection<T> {
    pub fn new() -> Collection<T> {
        Collection {
            items: Vec::new()
        }
    }

    pub fn push(&mut self, item: T) {
        self.items.push(item)
    }
}

impl<T> Into<Vec<T>> for Collection<T> {
    fn into(self) -> Vec<T> {
        self.items
    }
}

pub struct Expect<T: Any> {
    response: Option<T>,
}

impl<T: Any> Expect<T> {
    pub fn load(deps: &Deps) -> Result<T, ()> {
        let expectation = Expect::<T> {
            response: None,
        };
        let maybe_fullfilled = deps.create_for(expectation).explode();
        match maybe_fullfilled.response {
            Some(value) => Ok(value),
            None => Err(()),
        }
    }

    pub fn replace(&mut self, value: T) -> Result<(), ()> {
        if let Some(_) = self.response {
            return Err(());
        }

        self.response = Some(value);

        Ok(())
    }
}

pub fn load_from<T: Any>(deps: &Deps) -> Result<T, ()> {
    Expect::load(deps)
}
<commit_msg>Allow immutable inspection of collection items.<commit_after>/*!

*/

/*!

*/
#![feature(specialization)]

mod deps;
pub mod extension;

use std::any::Any;
use std::fmt;
use std::convert;
pub use deps::{ Deps, Features, Scope };

pub struct Collection<T> {
    items: Vec<T>,
}

impl<T> fmt::Debug for Collection<T> where T: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.items.iter()).finish()
    }
}

impl<T> Collection<T> {
    pub fn new() -> Collection<T> {
        Collection {
            items: Vec::new()
        }
    }

    pub fn push(&mut self, item: T) {
        self.items.push(item)
    }
}

impl<T> convert::AsRef<[T]> for Collection<T> {
    fn as_ref(&self) -> &[T] {
        &self.items
    }
}

impl<T> Into<Vec<T>> for Collection<T> {
    fn into(self) -> Vec<T> {
        self.items
    }
}

pub struct Expect<T: Any> {
    response: Option<T>,
}

impl<T: Any> Expect<T> {
    pub fn load(deps: &Deps) -> Result<T, ()> {
        let expectation = Expect::<T> {
            response: None,
        };
        let maybe_fullfilled = deps.create_for(expectation).explode();
        match maybe_fullfilled.response {
            Some(value) => Ok(value),
            None => Err(()),
        }
    }

    pub fn replace(&mut self, value: T) -> Result<(), ()> {
        if let Some(_) = self.response {
            return Err(());
        }

        self.response = Some(value);

        Ok(())
    }
}

pub fn load_from<T: Any>(deps: &Deps) -> Result<T, ()> {
    Expect::load(deps)
}
<|endoftext|>


<commit_before>#![feature(slice_splits)]
extern crate itertools;
use itertools::partition;

#[derive(Debug, Clone)]
struct LazySort<T> {
    greater: Vec<T>,
    less: Option<Box<LazySort<T>>>,
}

impl<T: Ord> LazySort<T> {
    fn split_greater(&mut self) -> Option<T> {
        match self.greater.len() {
            0 => None,
            1 => self.greater.pop(),
            _ => {
                let split_idx = {
                    let (pivot, rest) = self.greater.split_last_mut().unwrap();
                    partition(rest, |el| el > pivot)
                };
                let pivot_idx = self.greater.len() - 1;
                self.greater.swap(pivot_idx, split_idx);
                let mut less = Box::new(LazySort {
                    greater: self.greater.split_off(split_idx + 1),
                    less: None
                });
                if let next @ Some(_) = less.next() {
                    self.less = Some(less);
                    next
                } else {
                    self.greater.pop()
                }
            }
        }
    }
}

impl<T: Ord> Iterator for LazySort<T> {
    type Item = T;

    #[inline]
    fn next(&mut self) -> Option<T> {
        let next = if let Some(ref mut less) = self.less {
            less.next()
        } else {
            return self.split_greater();
        };
        if next.is_some() {
            next
        } else {
            self.less = None;
            self.greater.pop()
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.less {
            None => (self.greater.len(), Some(self.greater.len())),
            Some(ref less) => {
                let (lower, upper) = less.size_hint();
                (lower + self.greater.len(), upper.map(|upper| upper + self.greater.len()))
            }
        }
    }

}

trait LazySortIterator: Iterator
    where Self: Sized
{
    fn lazy_sort(self) -> LazySort<Self::Item> {
        LazySort {
            greater: self.collect(),
            less: None,
        }
    }
}

impl<T> LazySortIterator for T where T: Iterator { }

#[test]
fn test_sort() {
    let mut v = vec![2, 4, 2, 5, 8, 4, 3, 4, 6];
    let v2: Vec<_> = v.iter().cloned().lazy_sort().collect();
    v.sort();
    assert_eq!(v, v2);
}

#[test]
fn test_empty() {
    let v: Vec<u64> = vec![];
    let v2: Vec<_> = v.iter().cloned().lazy_sort().collect();
    assert_eq!(v, v2);
}
<commit_msg>Add size hint test<commit_after>#![feature(slice_splits)]
extern crate itertools;
use itertools::partition;

#[derive(Debug, Clone)]
struct LazySort<T> {
    greater: Vec<T>,
    less: Option<Box<LazySort<T>>>,
}

impl<T: Ord> LazySort<T> {
    fn split_greater(&mut self) -> Option<T> {
        match self.greater.len() {
            0 => None,
            1 => self.greater.pop(),
            _ => {
                let split_idx = {
                    let (pivot, rest) = self.greater.split_last_mut().unwrap();
                    partition(rest, |el| el > pivot)
                };
                let pivot_idx = self.greater.len() - 1;
                self.greater.swap(pivot_idx, split_idx);
                let mut less = Box::new(LazySort {
                    greater: self.greater.split_off(split_idx + 1),
                    less: None
                });
                if let next @ Some(_) = less.next() {
                    self.less = Some(less);
                    next
                } else {
                    self.greater.pop()
                }
            }
        }
    }
}

impl<T: Ord> Iterator for LazySort<T> {
    type Item = T;

    #[inline]
    fn next(&mut self) -> Option<T> {
        let next = if let Some(ref mut less) = self.less {
            less.next()
        } else {
            return self.split_greater();
        };
        if next.is_some() {
            next
        } else {
            self.less = None;
            self.greater.pop()
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.less {
            None => (self.greater.len(), Some(self.greater.len())),
            Some(ref less) => {
                let (lower, upper) = less.size_hint();
                (lower + self.greater.len(), upper.map(|upper| upper + self.greater.len()))
            }
        }
    }

}

trait LazySortIterator: Iterator
    where Self: Sized
{
    fn lazy_sort(self) -> LazySort<Self::Item> {
        LazySort {
            greater: self.collect(),
            less: None,
        }
    }
}

impl<T> LazySortIterator for T where T: Iterator { }

#[test]
fn test_sort() {
    let mut v = vec![2, 4, 2, 5, 8, 4, 3, 4, 6];
    let v2: Vec<_> = v.iter().cloned().lazy_sort().collect();
    v.sort();
    assert_eq!(v, v2);
}

#[test]
fn test_empty() {
    let v: Vec<u64> = vec![];
    let v2: Vec<_> = v.iter().cloned().lazy_sort().collect();
    assert_eq!(v, v2);
}

#[test]
fn test_size_hint() {
    let v = vec![2, 4, 2, 5, 8, 4, 3, 4, 6];
    let mut sort_iter = v.iter().cloned().lazy_sort();
    for i in 0..v.len() {
        let (lower, upper) = sort_iter.size_hint();
        assert_eq!(v.len() - i, lower);
        assert_eq!(Some(v.len() - i), upper);
        sort_iter.next();
    }
}
<|endoftext|>


<commit_before>#![crate_name = "bitmap"]
#![crate_type = "lib"]

use std::io;

/// Main bitmap structure
pub struct Bitmap {
    pub width:  uint,
    pub height: uint,
    pixels: Vec<u8>,
}

impl Bitmap {
    /// Set a pixel at x,y to a specified color
    /// # Arugments
    /// `x` - x coordinate
    /// `y` - y coordinate
    /// `color` - color values in the form (r, g, b)
    pub fn set_pixel(&mut self, x: uint, y: uint, color: (u8, u8, u8)) {
        // Calculate the byte offset for x
        let i = (self.height - y - 1) * (self.width * 3) + x * 3;

        // Note: Pixel order for bitmaps is (blue, green, red)
        let (r, g, b) = color;
        *self.pixels.get_mut(i + 0) = r;
        *self.pixels.get_mut(i + 1) = g;
        *self.pixels.get_mut(i + 2) = b;
    }

    /// Write the stored data to a file with given filename
    /// # Arguments
    /// `filename` - the file name to save the file to
    pub fn write_to_file(&self, filename: &str) -> io::IoResult<()> {
        static FILE_HEADER_SIZE:  u32 = 14;
        static BMP_INFO_SIZE:     u32 = 40;
        static TOTAL_HEADER_SIZE: u32 = FILE_HEADER_SIZE + BMP_INFO_SIZE;

        let image_size = (self.height * self.width*3 + self.height * (self.width % 4)) as u32;
        let file_size = image_size + TOTAL_HEADER_SIZE;

        // Bitmap file header
        let file_header: [u8, ..FILE_HEADER_SIZE] = [
            'B' as u8, 'M' as u8,
            file_size as u8, (file_size>>8) as u8, (file_size>>16) as u8, (file_size>>24) as u8,
            0, 0,
            0, 0,
            TOTAL_HEADER_SIZE as u8, 0, 0, 0
        ];
        // Bitmap information header
        let info_header: [u8, ..BMP_INFO_SIZE] = [
            BMP_INFO_SIZE as u8, 0, 0, 0,
            self.width as u8, (self.width>>8) as u8, (self.width>>16) as u8, (self.width>>24) as u8,
            self.height as u8, (self.height>>8) as u8, (self.height>>16) as u8, (self.height>>24) as u8,
            1, 0,
            24, 0,
            0, 0, 0, 0,
            image_size as u8, (image_size>>8) as u8, (image_size>>16) as u8, (image_size>>24) as u8,
            72, 0, 0, 0,
            72, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0
        ];

        // Set up the file writer
        let mut file = io::File::create(&Path::new(filename));

        // Write the bitmap headers to file
        try!(file.write(file_header));
        try!(file.write(info_header));

        // Write data to file
        file.write(self.pixels.as_slice())
    }

    /// Create a new bitmap
    /// # Arguments
    /// `width` - the width of the bitmap
    /// `height` - the height of the bitmap
    pub fn new(width: uint, height: uint) -> Bitmap {
        Bitmap {
            width:  width,
            height: height,
            pixels: Vec::from_elem(height * (width * 3 + width % 4), 0u8)
        }
    }
}
<commit_msg>Fix pixel color ordering.<commit_after>#![crate_name = "bitmap"]
#![crate_type = "lib"]

use std::io;

/// Main bitmap structure
pub struct Bitmap {
    pub width:  uint,
    pub height: uint,
    pixels: Vec<u8>,
}

impl Bitmap {
    /// Set a pixel at x,y to a specified color
    /// # Arugments
    /// `x` - x coordinate
    /// `y` - y coordinate
    /// `color` - color values in the form (r, g, b)
    pub fn set_pixel(&mut self, x: uint, y: uint, color: (u8, u8, u8)) {
        // Calculate the byte offset for x
        let i = (self.height - y - 1) * (self.width * 3) + x * 3;

        // Note: Pixel order for bitmaps is (blue, green, red)
        let (r, g, b) = color;
        *self.pixels.get_mut(i + 0) = b;
        *self.pixels.get_mut(i + 1) = g;
        *self.pixels.get_mut(i + 2) = r;
    }

    /// Write the stored data to a file with given filename
    /// # Arguments
    /// `filename` - the file name to save the file to
    pub fn write_to_file(&self, filename: &str) -> io::IoResult<()> {
        static FILE_HEADER_SIZE:  u32 = 14;
        static BMP_INFO_SIZE:     u32 = 40;
        static TOTAL_HEADER_SIZE: u32 = FILE_HEADER_SIZE + BMP_INFO_SIZE;

        let image_size = (self.height * self.width*3 + self.height * (self.width % 4)) as u32;
        let file_size = image_size + TOTAL_HEADER_SIZE;

        // Bitmap file header
        let file_header: [u8, ..FILE_HEADER_SIZE] = [
            'B' as u8, 'M' as u8,
            file_size as u8, (file_size>>8) as u8, (file_size>>16) as u8, (file_size>>24) as u8,
            0, 0,
            0, 0,
            TOTAL_HEADER_SIZE as u8, 0, 0, 0
        ];
        // Bitmap information header
        let info_header: [u8, ..BMP_INFO_SIZE] = [
            BMP_INFO_SIZE as u8, 0, 0, 0,
            self.width as u8, (self.width>>8) as u8, (self.width>>16) as u8, (self.width>>24) as u8,
            self.height as u8, (self.height>>8) as u8, (self.height>>16) as u8, (self.height>>24) as u8,
            1, 0,
            24, 0,
            0, 0, 0, 0,
            image_size as u8, (image_size>>8) as u8, (image_size>>16) as u8, (image_size>>24) as u8,
            72, 0, 0, 0,
            72, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0
        ];

        // Set up the file writer
        let mut file = io::File::create(&Path::new(filename));

        // Write the bitmap headers to file
        try!(file.write(file_header));
        try!(file.write(info_header));

        // Write data to file
        file.write(self.pixels.as_slice())
    }

    /// Create a new bitmap
    /// # Arguments
    /// `width` - the width of the bitmap
    /// `height` - the height of the bitmap
    pub fn new(width: uint, height: uint) -> Bitmap {
        Bitmap {
            width:  width,
            height: height,
            pixels: Vec::from_elem(height * (width * 3 + width % 4), 0u8)
        }
    }
}
<|endoftext|>