<commit_before>//! **GraphMap\<N, E\>** is an undirected graph where node values are mapping keys.

use std::hash::{Hash};
use std::collections::HashMap;
use std::iter::Map;
use std::collections::hash_map::{
    Keys,
};
use std::slice::{
    Iter,
};
use std::fmt;
use std::ops::{Index, IndexMut};

/// **GraphMap\<N, E\>** is an undirected graph, with generic node values **N** and edge weights **E**.
///
/// It uses an combined adjacency list and sparse adjacency matrix representation, using **O(|V|
/// + |E|)** space, and allows testing for edge existance in constant time.
///
/// The node type **N** must implement **Copy** and will be used as node identifier, duplicated
/// into several places in the data structure.
/// It must be suitable as a hash table key (implementing **Eq + Hash**).
/// The node type must also implement **Ord** so that the implementation can
/// order the pair (**a**, **b**) for an edge connecting any two nodes **a** and **b**.
///
/// **GraphMap** does not allow parallel edges, but self loops are allowed.
#[derive(Clone)]
pub struct GraphMap<N: Eq + Hash, E> {
    nodes: HashMap<N, Vec<N>>,
    edges: HashMap<(N, N), E>,
}

impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug> fmt::Debug for GraphMap<N, E>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.nodes.fmt(f)
    }
}

#[inline]
fn edge_key<N: Copy + Ord>(a: N, b: N) -> (N, N)
{
    if a <= b { (a, b) } else { (b, a) }
}

#[inline]
fn copy<N: Copy>(n: &N) -> N { *n }

/// A trait group for **GraphMap**'s node identifier.
pub trait NodeTrait : Copy + Ord + Eq + Hash {}
impl<N> NodeTrait for N where N: Copy + Ord + Eq + Hash {}

impl<N, E> GraphMap<N, E> where N: NodeTrait
{
    /// Create a new **GraphMap**.
    pub fn new() -> Self
    {
        GraphMap {
            nodes: HashMap::new(),
            edges: HashMap::new(),
        }
    }

    /// Create a new **GraphMap** with estimated capacity.
    pub fn with_capacity(nodes: usize, edges: usize) -> Self
    {
        GraphMap {
            nodes: HashMap::with_capacity(nodes),
            edges: HashMap::with_capacity(edges),
        }
    }

    /// Return the number of nodes in the graph.
    pub fn node_count(&self) -> usize
    {
        self.nodes.len()
    }

    /// Return the number of edges in the graph.
    pub fn edge_count(&self) -> usize
    {
        self.edges.len()
    }

    /// Remove all nodes and edges
    pub fn clear(&mut self)
    {
        self.nodes.clear();
        self.edges.clear();
    }

    /// Add node **n** to the graph.
    pub fn add_node(&mut self, n: N) -> N {
        self.nodes.entry(n).or_insert_with(|| Vec::new());
        n
    }

    /// Return **true** if node **n** was removed.
    pub fn remove_node(&mut self, n: N) -> bool {
        let successors = match self.nodes.remove(&n) {
            None => return false,
            Some(sus) => sus,
        };
        for succ in successors.into_iter() {
            // remove all successor links
            self.remove_single_edge(&succ, &n);
            // Remove all edge values
            self.edges.remove(&edge_key(n, succ));
        }
        true
    }

    /// Return **true** if the node is contained in the graph.
    pub fn contains_node(&self, n: N) -> bool {
        self.nodes.contains_key(&n)
    }

    /// Add an edge connecting **a** and **b** to the graph.
    ///
    /// Inserts nodes **a** and/or **b** if they aren't already part of the graph.
    ///
    /// Return **true** if edge did not previously exist.
    ///
    /// ## Example
    /// ```
    /// use petgraph::GraphMap;
    ///
    /// let mut g = GraphMap::new();
    /// g.add_edge(1, 2, -1);
    /// assert_eq!(g.node_count(), 2);
    /// assert_eq!(g.edge_count(), 1);
    /// ```
    pub fn add_edge(&mut self, a: N, b: N, edge: E) -> bool
    {
        // Use Ord to order the edges
        self.nodes.entry(a)
                  .or_insert_with(|| Vec::with_capacity(1))
                  .push(b);
        self.nodes.entry(b)
                  .or_insert_with(|| Vec::with_capacity(1))
                  .push(a);
        self.edges.insert(edge_key(a, b), edge).is_none()
    }

    /// Remove successor relation from a to b
    ///
    /// Return **true** if it did exist.
    fn remove_single_edge(&mut self, a: &N, b: &N) -> bool
    {
        match self.nodes.get_mut(a) {
            None => false,
            Some(sus) => {
                match sus.iter().position(|elt| elt == b) {
                    Some(index) => { sus.swap_remove(index); true }
                    None => false,
                }
            }
        }
    }

    /// Remove edge from **a** to **b** from the graph and return the edge weight.
    ///
    /// Return **None** if the edge didn't exist.
    ///
    /// ## Example
    ///
    /// ```
    /// use petgraph::GraphMap;
    ///
    /// let mut g = GraphMap::new();
    /// g.add_node(1);
    /// g.add_node(2);
    /// g.add_edge(1, 2, -1);
    ///
    /// let edge = g.remove_edge(2, 1);
    /// assert_eq!(edge, Some(-1));
    /// assert_eq!(g.edge_count(), 0);
    /// ```
    pub fn remove_edge(&mut self, a: N, b: N) -> Option<E>
    {
        let exist1 = self.remove_single_edge(&a, &b);
        let exist2 = self.remove_single_edge(&b, &a);
        let weight = self.edges.remove(&edge_key(a, b));
        debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
        weight
    }

    /// Return **true** if the edge connecting **a** with **b** is contained in the graph.
    pub fn contains_edge(&self, a: N, b: N) -> bool {
        self.edges.contains_key(&edge_key(a, b))
    }

    /// Return an iterator over the nodes of the graph.
    ///
    /// Iterator element type is **N**.
    pub fn nodes<'a>(&'a self) -> Nodes<'a, N>
    {
        Nodes{iter: self.nodes.keys().map(copy)}
    }

    /// Return an iterator over the nodes that are connected with **from** by edges.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **N**.
    pub fn neighbors<'a>(&'a self, from: N) -> Neighbors<'a, N>
    {
        Neighbors{iter:
            match self.nodes.get(&from) {
                Some(neigh) => neigh.iter(),
                None => [].iter(),
            }.map(copy)
        }
    }

    /// Return an iterator over the nodes that are connected with **from** by edges,
    /// paired with the edge weight.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **(N, &'a E)**.
    pub fn edges<'a>(&'a self, from: N) -> Edges<'a, N, E>
    {
        Edges {
            from: from,
            iter: self.neighbors(from),
            edges: &self.edges,
        }
    }

    /// Return a reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_weight<'a>(&'a self, a: N, b: N) -> Option<&'a E>
    {
        self.edges.get(&edge_key(a, b))
    }

    /// Return a mutable reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_weight_mut<'a>(&'a mut self, a: N, b: N) -> Option<&'a mut E>
    {
        self.edges.get_mut(&edge_key(a, b))
    }
}

/// Utitily macro -- reinterpret passed in macro arguments as items
macro_rules! items {
    ($($item:item)*) => ($($item)*);
}

macro_rules! iterator_wrap {
    ($name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
     item: $item: ty,
     iter: $iter: ty,
     ) => (
        items! {
            pub struct $name <$($typarm),*> where $($bounds)* {
                iter: $iter,
            }
            impl<$($typarm),*> Iterator for $name <$($typarm),*>
            {
                type Item = $item;
                #[inline]
                fn next(&mut self) -> Option<Self::Item> {
                    self.iter.next()
                }

                #[inline]
                fn size_hint(&self) -> (usize, Option<usize>) {
                    self.iter.size_hint()
                }
            }
        }
    );
}

iterator_wrap! {
    Nodes <'a, N> where { N: 'a }
    item: N,
    iter: Map<Keys<'a, N, Vec<N>>, fn(&N) -> N>,
}

iterator_wrap! {
    Neighbors <'a, N> where { N: 'a }
    item: N,
    iter: Map<Iter<'a, N>, fn(&N) -> N>,
}

pub struct Edges<'a, N, E: 'a> where N: 'a + NodeTrait
{
    pub from: N,
    pub edges: &'a HashMap<(N, N), E>,
    pub iter: Neighbors<'a, N>,
}

impl<'a, N, E> Iterator for Edges<'a, N, E>
    where N: 'a + NodeTrait, E: 'a
{
    type Item = (N, &'a E);
    fn next(&mut self) -> Option<(N, &'a E)>
    {
        match self.iter.next() {
            None => None,
            Some(b) => {
                let a = self.from;
                match self.edges.get(&edge_key(a, b)) {
                    None => unreachable!(),
                    Some(edge) => {
                        Some((b, edge))
                    }
                }
            }
        }
    }
}

/// Index **GraphMap** by node pairs to access edge weights.
impl<N, E> Index<(N, N)> for GraphMap<N, E> where N: NodeTrait
{
    type Output = E;
    fn index(&self, index: (N, N)) -> &E
    {
        self.edge_weight(index.0, index.1).expect("GraphMap::index: no such edge")
    }
}

/// Index **GraphMap** by node pairs to access edge weights.
impl<N, E> IndexMut<(N, N)> for GraphMap<N, E> where N: NodeTrait
{
    fn index_mut(&mut self, index: (N, N)) -> &mut E
    {
        self.edge_weight_mut(index.0, index.1).expect("GraphMap::index: no such edge")
    }
}
<commit_msg>Improve iterator wrapper macro<commit_after>//! **GraphMap\<N, E\>** is an undirected graph where node values are mapping keys.

use std::hash::{Hash};
use std::collections::HashMap;
use std::iter::Map;
use std::collections::hash_map::{
    Keys,
};
use std::slice::{
    Iter,
};
use std::fmt;
use std::ops::{Index, IndexMut};

/// **GraphMap\<N, E\>** is an undirected graph, with generic node values **N** and edge weights **E**.
///
/// It uses an combined adjacency list and sparse adjacency matrix representation, using **O(|V|
/// + |E|)** space, and allows testing for edge existance in constant time.
///
/// The node type **N** must implement **Copy** and will be used as node identifier, duplicated
/// into several places in the data structure.
/// It must be suitable as a hash table key (implementing **Eq + Hash**).
/// The node type must also implement **Ord** so that the implementation can
/// order the pair (**a**, **b**) for an edge connecting any two nodes **a** and **b**.
///
/// **GraphMap** does not allow parallel edges, but self loops are allowed.
#[derive(Clone)]
pub struct GraphMap<N: Eq + Hash, E> {
    nodes: HashMap<N, Vec<N>>,
    edges: HashMap<(N, N), E>,
}

impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug> fmt::Debug for GraphMap<N, E>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.nodes.fmt(f)
    }
}

#[inline]
fn edge_key<N: Copy + Ord>(a: N, b: N) -> (N, N)
{
    if a <= b { (a, b) } else { (b, a) }
}

#[inline]
fn copy<N: Copy>(n: &N) -> N { *n }

/// A trait group for **GraphMap**'s node identifier.
pub trait NodeTrait : Copy + Ord + Eq + Hash {}
impl<N> NodeTrait for N where N: Copy + Ord + Eq + Hash {}

impl<N, E> GraphMap<N, E> where N: NodeTrait
{
    /// Create a new **GraphMap**.
    pub fn new() -> Self
    {
        GraphMap {
            nodes: HashMap::new(),
            edges: HashMap::new(),
        }
    }

    /// Create a new **GraphMap** with estimated capacity.
    pub fn with_capacity(nodes: usize, edges: usize) -> Self
    {
        GraphMap {
            nodes: HashMap::with_capacity(nodes),
            edges: HashMap::with_capacity(edges),
        }
    }

    /// Return the number of nodes in the graph.
    pub fn node_count(&self) -> usize
    {
        self.nodes.len()
    }

    /// Return the number of edges in the graph.
    pub fn edge_count(&self) -> usize
    {
        self.edges.len()
    }

    /// Remove all nodes and edges
    pub fn clear(&mut self)
    {
        self.nodes.clear();
        self.edges.clear();
    }

    /// Add node **n** to the graph.
    pub fn add_node(&mut self, n: N) -> N {
        self.nodes.entry(n).or_insert_with(|| Vec::new());
        n
    }

    /// Return **true** if node **n** was removed.
    pub fn remove_node(&mut self, n: N) -> bool {
        let successors = match self.nodes.remove(&n) {
            None => return false,
            Some(sus) => sus,
        };
        for succ in successors.into_iter() {
            // remove all successor links
            self.remove_single_edge(&succ, &n);
            // Remove all edge values
            self.edges.remove(&edge_key(n, succ));
        }
        true
    }

    /// Return **true** if the node is contained in the graph.
    pub fn contains_node(&self, n: N) -> bool {
        self.nodes.contains_key(&n)
    }

    /// Add an edge connecting **a** and **b** to the graph.
    ///
    /// Inserts nodes **a** and/or **b** if they aren't already part of the graph.
    ///
    /// Return **true** if edge did not previously exist.
    ///
    /// ## Example
    /// ```
    /// use petgraph::GraphMap;
    ///
    /// let mut g = GraphMap::new();
    /// g.add_edge(1, 2, -1);
    /// assert_eq!(g.node_count(), 2);
    /// assert_eq!(g.edge_count(), 1);
    /// ```
    pub fn add_edge(&mut self, a: N, b: N, edge: E) -> bool
    {
        // Use Ord to order the edges
        self.nodes.entry(a)
                  .or_insert_with(|| Vec::with_capacity(1))
                  .push(b);
        self.nodes.entry(b)
                  .or_insert_with(|| Vec::with_capacity(1))
                  .push(a);
        self.edges.insert(edge_key(a, b), edge).is_none()
    }

    /// Remove successor relation from a to b
    ///
    /// Return **true** if it did exist.
    fn remove_single_edge(&mut self, a: &N, b: &N) -> bool
    {
        match self.nodes.get_mut(a) {
            None => false,
            Some(sus) => {
                match sus.iter().position(|elt| elt == b) {
                    Some(index) => { sus.swap_remove(index); true }
                    None => false,
                }
            }
        }
    }

    /// Remove edge from **a** to **b** from the graph and return the edge weight.
    ///
    /// Return **None** if the edge didn't exist.
    ///
    /// ## Example
    ///
    /// ```
    /// use petgraph::GraphMap;
    ///
    /// let mut g = GraphMap::new();
    /// g.add_node(1);
    /// g.add_node(2);
    /// g.add_edge(1, 2, -1);
    ///
    /// let edge = g.remove_edge(2, 1);
    /// assert_eq!(edge, Some(-1));
    /// assert_eq!(g.edge_count(), 0);
    /// ```
    pub fn remove_edge(&mut self, a: N, b: N) -> Option<E>
    {
        let exist1 = self.remove_single_edge(&a, &b);
        let exist2 = self.remove_single_edge(&b, &a);
        let weight = self.edges.remove(&edge_key(a, b));
        debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
        weight
    }

    /// Return **true** if the edge connecting **a** with **b** is contained in the graph.
    pub fn contains_edge(&self, a: N, b: N) -> bool {
        self.edges.contains_key(&edge_key(a, b))
    }

    /// Return an iterator over the nodes of the graph.
    ///
    /// Iterator element type is **N**.
    pub fn nodes<'a>(&'a self) -> Nodes<'a, N>
    {
        Nodes{iter: self.nodes.keys().map(copy)}
    }

    /// Return an iterator over the nodes that are connected with **from** by edges.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **N**.
    pub fn neighbors<'a>(&'a self, from: N) -> Neighbors<'a, N>
    {
        Neighbors{iter:
            match self.nodes.get(&from) {
                Some(neigh) => neigh.iter(),
                None => [].iter(),
            }.map(copy)
        }
    }

    /// Return an iterator over the nodes that are connected with **from** by edges,
    /// paired with the edge weight.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **(N, &'a E)**.
    pub fn edges<'a>(&'a self, from: N) -> Edges<'a, N, E>
    {
        Edges {
            from: from,
            iter: self.neighbors(from),
            edges: &self.edges,
        }
    }

    /// Return a reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_weight<'a>(&'a self, a: N, b: N) -> Option<&'a E>
    {
        self.edges.get(&edge_key(a, b))
    }

    /// Return a mutable reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_weight_mut<'a>(&'a mut self, a: N, b: N) -> Option<&'a mut E>
    {
        self.edges.get_mut(&edge_key(a, b))
    }
}

/// Utitily macro -- reinterpret passed in macro arguments as items
macro_rules! items {
    ($($item:item)*) => ($($item)*);
}

macro_rules! iterator_wrap {
    ($name: ident <$($typarm:tt),*> where { $($bounds: tt)* }
     item: $item: ty,
     iter: $iter: ty,
     ) => (
        items! {
            pub struct $name <$($typarm),*> where $($bounds)* {
                iter: $iter,
            }
            impl<$($typarm),*> Iterator for $name <$($typarm),*>
            {
                type Item = $item;
                #[inline]
                fn next(&mut self) -> Option<Self::Item> {
                    self.iter.next()
                }

                #[inline]
                fn size_hint(&self) -> (usize, Option<usize>) {
                    self.iter.size_hint()
                }
            }
            impl<$($typarm),*> DoubleEndedIterator for $name <$($typarm),*>
                where $iter: DoubleEndedIterator<Item=$item>,
            {
                #[inline]
                fn next_back(&mut self) -> Option<Self::Item> {
                    self.iter.next_back()
                }
            }

            impl<$($typarm),*> ExactSizeIterator for $name <$($typarm),*>
                where $iter: ExactSizeIterator<Item=$item>,
            {
            }
        }
    );
}

iterator_wrap! {
    Nodes <'a, N> where { N: 'a }
    item: N,
    iter: Map<Keys<'a, N, Vec<N>>, fn(&N) -> N>,
}

iterator_wrap! {
    Neighbors <'a, N> where { N: 'a }
    item: N,
    iter: Map<Iter<'a, N>, fn(&N) -> N>,
}

pub struct Edges<'a, N, E: 'a> where N: 'a + NodeTrait
{
    pub from: N,
    pub edges: &'a HashMap<(N, N), E>,
    pub iter: Neighbors<'a, N>,
}

impl<'a, N, E> Iterator for Edges<'a, N, E>
    where N: 'a + NodeTrait, E: 'a
{
    type Item = (N, &'a E);
    fn next(&mut self) -> Option<(N, &'a E)>
    {
        match self.iter.next() {
            None => None,
            Some(b) => {
                let a = self.from;
                match self.edges.get(&edge_key(a, b)) {
                    None => unreachable!(),
                    Some(edge) => {
                        Some((b, edge))
                    }
                }
            }
        }
    }
}

/// Index **GraphMap** by node pairs to access edge weights.
impl<N, E> Index<(N, N)> for GraphMap<N, E> where N: NodeTrait
{
    type Output = E;
    fn index(&self, index: (N, N)) -> &E
    {
        self.edge_weight(index.0, index.1).expect("GraphMap::index: no such edge")
    }
}

/// Index **GraphMap** by node pairs to access edge weights.
impl<N, E> IndexMut<(N, N)> for GraphMap<N, E> where N: NodeTrait
{
    fn index_mut(&mut self, index: (N, N)) -> &mut E
    {
        self.edge_weight_mut(index.0, index.1).expect("GraphMap::index: no such edge")
    }
}
<|endoftext|>


<commit_before>//!
//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern crate knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

#![crate_id = "knob#1.0.1"]
#![crate_type = "lib"]
#![comment = "A convenient Rust settings system"]
#![license = "MIT"]

extern crate getopts;
extern crate collections;

use collections::hashmap::HashMap;
use std::os;
use std::from_str::FromStr;
use std::to_str::ToStr;

use getopts::{usage,getopts,OptGroup};
use getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  priv store: HashMap<~str,~str>,
  priv options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: |Option<T>| -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

<commit_msg>Remove priv statements<commit_after>//!
//! A convenient structure to store and load settings.
//!
//! It is meant for items that are rarely read and stored, like command line flags or
//! application configuration.
//!
//! knob::Settings expects all values to implement ToStr + FromStr and stores them as
//! strings internally. This allows sideloading of settings through multiple means, e.g.
//! the command line or a simple config file. knob is not meant for structured data. If
//! you want to load such data, store the location of the data as a Knob setting and do
//! the loading parsing yourself.
//!
//! knob is typesafe in a sense that it will return you the type you wanted back if possible and
//! fails otherwise.
//!
//! knob allows you to decorate the Settings structure yourself for convenience (see examples).
//!
//! # Storing and fetching values
//!
//! The following example shows you how to store an ip in knob:
//!
//! ~~~{.rust}
//! extern crate knob;
//! use knob::*;
//! use std::rt::io::net::ip::IpAddr;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "0.0.0.0:4567");
//!   let socket: IpAddr = settings.socket();
//!   assert_eq!(socket.to_str(), ~"0.0.0.0:4567")
//! }
//! ~~~
//!
//! This works the same for IPv6 addresses:
//!
//! ~~~{.rust}
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set("ip", "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch("ip");
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Providing your own keys
//!
//! You can use enums as keys, as long as they implement ToStr:
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.fetch(Ip);
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! # Registering command line options
//!
//! Knob allows you to register command line options to read from the command line later.
//!
//! The options are getopts option groups.
//!
//! If the loading of the command line args fails, an error will be returned.
//!
//! ~~~{.rust}
//! use extra::getopts::groups::*;
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.opt(optopt("p", "port", "the port to bind to", "4000"))
//!   settings.opt(reqopt("e", "environment", "the environment to run in", ""));;
//!   let errors = settings.load_os_args();
//!   if errors.is_some() {
//!     println(settings.usage("Try one of these:"))
//!   }
//! }
//! ~~~
//!
//! # Decorating the settings struct
//!
//! To make matters more convenient, you can implement a decorator
//! to implement your own loading behaviour.
//!
//! ~~~{.rust}
//! enum Keys {
//!   Port,
//!   Ip,
//!   Addr,
//! }
//!
//! pub trait SocketSettings {
//!   fn socket(&self) -> SocketAddr;
//!   fn port(&self) -> u16;
//!   fn ip(&self) -> IpAddr;
//! }
//!
//! impl SocketSettings for Settings {
//!   fn socket(&self) -> SocketAddr {
//!     do self.fetch_with(Addr) |addr| {
//!       match addr {
//!         Some(socket_addr) => { socket_addr },
//!         None => {
//!           let port: u16 = self.port();
//!           let ip: IpAddr = self.ip();
//!           SocketAddr { ip: ip, port: port }
//!         }
//!       }
//!     }
//!   }
//!
//!   fn port(&self) -> u16 {
//!     self.fetch(Port).unwrap_or(8080)
//!   }
//!
//!   fn ip(&self) -> IpAddr {
//!     self.fetch(Ip).unwrap_or(Ipv4Addr(127,0,0,1))
//!   }
//! }
//! enum Keys {
//!   Port,
//!   Ip,
//! }
//!
//! fn main() {
//!   let settings = Settings::new();
//!   settings.set(Ip, "::0.0.0.1");
//!   let socket: IpAddr = settings.ip();
//!   assert_eq!(socket.to_str(), ~"::0.0.0.1")
//! }
//! ~~~
//!
//! knob goes up to 11.

#![crate_id = "knob#1.0.1"]
#![crate_type = "lib"]
#![comment = "A convenient Rust settings system"]
#![license = "MIT"]

extern crate getopts;
extern crate collections;

use collections::hashmap::HashMap;
use std::os;
use std::from_str::FromStr;
use std::to_str::ToStr;

use getopts::{usage,getopts,OptGroup};
use getopts::Fail_;

/// The settings structure we save the options and settings in.
#[deriving(Clone)]
pub struct Settings {
  store: HashMap<~str,~str>,
  options: ~[OptGroup],
}

impl Settings {
  /// Create a new Settings struct.
  pub fn new() -> Settings {
    Settings { store: HashMap::new(), options: ~[] }
  }

  /// Set a settings key to a value. The value will be serialized.
  pub fn set<A: ToStr, T: ToStr>(&mut self, setting: A, value: T) {
    self.store.swap(setting.to_str(), value.to_str());
  }

  /// Set a value using an Option struct. The value will only be set if the
  /// Some value is given. This way, you can avoid unwrapping the result of a
  /// previous operation by yourself.
  pub fn set_opt<A: ToStr, T: ToStr>(&mut self, setting: A, value: Option<T>) {
    if !value.is_none() {
      self.store.swap(setting.to_str(), value.unwrap().to_str());
    }
  }

  /// Fetch a setting for a key. Fails if the setting is present but could not be
  /// parsed.
  pub fn fetch<A: ToStr, T: FromStr>(&self, setting: A) -> Option<T> {
    match self.store.find(&setting.to_str()) {
      Some(string) => {
        let value = from_str(string.to_owned());
        if value.is_none() {
          fail!("setting could not be parsed:" + setting.to_str())
        }
        value
      },
      None => { None }
    }
  }

  /// Fetch a setting for a key and pass it to given function. The result of the function
  /// will be returned.
  pub fn fetch_with<A: ToStr, T: FromStr>(&self, setting: A, f: |Option<T>| -> T) -> T {
    let value = self.fetch(setting.to_str());
    f(value)
  }

  /// Register a commandline for laster use with load_args.
  ///
  /// Currently, only optopt and reqopt are properly supported.
  pub fn opt(&mut self, opt: OptGroup) {
    self.options.push(opt);
  }

  /// Load the command line argument given by the OS.
  ///
  /// Optionally returns failures.
  pub fn load_os_args(&mut self) -> Option<Fail_> {
    let args = os::args();
    self.load_args(args)
  }

  /// Load a list of command line arguments.
  ///
  /// Automatically sets "knob.progname" to the name of the program.
  ///
  /// Optionally returns failures.
  pub fn load_args(&mut self, args: ~[~str]) -> Option<Fail_> {
    let ref prog_name = args[0];

    self.set("knob.progname", prog_name.clone());

    let matches = match getopts(args.tail(), self.options) {
      Ok(m) => { m }
      Err(fail) => { return Some(fail) }
    };

    let given_options = self.options.clone();
    for opt in given_options.iter() {
      let opt_strings = &[opt.short_name.clone(), opt.long_name.clone()];
      self.set_opt(opt.long_name.clone(), matches.opts_str(opt_strings))
    };
    None
  }

  /// Returns the usage string for the stored OptGroups. Pass `brief`
  /// to have it included.
  pub fn usage(&self, brief: &str) -> ~str {
    usage(brief, self.options)
  }
}

<|endoftext|>


<commit_before>//! ICWS '94 draft
//!

use std::ops::{Index, IndexMut};

// #[derive(Clone, Copy, Debug, Default)]
// pub struct Address(u32);
pub type Address = u32;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Opcode {
    DAT, // terminate process
    MOV, // move from A to B
    ADD, // add A to B, store result in B
    SUB, // subtract A from B, store result in B
    MUL, // multiply A by B, store result in B
    DIV, // divide B by A, store result in B if A <> 0, else terminate
    MOD, // divide B by A, store remainder in B if A <> 0, else terminate
    JMP, // transfer execution to A
    JMZ, // transfer execution to A if B is zero
    JMN, // transfer execution to A if B is non-zero
    DJN, // decrement B, if B is non-zero, transfer execution to A
    CMP, // same as SEQ
    SLT, // skip next instruction if A is less than B
    SPL, // split off process to A
    SEQ, // (*) Skip next instruction if A is equal to B
    SNE, // (*) Skip next instruction if A is not equal to B
    NOP, // (*) No operation
    LDP, // (+) Load P-space cell A into core address B
    STP, // (+) Store A-number into P-space cell B
}

impl Default for Opcode {
    fn default() -> Self {
        Opcode::DAT
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Modifier {
    A,
    B,
    AB,
    BA,
    F,
    X,
    I,
}

impl Default for Modifier {
    fn default() -> Self {
        Modifier::A
    }
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Mode {
    IMMEDIATE, // #
    DIRECT, // $ (Default)
    INDIRECT, // @
    DECREMENT, // <
    INCREMENT, // >
}

impl Default for Mode {
    fn default() -> Self {
        Mode::IMMEDIATE
    }
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Instruction {
    pub opcode: Opcode,
    pub modifier: Modifier,
    pub a_mode: Mode,
    pub a_number: Address,
    pub b_mode: Mode,
    pub b_number: Address,
}

impl Instruction {
    pub fn random() -> Self {
        Instruction::default()  // XXX Need real random implementation
    }
}

#[derive(Clone, Copy, Debug, Default)]
pub struct Warrior(u32);

#[derive(Debug)]
pub struct TaskQueue {
    task_limit: usize,
    task_pointer: Vec<Address>,
}

impl TaskQueue {
    fn new(limit: usize) -> Self {
        TaskQueue {
            task_limit: limit,
            task_pointer: Vec::<Address>::with_capacity(limit),
        }
    }

    pub fn queue(&mut self, addr: Address) {
        if self.task_pointer.len() < self.task_limit {
            self.task_pointer.push(addr);
        }
    }

    pub fn next(&mut self) -> Option<Address> {
        if self.task_pointer.len() > 0 {
            Some(self.task_pointer.remove(0))
        } else {
            None
        }
    }
}

#[derive(Debug)]
pub struct CoreMemory(Address, Vec<Instruction>);

impl Index<Address> for CoreMemory {
    type Output = Instruction;

    fn index<'a>(&'a self, _index: Address) -> &'a Instruction {
        &self.1[(_index % self.0) as usize]
    }
}

impl IndexMut<Address> for CoreMemory {
    fn index_mut<'a>(&'a mut self, _index: Address) -> &'a mut Instruction {
        &mut self.1[(_index % self.0) as usize]
    }
}

impl CoreMemory {
    fn new(size: Address, initial_instruction: InitialInstruction) -> Self {
        let mut instructions = Vec::<Instruction>::new();
        for _ in 0..size {
            instructions.push(match initial_instruction {
                InitialInstruction::Default => Instruction::default(),
                InitialInstruction::Random => Instruction::random(),
                InitialInstruction::Instruction(insn) => insn,
            })
        }

        CoreMemory(size, instructions)
    }

    fn size(&self) -> Address {
        self.0
    }
}

#[derive(Debug)]
pub struct Core {
    core: CoreMemory,
    warrior: [TaskQueue; 2],
    read_limit: Address,
    write_limit: Address,
}

impl Core {
    pub fn queue(&mut self, warrior: usize, task_pointer: Address) {
        self.warrior[warrior].queue(task_pointer)
    }

    fn fold(&self, pointer: Address, limit: Address) -> Address {
        let mut result = pointer % limit;
        if result > limit / 2 {
            result += self.core.size() - limit;
        }
        result
    }

    fn direct(&self, number: Address) -> (Address, Address) {
        (self.fold(number, self.read_limit),
         self.fold(number, self.write_limit))
    }

    fn indirect_pointer(&self, pc: Address, number: Address, limit: Address) -> Address {
        let p = self.fold(number, limit);
        let i = p + self.core[pc + p].b_number;
        self.fold(i, limit)
    }

    fn indirect(&self, pc: Address, number: Address) -> (Address, Address) {
        (self.indirect_pointer(pc, number, self.read_limit),
         self.indirect_pointer(pc, number, self.write_limit))
    }

    pub fn evaluate(&mut self, pc: Address, mode: Mode, number: Address) -> (Address, Address) {
        // let mut rp: Address;
        // let mut wp: Address;
        let rlim = self.read_limit;
        let wlim = self.write_limit;

        match mode {
            Mode::IMMEDIATE => (0, 0),
            Mode::DIRECT => self.direct(number),
            Mode::INDIRECT => self.indirect(pc, number),
            Mode::DECREMENT => (self.fold(number, rlim), self.fold(number, wlim)),
            Mode::INCREMENT => (self.fold(number, rlim), self.fold(number, wlim)),
        }
    }

    pub fn emi94(&mut self, pc: Address) {
        let ir: Instruction;
        let ira: Instruction;
        let irb: Instruction;
        let mut rpa: Address;
        let mut wpa: Address;
        let rpb: Address;
        let wpb: Address;
        let mut pip: Address = 0;
        let size = self.core.size();

        ir = self.core[pc];

        // Evaluate A-operand
        //
        if ir.a_mode == Mode::IMMEDIATE {
            // For instructions with an Immediate A-mode, the Pointer A
            // points to the source of the current instruction.
            rpa = 0;
            wpa = 0;
        } else {
            // For instructions with a Direct A-mode, the Pointer A
            // points to the instruction IR.ANumber away, relative to
            // the Program Counter.
            rpa = self.fold(ir.a_number, self.read_limit);
            wpa = self.fold(ir.a_number, self.write_limit);

            if ir.a_mode != Mode::DIRECT {
                if ir.a_mode == Mode::DECREMENT {
                    self.core[pc + wpa].b_number = (self.core[pc + wpa].b_number + size - 1) % size;
                }

                if ir.a_mode == Mode::INCREMENT {
                    pip = (pc + wpa) % size;
                }

                rpa = self.fold((rpa + self.core[pc + rpa].b_number), self.read_limit);
                wpa = self.fold((wpa + self.core[pc + wpa].b_number), self.write_limit);
            }
        }

        ira = self.core[pc + rpa];

        if ir.a_mode == Mode::INCREMENT {
            self.core[pip].b_number = (self.core[pip].b_number + 1) % size;
        }

    }
}

#[derive(Clone, Copy, Debug)]
pub enum InitialInstruction {
    Default,
    Random,
    Instruction(Instruction),
}

#[derive(Debug)]
pub struct CoreBuilder {
    core_size: u32,
    initial_instruction: InitialInstruction,
    task_limit: usize,
}

impl CoreBuilder {
    pub fn new() -> Self {
        CoreBuilder {
            core_size: 8192,
            initial_instruction: InitialInstruction::Default,
            task_limit: 64,
        }
    }

    pub fn coresize(&mut self, size: u32) -> &Self {
        self.core_size = size;
        self
    }

    pub fn initial_instruction(&mut self, insn: InitialInstruction) -> &Self {
        self.initial_instruction = insn;
        self
    }

    pub fn task_limit(&mut self, limit: usize) -> &Self {
        self.task_limit = limit;
        self
    }

    pub fn build(&self) -> Core {
        let mut instructions = Vec::<Instruction>::new();
        for _ in 0..self.core_size {
            instructions.push(match self.initial_instruction {
                InitialInstruction::Default => Instruction::default(),
                InitialInstruction::Random => Instruction::random(),
                InitialInstruction::Instruction(insn) => insn,
            })
        }

        Core {
            core: CoreMemory::new(self.core_size, self.initial_instruction),
            warrior: [TaskQueue::new(self.task_limit), TaskQueue::new(self.task_limit)],
            read_limit: 300,
            write_limit: 300,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn task_queue_simple() {
        let mut tq = TaskQueue::new(2);
        tq.queue(1);
        tq.queue(3);
        assert_eq!(tq.next(), Some(1));
        assert_eq!(tq.next(), Some(3));
        assert_eq!(tq.next(), None);
    }

    #[test]
    fn task_queue_limit() {
        let mut tq = TaskQueue::new(3);
        tq.queue(100);
        tq.queue(200);
        tq.queue(300);
        tq.queue(400);

        assert_eq!(tq.next(), Some(100));
        assert_eq!(tq.next(), Some(200));
        assert_eq!(tq.next(), Some(300));
        assert_eq!(tq.next(), None);
    }

    #[test]
    fn task_queue_empty() {
        let mut tq = TaskQueue::new(100);

        assert_eq!(tq.next(), None);
    }

    #[test]
    fn core_mem_size() {
        let core = CoreMemory::new(2, InitialInstruction::Default);
        assert_eq!(core.size(), 2);
    }

    #[test]
    fn core_mem_wrap() {
        let core = CoreMemory::new(2, InitialInstruction::Default);
        assert_eq!(core[0], core[2]);
    }
}
<commit_msg>Drop unused builder code<commit_after>//! ICWS '94 draft
//!

use std::ops::{Index, IndexMut};

// #[derive(Clone, Copy, Debug, Default)]
// pub struct Address(u32);
pub type Address = u32;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Opcode {
    DAT, // terminate process
    MOV, // move from A to B
    ADD, // add A to B, store result in B
    SUB, // subtract A from B, store result in B
    MUL, // multiply A by B, store result in B
    DIV, // divide B by A, store result in B if A <> 0, else terminate
    MOD, // divide B by A, store remainder in B if A <> 0, else terminate
    JMP, // transfer execution to A
    JMZ, // transfer execution to A if B is zero
    JMN, // transfer execution to A if B is non-zero
    DJN, // decrement B, if B is non-zero, transfer execution to A
    CMP, // same as SEQ
    SLT, // skip next instruction if A is less than B
    SPL, // split off process to A
    SEQ, // (*) Skip next instruction if A is equal to B
    SNE, // (*) Skip next instruction if A is not equal to B
    NOP, // (*) No operation
    LDP, // (+) Load P-space cell A into core address B
    STP, // (+) Store A-number into P-space cell B
}

impl Default for Opcode {
    fn default() -> Self {
        Opcode::DAT
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Modifier {
    A,
    B,
    AB,
    BA,
    F,
    X,
    I,
}

impl Default for Modifier {
    fn default() -> Self {
        Modifier::A
    }
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Mode {
    IMMEDIATE, // #
    DIRECT, // $ (Default)
    INDIRECT, // @
    DECREMENT, // <
    INCREMENT, // >
}

impl Default for Mode {
    fn default() -> Self {
        Mode::IMMEDIATE
    }
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Instruction {
    pub opcode: Opcode,
    pub modifier: Modifier,
    pub a_mode: Mode,
    pub a_number: Address,
    pub b_mode: Mode,
    pub b_number: Address,
}

impl Instruction {
    pub fn random() -> Self {
        Instruction::default()  // XXX Need real random implementation
    }
}

#[derive(Clone, Copy, Debug, Default)]
pub struct Warrior(u32);

#[derive(Debug)]
pub struct TaskQueue {
    task_limit: usize,
    task_pointer: Vec<Address>,
}

impl TaskQueue {
    fn new(limit: usize) -> Self {
        TaskQueue {
            task_limit: limit,
            task_pointer: Vec::<Address>::with_capacity(limit),
        }
    }

    pub fn queue(&mut self, addr: Address) {
        if self.task_pointer.len() < self.task_limit {
            self.task_pointer.push(addr);
        }
    }

    pub fn next(&mut self) -> Option<Address> {
        if self.task_pointer.len() > 0 {
            Some(self.task_pointer.remove(0))
        } else {
            None
        }
    }
}

#[derive(Debug)]
pub struct CoreMemory(Address, Vec<Instruction>);

impl Index<Address> for CoreMemory {
    type Output = Instruction;

    fn index<'a>(&'a self, _index: Address) -> &'a Instruction {
        &self.1[(_index % self.0) as usize]
    }
}

impl IndexMut<Address> for CoreMemory {
    fn index_mut<'a>(&'a mut self, _index: Address) -> &'a mut Instruction {
        &mut self.1[(_index % self.0) as usize]
    }
}

impl CoreMemory {
    fn new(size: Address, initial_instruction: InitialInstruction) -> Self {
        let mut instructions = Vec::<Instruction>::new();
        for _ in 0..size {
            instructions.push(match initial_instruction {
                InitialInstruction::Default => Instruction::default(),
                InitialInstruction::Random => Instruction::random(),
                InitialInstruction::Instruction(insn) => insn,
            })
        }

        CoreMemory(size, instructions)
    }

    fn size(&self) -> Address {
        self.0
    }
}

#[derive(Debug)]
pub struct Core {
    core: CoreMemory,
    warrior: [TaskQueue; 2],
    read_limit: Address,
    write_limit: Address,
}

impl Core {
    pub fn queue(&mut self, warrior: usize, task_pointer: Address) {
        self.warrior[warrior].queue(task_pointer)
    }

    fn fold(&self, pointer: Address, limit: Address) -> Address {
        let mut result = pointer % limit;
        if result > limit / 2 {
            result += self.core.size() - limit;
        }
        result
    }

    fn direct(&self, number: Address) -> (Address, Address) {
        (self.fold(number, self.read_limit),
         self.fold(number, self.write_limit))
    }

    fn indirect_pointer(&self, pc: Address, number: Address, limit: Address) -> Address {
        let p = self.fold(number, limit);
        let i = p + self.core[pc + p].b_number;
        self.fold(i, limit)
    }

    fn indirect(&self, pc: Address, number: Address) -> (Address, Address) {
        (self.indirect_pointer(pc, number, self.read_limit),
         self.indirect_pointer(pc, number, self.write_limit))
    }

    pub fn evaluate(&mut self, pc: Address, mode: Mode, number: Address) -> (Address, Address) {
        // let mut rp: Address;
        // let mut wp: Address;
        let rlim = self.read_limit;
        let wlim = self.write_limit;

        match mode {
            Mode::IMMEDIATE => (0, 0),
            Mode::DIRECT => self.direct(number),
            Mode::INDIRECT => self.indirect(pc, number),
            Mode::DECREMENT => (self.fold(number, rlim), self.fold(number, wlim)),
            Mode::INCREMENT => (self.fold(number, rlim), self.fold(number, wlim)),
        }
    }

    pub fn emi94(&mut self, pc: Address) {
        let ir: Instruction;
        let ira: Instruction;
        let irb: Instruction;
        let mut rpa: Address;
        let mut wpa: Address;
        let rpb: Address;
        let wpb: Address;
        let mut pip: Address = 0;
        let size = self.core.size();

        ir = self.core[pc];

        // Evaluate A-operand
        //
        if ir.a_mode == Mode::IMMEDIATE {
            // For instructions with an Immediate A-mode, the Pointer A
            // points to the source of the current instruction.
            rpa = 0;
            wpa = 0;
        } else {
            // For instructions with a Direct A-mode, the Pointer A
            // points to the instruction IR.ANumber away, relative to
            // the Program Counter.
            rpa = self.fold(ir.a_number, self.read_limit);
            wpa = self.fold(ir.a_number, self.write_limit);

            if ir.a_mode != Mode::DIRECT {
                if ir.a_mode == Mode::DECREMENT {
                    self.core[pc + wpa].b_number = (self.core[pc + wpa].b_number + size - 1) % size;
                }

                if ir.a_mode == Mode::INCREMENT {
                    pip = (pc + wpa) % size;
                }

                rpa = self.fold((rpa + self.core[pc + rpa].b_number), self.read_limit);
                wpa = self.fold((wpa + self.core[pc + wpa].b_number), self.write_limit);
            }
        }

        ira = self.core[pc + rpa];

        if ir.a_mode == Mode::INCREMENT {
            self.core[pip].b_number = (self.core[pip].b_number + 1) % size;
        }

    }
}

#[derive(Clone, Copy, Debug)]
pub enum InitialInstruction {
    Default,
    Random,
    Instruction(Instruction),
}

#[derive(Debug)]
pub struct CoreBuilder {
    core_size: u32,
    initial_instruction: InitialInstruction,
    task_limit: usize,
}

impl CoreBuilder {
    pub fn new() -> Self {
        CoreBuilder {
            core_size: 8192,
            initial_instruction: InitialInstruction::Default,
            task_limit: 64,
        }
    }

    pub fn coresize(&mut self, size: u32) -> &Self {
        self.core_size = size;
        self
    }

    pub fn initial_instruction(&mut self, insn: InitialInstruction) -> &Self {
        self.initial_instruction = insn;
        self
    }

    pub fn task_limit(&mut self, limit: usize) -> &Self {
        self.task_limit = limit;
        self
    }

    pub fn build(&self) -> Core {
        Core {
            core: CoreMemory::new(self.core_size, self.initial_instruction),
            warrior: [TaskQueue::new(self.task_limit), TaskQueue::new(self.task_limit)],
            read_limit: 300,
            write_limit: 300,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn task_queue_simple() {
        let mut tq = TaskQueue::new(2);
        tq.queue(1);
        tq.queue(3);
        assert_eq!(tq.next(), Some(1));
        assert_eq!(tq.next(), Some(3));
        assert_eq!(tq.next(), None);
    }

    #[test]
    fn task_queue_limit() {
        let mut tq = TaskQueue::new(3);
        tq.queue(100);
        tq.queue(200);
        tq.queue(300);
        tq.queue(400);

        assert_eq!(tq.next(), Some(100));
        assert_eq!(tq.next(), Some(200));
        assert_eq!(tq.next(), Some(300));
        assert_eq!(tq.next(), None);
    }

    #[test]
    fn task_queue_empty() {
        let mut tq = TaskQueue::new(100);

        assert_eq!(tq.next(), None);
    }

    #[test]
    fn core_mem_size() {
        let core = CoreMemory::new(2, InitialInstruction::Default);
        assert_eq!(core.size(), 2);
    }

    #[test]
    fn core_mem_wrap() {
        let core = CoreMemory::new(2, InitialInstruction::Default);
        assert_eq!(core[0], core[2]);
    }
}
<|endoftext|>


<commit_before>use error::Result;
use token::Token;

pub struct Body;
pub struct Block;
pub struct Macro;
pub struct Trait;
pub struct AnyNode;

pub struct Module {
    // Sub nodes.
    body: Vec<Body>,
    blocks: Vec<Block>,
    macros: Vec<Macro>,
    traits: Vec<Trait>,

    // Attributes.
    file_id: Option<String>, // this must NOT be treated as file name
    index: i32, // TODO: wtf is this
    embedded_templates: Vec<()>, // TODO: should this be here

    // TODO: check usage of things bellow
    display_start: AnyNode,
    display_end: AnyNode,
    constructor_start: AnyNode,
    constructor_end: AnyNode,
    class_end: AnyNode,
}

/// Root Twig AST node.
impl Module {
    pub fn new() -> Module {
        Module {
            body: vec![],
            blocks: vec![],
            macros: vec![],
            traits: vec![],

            file_id: None,
            index: 0,
            embedded_templates: vec![],

            display_start: AnyNode,
            display_end: AnyNode,
            constructor_start: AnyNode,
            constructor_end: AnyNode,
            class_end: AnyNode,
        }
    }

    pub fn from_tokens<'code, I>(tokens: I)
        -> Result<Module>
            where I: IntoIterator<Item=Result<Token<'code>>>
    {
        let mut i = tokens.into_iter();
        i.next();
        Ok(Module::new())
    }
}
<commit_msg>Embeded template.<commit_after>use error::Result;
use token::Token;

pub struct Body;
pub struct Block;
pub struct Macro;
pub struct Trait;
pub struct AnyNode;
pub struct EmbededTemplate; // reference to another module

pub struct Module {
    // Sub nodes.
    body: Vec<Body>,
    blocks: Vec<Block>,
    macros: Vec<Macro>,
    traits: Vec<Trait>,

    // Attributes.
    file_id: Option<String>, // this must NOT be treated as file name
    index: i32, // TODO: wtf is this
    embedded_templates: Vec<EmbededTemplate>,

    // TODO: check usage of things bellow
    display_start: AnyNode,
    display_end: AnyNode,
    constructor_start: AnyNode,
    constructor_end: AnyNode,
    class_end: AnyNode,
}

/// Root Twig AST node.
impl Module {
    pub fn new() -> Module {
        Module {
            body: vec![],
            blocks: vec![],
            macros: vec![],
            traits: vec![],

            file_id: None,
            index: 0,
            embedded_templates: vec![],

            display_start: AnyNode,
            display_end: AnyNode,
            constructor_start: AnyNode,
            constructor_end: AnyNode,
            class_end: AnyNode,
        }
    }

    pub fn from_tokens<'code, I>(tokens: I)
        -> Result<Module>
            where I: IntoIterator<Item=Result<Token<'code>>>
    {
        let mut i = tokens.into_iter();
        i.next();
        Ok(Module::new())
    }
}
<|endoftext|>


<commit_before>//! The nodes.

use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::fmt;

mod comment;
mod text;
mod value;

pub use self::comment::Comment;
pub use self::text::Text;
pub use self::value::Value;

/// Attributes.
pub type Attributes = HashMap<String, Value>;

/// Child nodes.
pub type Children = Vec<Box<dyn Node>>;

/// A node.
pub trait Node: 'static + fmt::Debug + fmt::Display + NodeDefaultHash + NodeClone {
    /// Append a child node.
    fn append<T>(&mut self, _: T)
    where
        Self: Sized,
        T: Node;

    /// Assign an attribute.
    fn assign<T, U>(&mut self, _: T, _: U)
    where
        Self: Sized,
        T: Into<String>,
        U: Into<Value>;
}

#[doc(hidden)]
pub trait NodeClone {
    fn clone(&self) -> Box<dyn Node>;
}

impl<T> NodeClone for T
where
    T: Node + Clone,
{
    #[inline]
    fn clone(&self) -> Box<dyn Node> {
        Box::new(Clone::clone(self))
    }
}

impl Clone for Box<dyn Node> {
    #[inline]
    fn clone(&self) -> Self {
        NodeClone::clone(&**self)
    }
}

#[doc(hidden)]
pub trait NodeDefaultHash {
    /// Get default hash
    fn default_hash(&self, state: &mut DefaultHasher);
}

impl NodeDefaultHash for Box<dyn Node> {
    fn default_hash(&self, state: &mut DefaultHasher) {
        NodeDefaultHash::default_hash(&**self, state)
    }
}

macro_rules! node(
    ($struct_name:ident::$field_name:ident) => (
        impl $struct_name {
            /// Append a node.
            pub fn add<T>(mut self, node: T) -> Self
            where
                T: crate::node::Node,
            {
                crate::node::Node::append(&mut self, node);
                self
            }

            /// Assign an attribute.
            #[inline]
            pub fn set<T, U>(mut self, name: T, value: U) -> Self
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                crate::node::Node::assign(&mut self, name, value);
                self
            }
        }

        impl crate::node::Node for $struct_name {
            #[inline]
            fn append<T>(&mut self, node: T)
            where
                T: crate::node::Node,
            {
                self.$field_name.append(node);
            }

            #[inline]
            fn assign<T, U>(&mut self, name: T, value: U)
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                self.$field_name.assign(name, value);
            }
        }

        impl ::std::fmt::Display for $struct_name {
            #[inline]
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.$field_name.fmt(formatter)
            }
        }
    );
);

pub mod element;
<commit_msg>get_inner added<commit_after>//! The nodes.

use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::fmt;

mod comment;
mod text;
mod value;

pub use self::comment::Comment;
pub use self::text::Text;
pub use self::value::Value;

/// Attributes.
pub type Attributes = HashMap<String, Value>;

/// Child nodes.
pub type Children = Vec<Box<dyn Node>>;

/// A node.
pub trait Node: 'static + fmt::Debug + fmt::Display + NodeDefaultHash + NodeClone {
    /// Append a child node.
    fn append<T>(&mut self, _: T)
    where
        Self: Sized,
        T: Node;

    /// Assign an attribute.
    fn assign<T, U>(&mut self, _: T, _: U)
    where
        Self: Sized,
        T: Into<String>,
        U: Into<Value>;
}

#[doc(hidden)]
pub trait NodeClone {
    fn clone(&self) -> Box<dyn Node>;
}

impl<T> NodeClone for T
where
    T: Node + Clone,
{
    #[inline]
    fn clone(&self) -> Box<dyn Node> {
        Box::new(Clone::clone(self))
    }
}

impl Clone for Box<dyn Node> {
    #[inline]
    fn clone(&self) -> Self {
        NodeClone::clone(&**self)
    }
}

#[doc(hidden)]
pub trait NodeDefaultHash {
    /// Get default hash
    fn default_hash(&self, state: &mut DefaultHasher);
}

impl NodeDefaultHash for Box<dyn Node> {
    fn default_hash(&self, state: &mut DefaultHasher) {
        NodeDefaultHash::default_hash(&**self, state)
    }
}

macro_rules! node(
    ($struct_name:ident::$field_name:ident) => (
        impl $struct_name {
            /// Append a node.
            pub fn add<T>(mut self, node: T) -> Self
            where
                T: crate::node::Node,
            {
                crate::node::Node::append(&mut self, node);
                self
            }

            /// Assign an attribute.
            #[inline]
            pub fn set<T, U>(mut self, name: T, value: U) -> Self
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                crate::node::Node::assign(&mut self, name, value);
                self
            }

            pub fn get_inner(&self) -> &Element {
                &self.inner
            }
        }

        impl crate::node::Node for $struct_name {
            #[inline]
            fn append<T>(&mut self, node: T)
            where
                T: crate::node::Node,
            {
                self.$field_name.append(node);
            }

            #[inline]
            fn assign<T, U>(&mut self, name: T, value: U)
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                self.$field_name.assign(name, value);
            }
        }

        impl ::std::fmt::Display for $struct_name {
            #[inline]
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.$field_name.fmt(formatter)
            }
        }
    );
);

pub mod element;
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]

use std::io::{Reader, IoResult};

#[repr(u8)]
#[deriving(Show, PartialEq, Eq, FromPrimitive)]
pub enum KnownEntityKind {
    File = b'0',
    Dir  = b'1',
    CsoQuery = b'2',
    Error = b'3',
    MacBinHex = b'4',
    DosBin = b'5',
    Uuenc = b'6',
    SearchQuery = b'7',
    Telnet = b'8',
    Binary = b'9',
    RedundantServer = b'+',
    Tn3270 = b'T',
    Gif = b'g',
    Html = b'h',
    Info = b'i',
    Image = b'I'
}

#[deriving(Show, PartialEq, Eq)]
pub enum EntityKind {
    Known(KnownEntityKind),
    Unknown(u8)
}

impl EntityKind {
    fn from_byte(byte: u8) -> EntityKind {
        match FromPrimitive::from_u8(byte) {
            None => EntityKind::Unknown(byte),
            Some(item) => EntityKind::Known(item)
        }
    }
}

#[deriving(Show, PartialEq, Eq)]
pub struct DirEntity {
    pub kind: EntityKind,
    // FIXME: RFC 1436 allows (but does not recommend) Latin1 for this field, so
    // this should support that
    pub display: String,
    // Might be 0-length.
    pub selector: Vec<u8>,
    pub host: String,
    pub port: u16
}

impl DirEntity {
    pub fn is_dir(&self) -> bool {
        match self.kind {
            EntityKind::Known(KnownEntityKind::Dir) => true,
            _ => false
        }
    }
}

/// Parses the Gopher protocol.
pub struct Parser<'a> {
    reader: Box<Reader + 'a>,
    lookahead: Option<u8>,
    byte: u8,
}

// utility function to convert ASCII bytes to a String
fn bytes_to_string(bytes: &[u8]) -> String {
    // FIXME: use latin1 or something
    String::from_utf8_lossy(bytes).into_string()
}

impl<'a> Parser<'a> {
    pub fn new<R: Reader + 'a>(reader: R) -> IoResult<Parser<'a>> {
        let mut parser = Parser {
            reader: box reader as Box<Reader>,
            lookahead: None,
            byte: 0,
        };
        try!(parser.bump());
        Ok(parser)
    }

    fn parse_direntity(&mut self) -> IoResult<DirEntity> {
        use std::str::FromStr;

        let kind = self.byte;
        try!(self.bump());
        let display = bytes_to_string(try!(self.parse_field()).as_slice());
        let selector = try!(self.parse_field());
        let host = bytes_to_string(try!(self.parse_field()).as_slice());
        let port = bytes_to_string(try!(self.parse_field()).as_slice());

        // Skip over any other remaining tab-delimited fields
        loop {
            if self.byte == b'\r' && try!(self.peek()) == b'\n' {
                try!(self.bump()); try!(self.bump());
                break;
            }
            try!(self.bump());
        }
        Ok(DirEntity {
            kind: EntityKind::from_byte(kind),
            display: display.into_string(),
            selector: selector,
            host: host.into_string(),
            port: FromStr::from_str(port.as_slice()).unwrap() // FIXME
        })
    }

    /// Parses a Gopher 'menu' listing into `DirEntity`s.
    pub fn parse_menu(&mut self) -> IoResult<Vec<DirEntity>> {
        let mut out = Vec::with_capacity(16);
        loop {
            if self.byte == b'.' {
                break;
            }
            out.push(try!(self.parse_direntity()));
        }
        Ok(out)
    }

    // Parses one tab-delimeted field
    fn parse_field(&mut self) -> IoResult<Vec<u8>> {
        let mut out = Vec::with_capacity(32);
        loop {
            let byte = self.byte;
            if byte == b'\t' {
                try!(self.bump());
                break;
            } else if byte == b'\r' {
                if try!(self.peek()) == b'\n' {
                    break;
                } else {
                    out.push(byte);
                }
            } else {
                out.push(byte);
            }
            try!(self.bump());
        }
        out.shrink_to_fit();
        Ok(out)
    }

    fn peek(&mut self) -> IoResult<u8> {
        match self.lookahead {
            Some(byte) => Ok(byte),
            None => {
                let byte = try!(self.reader.read_byte());
                self.lookahead = Some(byte);
                Ok(byte)
            }
        }
    }

    fn bump(&mut self) -> IoResult<()> {
        self.byte = match self.lookahead.take() {
            Some(byte) => byte,
            None => try!(self.reader.read_byte())
        };
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::{DirEntity, EntityKind, KnownEntityKind, Parser};
    use std::io::BufReader;

    fn fixture(bytes: &[u8]) -> Parser {
        Parser::new(BufReader::new(bytes)).unwrap()
    }

    const DATA: &'static [u8] = b"\
    0About internet Gopher\tStuff:About us\trawBits.micro.umn.edu\t70\r\n\
    1Around University of Minnesota\tZ,5692,AUM\tunderdog.micro.umn.edu\t70\r\n\
    1Microcomputer News & Prices\tPrices/\tpserver.bookstore.umn.edu\t70\r\n\
    1Courses, Schedules, Calendars\t\tevents.ais.umn.edu\t9120\r\n\
    1Student-Staff Directories\t\tuinfo.ais.umn.edu\t70\r\n\
    1Departmental Publications\tStuff:DP:\trawBits.micro.umn.edu\t70\r\n\
    .";

    #[test]
    fn test_field() {
        let line = b"1Courses, Schedules, Calendars\t\tevents.ais.umn.edu\t9120\r\n";
        let mut parser = fixture(line);

        assert_eq!(parser.parse_field(), Ok(b"1Courses, Schedules, Calendars".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"events.ais.umn.edu".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"9120".to_vec()));
    }

    #[test]
    fn test_direntity() {
        let mut parser = fixture(DATA);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::File),
            display: "About internet Gopher".into_string(),
            selector: b"Stuff:About us".to_vec(),
            host: "rawBits.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(parser.parse_direntity(), Ok(item));

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::Dir),
            display: "Around University of Minnesota".into_string(),
            selector: b"Z,5692,AUM".to_vec(),
            host: "underdog.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(parser.parse_direntity(), Ok(item));
    }

    #[test]
    fn test_menu() {
        let mut parser = fixture(DATA);

        let items = parser.parse_menu().unwrap();
        assert_eq!(items.len(), 6);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::File),
            display: "About internet Gopher".into_string(),
            selector: b"Stuff:About us".to_vec(),
            host: "rawBits.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(items[0], item);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::Dir),
            display: "Around University of Minnesota".into_string(),
            selector: b"Z,5692,AUM".to_vec(),
            host: "underdog.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(items[1], item);
    }
}

<commit_msg>Opt-in Copy<commit_after>#![allow(dead_code, unused_variables)]

use std::io::{Reader, IoResult};

#[repr(u8)]
#[deriving(Copy, Show, PartialEq, Eq, FromPrimitive)]
pub enum KnownEntityKind {
    File = b'0',
    Dir  = b'1',
    CsoQuery = b'2',
    Error = b'3',
    MacBinHex = b'4',
    DosBin = b'5',
    Uuenc = b'6',
    SearchQuery = b'7',
    Telnet = b'8',
    Binary = b'9',
    RedundantServer = b'+',
    Tn3270 = b'T',
    Gif = b'g',
    Html = b'h',
    Info = b'i',
    Image = b'I'
}

#[deriving(Copy, Show, PartialEq, Eq)]
pub enum EntityKind {
    Known(KnownEntityKind),
    Unknown(u8)
}

impl EntityKind {
    fn from_byte(byte: u8) -> EntityKind {
        match FromPrimitive::from_u8(byte) {
            None => EntityKind::Unknown(byte),
            Some(item) => EntityKind::Known(item)
        }
    }
}

#[deriving(Show, PartialEq, Eq)]
pub struct DirEntity {
    pub kind: EntityKind,
    // FIXME: RFC 1436 allows (but does not recommend) Latin1 for this field, so
    // this should support that
    pub display: String,
    // Might be 0-length.
    pub selector: Vec<u8>,
    pub host: String,
    pub port: u16
}

impl DirEntity {
    pub fn is_dir(&self) -> bool {
        match self.kind {
            EntityKind::Known(KnownEntityKind::Dir) => true,
            _ => false
        }
    }
}

/// Parses the Gopher protocol.
pub struct Parser<'a> {
    reader: Box<Reader + 'a>,
    lookahead: Option<u8>,
    byte: u8,
}

// utility function to convert ASCII bytes to a String
fn bytes_to_string(bytes: &[u8]) -> String {
    // FIXME: use latin1 or something
    String::from_utf8_lossy(bytes).into_string()
}

impl<'a> Parser<'a> {
    pub fn new<R: Reader + 'a>(reader: R) -> IoResult<Parser<'a>> {
        let mut parser = Parser {
            reader: box reader as Box<Reader>,
            lookahead: None,
            byte: 0,
        };
        try!(parser.bump());
        Ok(parser)
    }

    fn parse_direntity(&mut self) -> IoResult<DirEntity> {
        use std::str::FromStr;

        let kind = self.byte;
        try!(self.bump());
        let display = bytes_to_string(try!(self.parse_field()).as_slice());
        let selector = try!(self.parse_field());
        let host = bytes_to_string(try!(self.parse_field()).as_slice());
        let port = bytes_to_string(try!(self.parse_field()).as_slice());

        // Skip over any other remaining tab-delimited fields
        loop {
            if self.byte == b'\r' && try!(self.peek()) == b'\n' {
                try!(self.bump()); try!(self.bump());
                break;
            }
            try!(self.bump());
        }
        Ok(DirEntity {
            kind: EntityKind::from_byte(kind),
            display: display.into_string(),
            selector: selector,
            host: host.into_string(),
            port: FromStr::from_str(port.as_slice()).unwrap() // FIXME
        })
    }

    /// Parses a Gopher 'menu' listing into `DirEntity`s.
    pub fn parse_menu(&mut self) -> IoResult<Vec<DirEntity>> {
        let mut out = Vec::with_capacity(16);
        loop {
            if self.byte == b'.' {
                break;
            }
            out.push(try!(self.parse_direntity()));
        }
        Ok(out)
    }

    // Parses one tab-delimeted field
    fn parse_field(&mut self) -> IoResult<Vec<u8>> {
        let mut out = Vec::with_capacity(32);
        loop {
            let byte = self.byte;
            if byte == b'\t' {
                try!(self.bump());
                break;
            } else if byte == b'\r' {
                if try!(self.peek()) == b'\n' {
                    break;
                } else {
                    out.push(byte);
                }
            } else {
                out.push(byte);
            }
            try!(self.bump());
        }
        out.shrink_to_fit();
        Ok(out)
    }

    fn peek(&mut self) -> IoResult<u8> {
        match self.lookahead {
            Some(byte) => Ok(byte),
            None => {
                let byte = try!(self.reader.read_byte());
                self.lookahead = Some(byte);
                Ok(byte)
            }
        }
    }

    fn bump(&mut self) -> IoResult<()> {
        self.byte = match self.lookahead.take() {
            Some(byte) => byte,
            None => try!(self.reader.read_byte())
        };
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::{DirEntity, EntityKind, KnownEntityKind, Parser};
    use std::io::BufReader;

    fn fixture(bytes: &[u8]) -> Parser {
        Parser::new(BufReader::new(bytes)).unwrap()
    }

    const DATA: &'static [u8] = b"\
    0About internet Gopher\tStuff:About us\trawBits.micro.umn.edu\t70\r\n\
    1Around University of Minnesota\tZ,5692,AUM\tunderdog.micro.umn.edu\t70\r\n\
    1Microcomputer News & Prices\tPrices/\tpserver.bookstore.umn.edu\t70\r\n\
    1Courses, Schedules, Calendars\t\tevents.ais.umn.edu\t9120\r\n\
    1Student-Staff Directories\t\tuinfo.ais.umn.edu\t70\r\n\
    1Departmental Publications\tStuff:DP:\trawBits.micro.umn.edu\t70\r\n\
    .";

    #[test]
    fn test_field() {
        let line = b"1Courses, Schedules, Calendars\t\tevents.ais.umn.edu\t9120\r\n";
        let mut parser = fixture(line);

        assert_eq!(parser.parse_field(), Ok(b"1Courses, Schedules, Calendars".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"events.ais.umn.edu".to_vec()));
        assert_eq!(parser.parse_field(), Ok(b"9120".to_vec()));
    }

    #[test]
    fn test_direntity() {
        let mut parser = fixture(DATA);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::File),
            display: "About internet Gopher".into_string(),
            selector: b"Stuff:About us".to_vec(),
            host: "rawBits.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(parser.parse_direntity(), Ok(item));

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::Dir),
            display: "Around University of Minnesota".into_string(),
            selector: b"Z,5692,AUM".to_vec(),
            host: "underdog.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(parser.parse_direntity(), Ok(item));
    }

    #[test]
    fn test_menu() {
        let mut parser = fixture(DATA);

        let items = parser.parse_menu().unwrap();
        assert_eq!(items.len(), 6);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::File),
            display: "About internet Gopher".into_string(),
            selector: b"Stuff:About us".to_vec(),
            host: "rawBits.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(items[0], item);

        let item = DirEntity {
            kind: EntityKind::Known(KnownEntityKind::Dir),
            display: "Around University of Minnesota".into_string(),
            selector: b"Z,5692,AUM".to_vec(),
            host: "underdog.micro.umn.edu".into_string(),
            port: 70
        };
        assert_eq!(items[1], item);
    }
}

<|endoftext|>


<commit_before>use tokio_core::reactor::Handle;
use futures::future::{ok, err, Future};
use futures::Sink;
use websocket::{ClientBuilder, Message};
use websocket::client::async;

const URL: &'static str = "wss://api2.poloniex.com:443";

type Client = async::ClientNew<async::TlsStream<async::TcpStream>>;

// subscribe to trading pair ticker updates
pub fn subscribe(pairs: Vec<String>, handle: &Handle) -> Client {
	let client_future = ClientBuilder::new(URL)
		.unwrap()
		.async_connect_secure(None, handle)
		.and_then(move |(mut client, hdr)| {
			for pair in pairs.iter() {
				let msg = message_subscribe(pair).into();
				match client.start_send(msg) {
					Err(status) => return err(status),
					_ => ()
				};
			}
			match client.poll_complete() {
				Err(status) => return err(status),
				_ => return ok((client, hdr))
			}
    });
		Box::new(client_future)
}

fn message_subscribe(channel: &str) -> Message {
	Message::text(format!("{{ command: \"subscribe\", channel: {} }}", channel))
}<commit_msg>fix subscription command<commit_after>use tokio_core::reactor::Handle;
use futures::future::{ok, err, Future};
use futures::Sink;
use websocket::{ClientBuilder, Message};
use websocket::client::async;

const URL: &'static str = "wss://api2.poloniex.com:443";

type Client = async::ClientNew<async::TlsStream<async::TcpStream>>;

// subscribe to trading pair ticker updates
pub fn subscribe(pairs: Vec<String>, handle: &Handle) -> Client {
	let client_future = ClientBuilder::new(URL)
		.unwrap()
		.async_connect_secure(None, handle)
		.and_then(move |(mut client, hdr)| {
			for pair in pairs.iter() {
				let msg = message_subscribe(pair).into();
				match client.start_send(msg) {
					Err(status) => return err(status),
					_ => ()
				};
			}
			match client.poll_complete() {
				Err(status) => return err(status),
				_ => return ok((client, hdr))
			}
    });
		Box::new(client_future)
}

fn message_subscribe(channel: &str) -> Message {
	Message::text(format!("{{ \"command\": \"subscribe\", \"channel\": \"{}\" }}", channel))
}<|endoftext|>


<commit_before>extern crate core;

use std::mem;
use std::fmt::Debug;
use std::vec::Vec;
use std::boxed::Box;
use std::collections::HashMap;
use std::collections::hash_map::Values;
use self::core::ops::RangeFull;

#[derive(Debug)]
pub struct QuadTree<S, T: Debug> {
    root: Node<S, T>
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> QuadTree<S, T> {
    pub fn new(span: S) -> QuadTree<S, T> {
        return QuadTree { root: Node::new(span) };
    }

    pub fn add(&mut self, t: T) {
        self.ensure_contains(&t);
        self.root.add(t);
    }

    pub fn print(&self) {
        print!("root: ");
        self.root.print(1);
    }

    fn ensure_contains(&mut self, t: &T) {
        while !self.root.span.contains(&t) {
            let new_span = self.root.span.expand(&self.root.span.dir_of(&t).unwrap());
            let mut new_root = Node::new(new_span);
            for (dir, span) in new_root.span.split() {
                if span == self.root.span {
                    mem::swap(&mut self.root, &mut new_root);
                    self.root.size = new_root.size;
                    if new_root.size > 0 {
                        self.root.children.insert(dir.clone(), Child::Inner(Box::new(new_root)));
                    }
                    break;
                }
                // unreachable!();
            }
        }
    }

    pub fn scan(&self, span: &S) -> Vec<T> {
        return self.root.scan(span);
    }

    pub fn contains(&self, t: &T) -> bool {
        return self.root.contains(t);
    }

    pub fn size(&self) -> usize {
        return self.root.size;
    }

    pub fn size_actual(&self) -> usize {
        return self.root.size();
    }

    pub fn remove(&mut self, t: &T) -> usize {
        return self.root.remove(t);
    }

    /// Not implemented!
    pub fn nearest<F>(&self, t: &T, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest_n<F>(&self, t: &T, n: i32, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn smallest_span(&self) -> S {
        unimplemented!();
    }

    // removes all elements equal to 'old' and adds new element 'new'
    // returns number of elements removed
    // efficient on small changes in element
    pub fn replace_with(&mut self, old: &T, new: T) -> usize {
        self.ensure_contains(&new);
        return self.root.replace_with(old, new);
    }

    /// Not implemented!
    pub fn rebalance(&self) {
        unimplemented!();
    }
}

#[derive(Debug)]
struct Node<S, T: Sized + Debug> {
    span: S,
    children: HashMap<Dir, Child<S, T>>,
    size: usize     // number of elements contained in the span
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> Node<S, T> {

    fn new(span: S) -> Node<S, T> {
        return Node {
            span: span,
            children: HashMap::new(),
            size: 0
        };
    }

    fn add(&mut self, t: T) {
        self.size += 1;
        let mut sub_spans = self.span.split();
        for (key, span) in sub_spans.drain() {
            if span.contains(&t) {
                let old_child = self.children.remove(&key);
                let new_child = self.new_child(span, old_child, t);
                self.children.insert(key, new_child);
                return;
            }
        }
        unreachable!("Tried to add {:?} to node with span {:?}", t, self.span);
    }

    fn new_child(&self, span: S, child: Option<Child<S, T>>, t: T) -> Child<S, T> {
        return match child {
            None => Child::Leaf(span, vec![t]),
            Some(c) => {
                match c {
                    Child::Leaf(span, mut v) => {
                        if v.len() > 1 && self.span.can_split() {
                            let mut new_node = Node::new(span);
                            for old_t in v.drain(RangeFull) {
                                new_node.add(old_t);
                            }
                            new_node.add(t);
                            Child::Inner(Box::new(new_node))
                        } else {
                            v.push(t);
                            Child::Leaf(span, v)
                        }
                    },
                    Child::Inner(mut b) => {
                        b.as_mut().add(t);
                        Child::Inner(b)
                    }
                }
            }
        };
    }

    fn print(&self, depth: usize) {
        println!("Node ({}) {:?}", self.size, self.span);
        let mut indent = String::new();
        for _ in 0..depth {
            indent.push_str(".   ");
        }
        for (key, child) in self.children.iter() {
            print!("{}{:?}: ", indent, key);
            match child {
                &Child::Inner(ref b) => b.as_ref().print(depth + 1),
                &Child::Leaf(_, ref v) => println!("{:?}", v),
            };
        }
    }

    fn scan(&self, span: &S) -> Vec<T> {
        if !self.span.overlaps(span) {
            return Vec::new();
        }
        let mut result: Vec<T> = Vec::new();
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    for t in v.iter().filter(|t| span.contains(&t)) {
                        result.push(t.clone());
                    }
                },
                &Child::Inner(ref b) => {
                    for t in b.as_ref().scan(span) {
                        result.push(t.clone());
                    }
                }
            };
        }
        return result;
    }

    fn contains(&self, t: &T) -> bool {
        if !self.span.contains(t) {
            return false;
        }
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    if v.contains(t) {
                        return true;
                    }
                },
                &Child::Inner(ref b) => {
                    if b.as_ref().contains(t) {
                        return true;
                    }
                }
            };
        }
        return false;
    }

    fn remove(&mut self, t: &T) -> usize {
        if !self.span.contains(t) {
            return 0;
        }

        for (_, child) in self.children.iter_mut() {
            let removed = match child {
                &mut Child::Leaf(_, ref mut v) => {
                    let mut i = 0;
                    let mut removed = 0;
                    while i < v.len() {
                        if v.get(i).unwrap() == t {
                            v.remove(i);
                            removed += 1;
                        } else {
                            i += 1;
                        }
                    }
                    removed
                },
                &mut Child::Inner(ref mut b) => {
                    b.as_mut().remove(t)
                }
            };
            if removed > 0 {
                return removed;
            }
        }
        return 0;
    }

    fn size(&self) -> usize {
        let mut result = 0;
        for (_, child) in &self.children {
            result += match child {
                &Child::Leaf(_, ref v) => v.len(),
                &Child::Inner(ref b) => b.as_ref().size()
            }
        };
        return result;
    }

    fn replace_with(&mut self, old: &T, new: T) -> usize {

        for (_, child) in self.children.iter_mut() {
            match child {
                &mut Child::Inner(ref mut b) => {
                    if b.as_ref().span.contains(old) && b.as_ref().span.contains(&new) {
                        return b.as_mut().replace_with(old, new);
                    }
                },
                _ => {}
            };
        }

        self.add(new);
        return self.remove(old);
    }
}

#[derive(Debug)]
enum Child<S, T: Sized + Debug> {
    Inner(Box<Node<S, T>>),
    Leaf(S, Vec<T>)
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Dir { N, S, E, W, NE, NW, SE, SW }

pub trait Span<S: Span<S, T>, T>: Clone + Eq + PartialEq {

    /// The direction of `t` in relation to `self`, or `None` if
    /// `self` `contains` `t`.
    fn dir_of(&self, t: &T) -> Option<Dir>;

    /// The span of equal size to the north of `self`.
    fn north_span(&self) -> S;

    /// The span of equal size to the south of `self`.
    fn south_span(&self) -> S;

    /// The span of equal size to the east of `self`.
    fn east_span(&self) -> S;

    /// The span of equal size to the west of `self`.
    fn west_span(&self) -> S;

    /// Returns the `S` in the given direction.
    fn span_at(&self, dir: &Dir) -> S {
        return match dir {
            &Dir::N => self.north_span(),
            &Dir::S => self.south_span(),
            &Dir::E => self.east_span(),
            &Dir::W => self.west_span(),
            &Dir::NE => self.north_span().east_span(),
            &Dir::NW => self.north_span().west_span(),
            &Dir::SE => self.south_span().east_span(),
            &Dir::SW => self.south_span().west_span()
        };
    }

    /// Returns a new `S` with double the size of `self` expanded
    /// in the direction `dir`.
    fn expand(&self, dir: &Dir) -> S;

    /// Returns a partition of `self` with four blocks.
    /// The partition of the result of `expand` must contain the
    /// original `S`.
    fn split(&self) -> HashMap<Dir, S>;

    /// Returns true if the span can be split, e.g., if the span is
    /// represented by integers and the width and height is larger than `1`.
    fn can_split(&self) -> bool;

    /// Not implemented!
    fn merge(spans: Values<Dir, S>) -> S;

    /// Returns `true` if `self` overlaps with `other`, otherwise `false`.
    /// Used for `QuadTree.scan`.
    fn overlaps(&self, other: &S) -> bool;

    /// Returns `true` if `self` contains `t`, otherwise `false`.
    fn contains(&self, t: &T) -> bool {
        return self.dir_of(t) == None;
    }
}
<commit_msg>added inefficient elements operation<commit_after>extern crate core;

use std::mem;
use std::fmt::Debug;
use std::vec::Vec;
use std::boxed::Box;
use std::collections::HashMap;
use std::collections::hash_map::Values;
use self::core::ops::RangeFull;

#[derive(Debug)]
pub struct QuadTree<S, T: Debug> {
    root: Node<S, T>
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> QuadTree<S, T> {
    pub fn new(span: S) -> QuadTree<S, T> {
        return QuadTree { root: Node::new(span) };
    }

    pub fn add(&mut self, t: T) {
        self.ensure_contains(&t);
        self.root.add(t);
    }

    pub fn print(&self) {
        print!("root: ");
        self.root.print(1);
    }

    fn ensure_contains(&mut self, t: &T) {
        while !self.root.span.contains(&t) {
            let new_span = self.root.span.expand(&self.root.span.dir_of(&t).unwrap());
            let mut new_root = Node::new(new_span);
            for (dir, span) in new_root.span.split() {
                if span == self.root.span {
                    mem::swap(&mut self.root, &mut new_root);
                    self.root.size = new_root.size;
                    if new_root.size > 0 {
                        self.root.children.insert(dir.clone(), Child::Inner(Box::new(new_root)));
                    }
                    break;
                }
                // unreachable!();
            }
        }
    }

    pub fn scan(&self, span: &S) -> Vec<T> {
        return self.root.scan(span);
    }

    pub fn contains(&self, t: &T) -> bool {
        return self.root.contains(t);
    }

    pub fn size(&self) -> usize {
        return self.root.size;
    }

    pub fn size_actual(&self) -> usize {
        return self.root.size();
    }

    pub fn remove(&mut self, t: &T) -> usize {
        return self.root.remove(t);
    }

    pub fn elements(&self) -> Vec<T> {
        return self.root.elements();
    }

    /// Not implemented!
    pub fn nearest<F>(&self, t: &T, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest_n<F>(&self, t: &T, n: i32, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn smallest_span(&self) -> S {
        unimplemented!();
    }

    // removes all elements equal to 'old' and adds new element 'new'
    // returns number of elements removed
    // efficient on small changes in element
    pub fn replace_with(&mut self, old: &T, new: T) -> usize {
        self.ensure_contains(&new);
        return self.root.replace_with(old, new);
    }

    /// Not implemented!
    pub fn rebalance(&self) {
        unimplemented!();
    }
}

#[derive(Debug)]
struct Node<S, T: Sized + Debug> {
    span: S,
    children: HashMap<Dir, Child<S, T>>,
    size: usize     // number of elements contained in the span
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> Node<S, T> {

    fn new(span: S) -> Node<S, T> {
        return Node {
            span: span,
            children: HashMap::new(),
            size: 0
        };
    }

    fn add(&mut self, t: T) {
        self.size += 1;
        let mut sub_spans = self.span.split();
        for (key, span) in sub_spans.drain() {
            if span.contains(&t) {
                let old_child = self.children.remove(&key);
                let new_child = self.new_child(span, old_child, t);
                self.children.insert(key, new_child);
                return;
            }
        }
        unreachable!("Tried to add {:?} to node with span {:?}", t, self.span);
    }

    fn new_child(&self, span: S, child: Option<Child<S, T>>, t: T) -> Child<S, T> {
        return match child {
            None => Child::Leaf(span, vec![t]),
            Some(c) => {
                match c {
                    Child::Leaf(span, mut v) => {
                        if v.len() > 1 && self.span.can_split() {
                            let mut new_node = Node::new(span);
                            for old_t in v.drain(RangeFull) {
                                new_node.add(old_t);
                            }
                            new_node.add(t);
                            Child::Inner(Box::new(new_node))
                        } else {
                            v.push(t);
                            Child::Leaf(span, v)
                        }
                    },
                    Child::Inner(mut b) => {
                        b.as_mut().add(t);
                        Child::Inner(b)
                    }
                }
            }
        };
    }

    fn print(&self, depth: usize) {
        println!("Node ({}) {:?}", self.size, self.span);
        let mut indent = String::new();
        for _ in 0..depth {
            indent.push_str(".   ");
        }
        for (key, child) in self.children.iter() {
            print!("{}{:?}: ", indent, key);
            match child {
                &Child::Inner(ref b) => b.as_ref().print(depth + 1),
                &Child::Leaf(_, ref v) => println!("{:?}", v),
            };
        }
    }

    fn scan(&self, span: &S) -> Vec<T> {
        if !self.span.overlaps(span) {
            return Vec::new();
        }
        let mut result: Vec<T> = Vec::new();
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    for t in v.iter().filter(|t| span.contains(&t)) {
                        result.push(t.clone());
                    }
                },
                &Child::Inner(ref b) => {
                    for t in b.as_ref().scan(span) {
                        result.push(t.clone());
                    }
                }
            };
        }
        return result;
    }

    fn contains(&self, t: &T) -> bool {
        if !self.span.contains(t) {
            return false;
        }
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    if v.contains(t) {
                        return true;
                    }
                },
                &Child::Inner(ref b) => {
                    if b.as_ref().contains(t) {
                        return true;
                    }
                }
            };
        }
        return false;
    }

    fn remove(&mut self, t: &T) -> usize {
        if !self.span.contains(t) {
            return 0;
        }

        for (_, child) in self.children.iter_mut() {
            let removed = match child {
                &mut Child::Leaf(_, ref mut v) => {
                    let mut i = 0;
                    let mut removed = 0;
                    while i < v.len() {
                        if v.get(i).unwrap() == t {
                            v.remove(i);
                            removed += 1;
                        } else {
                            i += 1;
                        }
                    }
                    removed
                },
                &mut Child::Inner(ref mut b) => {
                    b.as_mut().remove(t)
                }
            };
            if removed > 0 {
                return removed;
            }
        }
        return 0;
    }

    pub fn elements(&self) -> Vec<T> {
        let mut result = Vec::with_capacity(self.size);
        for child in self.children.values() {
            match child {
                &Child::Leaf(_, ref v) => {
                    for elem in v {
                        result.push(elem.clone());
                    }
                },
                &Child::Inner(ref b) => {
                    for elem in b.as_ref().elements() {
                        result.push(elem);
                    }
                }
            };
        }
        return result;
    }

    fn size(&self) -> usize {
        let mut result = 0;
        for (_, child) in &self.children {
            result += match child {
                &Child::Leaf(_, ref v) => v.len(),
                &Child::Inner(ref b) => b.as_ref().size()
            }
        };
        return result;
    }

    fn replace_with(&mut self, old: &T, new: T) -> usize {

        for (_, child) in self.children.iter_mut() {
            match child {
                &mut Child::Inner(ref mut b) => {
                    if b.as_ref().span.contains(old) && b.as_ref().span.contains(&new) {
                        return b.as_mut().replace_with(old, new);
                    }
                },
                _ => {}
            };
        }

        self.add(new);
        return self.remove(old);
    }
}

#[derive(Debug)]
enum Child<S, T: Sized + Debug> {
    Inner(Box<Node<S, T>>),
    Leaf(S, Vec<T>)
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Dir { N, S, E, W, NE, NW, SE, SW }

pub trait Span<S: Span<S, T>, T>: Clone + Eq + PartialEq {

    /// The direction of `t` in relation to `self`, or `None` if
    /// `self` `contains` `t`.
    fn dir_of(&self, t: &T) -> Option<Dir>;

    /// The span of equal size to the north of `self`.
    fn north_span(&self) -> S;

    /// The span of equal size to the south of `self`.
    fn south_span(&self) -> S;

    /// The span of equal size to the east of `self`.
    fn east_span(&self) -> S;

    /// The span of equal size to the west of `self`.
    fn west_span(&self) -> S;

    /// Returns the `S` in the given direction.
    fn span_at(&self, dir: &Dir) -> S {
        return match dir {
            &Dir::N => self.north_span(),
            &Dir::S => self.south_span(),
            &Dir::E => self.east_span(),
            &Dir::W => self.west_span(),
            &Dir::NE => self.north_span().east_span(),
            &Dir::NW => self.north_span().west_span(),
            &Dir::SE => self.south_span().east_span(),
            &Dir::SW => self.south_span().west_span()
        };
    }

    /// Returns a new `S` with double the size of `self` expanded
    /// in the direction `dir`.
    fn expand(&self, dir: &Dir) -> S;

    /// Returns a partition of `self` with four blocks.
    /// The partition of the result of `expand` must contain the
    /// original `S`.
    fn split(&self) -> HashMap<Dir, S>;

    /// Returns true if the span can be split, e.g., if the span is
    /// represented by integers and the width and height is larger than `1`.
    fn can_split(&self) -> bool;

    /// Not implemented!
    fn merge(spans: Values<Dir, S>) -> S;

    /// Returns `true` if `self` overlaps with `other`, otherwise `false`.
    /// Used for `QuadTree.scan`.
    fn overlaps(&self, other: &S) -> bool;

    /// Returns `true` if `self` contains `t`, otherwise `false`.
    fn contains(&self, t: &T) -> bool {
        return self.dir_of(t) == None;
    }
}
<|endoftext|>