<commit_before>#![feature(macro_rules, globs)]

extern crate conduit;
extern crate conduit_middleware = "conduit-middleware";
extern crate cookie;
extern crate serialize;
#[cfg(test)] extern crate test = "conduit-test";

use std::fmt::Show;
use conduit::{Request, Response};
use cookie::{CookieJar, Cookie};

pub use session::{RequestSession, SessionMiddleware};

mod session;

pub struct Middleware {
    key: Vec<u8>,
}

impl Middleware {
    pub fn new(key: &[u8]) -> Middleware {
        Middleware { key: key.to_vec() }
    }
}

impl conduit_middleware::Middleware for Middleware {
    fn before(&self, req: &mut Request) -> Result<(), Box<Show + 'static>> {
        let jar = {
            let headers = req.headers();
            let mut jar = CookieJar::new(self.key.as_slice());
            match headers.find("Cookie") {
                Some(cookies) => {
                    for cookie in cookies.iter() {
                        match Cookie::parse(*cookie) {
                            Ok(c) => jar.add_original(c),
                            Err(..) => {}
                        }
                    }
                }
                None => {}
            }
            jar
        };
        req.mut_extensions().insert(jar);
        Ok(())
    }

    fn after(&self, req: &mut Request, res: Result<Response, Box<Show + 'static>>)
        -> Result<Response, Box<Show + 'static>>
    {
        let mut res = try!(res);
        {
            let jar = req.cookies();
            let cookies = res.headers.find_or_insert("Set-Cookie".to_string(),
                                                     Vec::new());
            for delta in jar.delta().move_iter() {
                cookies.push(delta);
            }
        }
        Ok(res)
    }
}

pub trait RequestCookies<'a> {
    fn cookies(self) -> &'a CookieJar<'static>;
}

impl<'a> RequestCookies<'a> for &'a Request + 'a {
    fn cookies(self) -> &'a CookieJar<'static> {
        self.extensions().find::<CookieJar<'static>>()
            .expect("Missing cookie jar")
    }
}

#[cfg(test)]
mod tests {

    use conduit::{Request, Response, Handler, Post};
    use conduit_middleware::MiddlewareBuilder;
    use cookie::Cookie;
    use test::MockRequest;
    use std::collections::HashMap;
    use std::io::MemReader;

    use super::{RequestCookies, Middleware};

    #[test]
    fn request_headers() {
        let mut req = MockRequest::new(Post, "/articles");
        req.header("Cookie", "foo=bar");

        let mut app = MiddlewareBuilder::new(test);
        app.add(Middleware::new(b"foo"));
        assert!(app.call(&mut req).is_ok());

        fn test(req: &mut Request) -> Result<Response, String> {
            assert!(req.cookies().find("foo").is_some());
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: box MemReader::new(Vec::new()),
            })
        }
    }

    #[test]
    fn set_cookie() {
        let mut req = MockRequest::new(Post, "/articles");
        let mut app = MiddlewareBuilder::new(test);
        app.add(Middleware::new(b"foo"));
        let response = app.call(&mut req).ok().unwrap();
        let v = response.headers["Set-Cookie".to_string()].as_slice();
        assert_eq!(v, ["foo=bar; Path=/".to_string()].as_slice());

        fn test(req: &mut Request) -> Result<Response, String> {
            let c = Cookie::new("foo".to_string(), "bar".to_string());
            req.cookies().add(c);
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: box MemReader::new(Vec::new()),
            })
        }
    }
}
<commit_msg>Update to master<commit_after>#![feature(macro_rules, globs)]

extern crate conduit;
extern crate "conduit-middleware" as conduit_middleware;
extern crate cookie;
extern crate serialize;
#[cfg(test)] extern crate "conduit-test" as test;

use std::fmt::Show;
use conduit::{Request, Response};
use cookie::{CookieJar, Cookie};

pub use session::{RequestSession, SessionMiddleware};

mod session;

pub struct Middleware {
    key: Vec<u8>,
}

impl Middleware {
    pub fn new(key: &[u8]) -> Middleware {
        Middleware { key: key.to_vec() }
    }
}

impl conduit_middleware::Middleware for Middleware {
    fn before(&self, req: &mut Request) -> Result<(), Box<Show + 'static>> {
        let jar = {
            let headers = req.headers();
            let mut jar = CookieJar::new(self.key.as_slice());
            match headers.find("Cookie") {
                Some(cookies) => {
                    for cookie in cookies.iter() {
                        match Cookie::parse(*cookie) {
                            Ok(c) => jar.add_original(c),
                            Err(..) => {}
                        }
                    }
                }
                None => {}
            }
            jar
        };
        req.mut_extensions().insert(jar);
        Ok(())
    }

    fn after(&self, req: &mut Request, res: Result<Response, Box<Show + 'static>>)
        -> Result<Response, Box<Show + 'static>>
    {
        let mut res = try!(res);
        {
            let jar = req.cookies();
            let cookies = res.headers.find_or_insert("Set-Cookie".to_string(),
                                                     Vec::new());
            for delta in jar.delta().move_iter() {
                cookies.push(delta);
            }
        }
        Ok(res)
    }
}

pub trait RequestCookies<'a> {
    fn cookies(self) -> &'a CookieJar<'static>;
}

impl<'a> RequestCookies<'a> for &'a Request + 'a {
    fn cookies(self) -> &'a CookieJar<'static> {
        self.extensions().find::<CookieJar<'static>>()
            .expect("Missing cookie jar")
    }
}

#[cfg(test)]
mod tests {

    use conduit::{Request, Response, Handler, Post};
    use conduit_middleware::MiddlewareBuilder;
    use cookie::Cookie;
    use test::MockRequest;
    use std::collections::HashMap;
    use std::io::MemReader;

    use super::{RequestCookies, Middleware};

    #[test]
    fn request_headers() {
        let mut req = MockRequest::new(Post, "/articles");
        req.header("Cookie", "foo=bar");

        let mut app = MiddlewareBuilder::new(test);
        app.add(Middleware::new(b"foo"));
        assert!(app.call(&mut req).is_ok());

        fn test(req: &mut Request) -> Result<Response, String> {
            assert!(req.cookies().find("foo").is_some());
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: box MemReader::new(Vec::new()),
            })
        }
    }

    #[test]
    fn set_cookie() {
        let mut req = MockRequest::new(Post, "/articles");
        let mut app = MiddlewareBuilder::new(test);
        app.add(Middleware::new(b"foo"));
        let response = app.call(&mut req).ok().unwrap();
        let v = response.headers["Set-Cookie".to_string()].as_slice();
        assert_eq!(v, ["foo=bar; Path=/".to_string()].as_slice());

        fn test(req: &mut Request) -> Result<Response, String> {
            let c = Cookie::new("foo".to_string(), "bar".to_string());
            req.cookies().add(c);
            Ok(Response {
                status: (200, "OK"),
                headers: HashMap::new(),
                body: box MemReader::new(Vec::new()),
            })
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, VecDeque};
use std::iter::Iterator;
use std::u64;
use std::usize;

pub type VertexId = usize;

pub trait Property : Copy + Ord + Eq {}
impl<T> Property for T where T: Copy + Ord + Eq {}

/// Represent a Graph structure
#[derive(Debug)]
pub struct Graph<V: Property, E: Property> {
    pub vertexes: HashMap<VertexId, Vertex<V>>,
    pub edges: HashMap<(VertexId, VertexId), E>,
    adjacency_matrix: Vec<Vec<bool>>,
}

#[derive(Debug)]
pub struct Vertex<V: Property> {
    pub value: V,
    pub neighbors: Vec<VertexId>,
}

pub struct BfsIterator<'a, V: 'a + Property, E: 'a + Property, F> {
    queue: VecDeque<VertexId>,
    graph: &'a Graph<V, E>,
    distances: Vec<u64>,
    parents: Vec<VertexId>,
    predicate: F
}

impl<'a, V: Property, E: Property, F> BfsIterator<'a, V, E, F> {
    fn new(graph: &'a Graph<V, E>, source: VertexId, predicate: F) -> BfsIterator<'a, V, E, F> {
        let mut queue = VecDeque::new();
        queue.push_back(source);
        let mut distances = vec![u64::MAX; graph.n_vertexes()];
        let parents = vec![usize::MAX; graph.n_vertexes()];
        distances[source] = 0;
        BfsIterator {
            graph: graph,
            queue: queue,
            distances: distances,
            parents: parents,
            predicate: predicate
        }
    }
}

/// Iterator for a breadth first search over a graph
/// Returns in order a tuple of (vertex, distance, parent)
impl<'a, V: Property, E: Property, F> Iterator for BfsIterator<'a, V, E, F>
    where F: Fn(V, E, V) -> bool {
    type Item = (VertexId, u64, VertexId);
    fn next(&mut self) -> Option<(VertexId, u64, VertexId)> {
        let g = self.graph;
        match self.queue.pop_front() {
            Some(vertex) => {
                for v in self.graph.adjacent_vertexes(&vertex) {
                    let predicate = &self.predicate;
                    let pred = predicate(g.vertexes[&vertex].value, g.edges[&(vertex, *v)], g.vertexes[v].value);
                    if self.distances[*v] == u64::MAX && pred {
                        self.distances[*v] = self.distances[vertex] + 1;
                        self.parents[*v] = vertex;
                        self.queue.push_back(*v);
                    }
                }
                Some((vertex, self.distances[vertex], self.parents[vertex]))
            }
            _ => None
        }
    }
}

impl<'a, V: Property, E: Property> Graph<V, E> {
    pub fn new(vertex_list: &Vec<(VertexId, V)>, edge_list: &Vec<(VertexId, VertexId, E)>) -> Graph<V, E> {
        let mut vertexes: HashMap<VertexId, Vertex<V>> = HashMap::new();
        for v in vertex_list {
            vertexes.insert(v.0,
                            Vertex {
                                value: v.1,
                                neighbors: Vec::new(),
                            });
        }
        let n_vertexes: usize = vertexes.len();

        let mut adjacency_matrix: Vec<Vec<bool>> = vec![vec![false; n_vertexes]; n_vertexes];
        let mut edges: HashMap<(VertexId, VertexId), E> = HashMap::new();
        for edge in edge_list {
            adjacency_matrix[edge.0][edge.1] = true;
            vertexes.get_mut(&edge.0).unwrap().neighbors.push(edge.1);
            edges.insert((edge.0, edge.1), edge.2);
        }

        Graph {
            vertexes: vertexes,
            edges: edges,
            adjacency_matrix: adjacency_matrix,
        }
    }
    pub fn size(&self) -> (usize, usize) {
        (self.vertexes.len(), self.edges.len())
    }
    pub fn n_vertexes(&self) -> usize {
        self.vertexes.len()
    }
    pub fn n_edges(&self) -> usize {
        self.edges.len()
    }
    pub fn adjacent_vertexes(&self, vertex: &VertexId) -> &Vec<VertexId> {
        &self.vertexes[vertex].neighbors
    }
    pub fn bfs_iter(&self, source: VertexId) -> BfsIterator<V, E, fn(V, E, V) -> bool> {
        BfsIterator::new(self, source, bfs_true_predicate)
    }
    pub fn bfs_iter_predicate<F>(&'a self, source: VertexId, predicate: F) -> BfsIterator<V, E, F>
    where F: Fn(V, E, V) -> bool {
        BfsIterator::new(self, source, predicate)
    }
}

pub trait FlowGraph<V> {
    fn augmenting_path(&self, source: VertexId) -> Vec<(VertexId, u64, VertexId)>;
}

impl<'a, V: Property> FlowGraph<V> for Graph<V, i64> {
    fn augmenting_path(&self, source: VertexId) -> Vec<(VertexId, u64, VertexId)> {
        BfsIterator::new(self, source, flow_predicate).collect()
    }
}

fn bfs_true_predicate<'a, V: Property, E: Property>(_: V, _: E, _: V) -> bool {
    true
}

fn flow_predicate<'a, V: Property>(_: V, edge: i64, _: V) -> bool {
    edge > 0
}

#[cfg(test)]
mod tests {
    use Graph;
    use VertexId;
    use std::collections::HashSet;
    use std::usize;

    #[test]
    fn test_new_graph() {
        let vertex_list = vec![(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)];
        let edge_list = vec![(0, 1, 5), (0, 2, 2), (2, 3, 3), (4, 3, 1)];
        let g = Graph::new(&vertex_list, &edge_list);
        assert_eq!(g.size(), (5, 4));
        for k in 0..5 {
            assert!(g.vertexes.contains_key(&k));
        }
        assert_eq!(g.edges[&(0, 1)], 5);
        assert_eq!(g.edges[&(0, 2)], 2);
        assert_eq!(g.edges[&(2, 3)], 3);
        assert_eq!(g.edges[&(4, 3)], 1);
    }

    #[test]
    fn test_bfs() {
        let vertex_list = vec![(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0)];
        let edge_list = vec![(0, 1, 1), (1, 2, 1), (0, 3, 1), (3, 4, 1), (4, 1, 0), (4, 5, 1), (5, 2, 1)];
        let g = Graph::new(&vertex_list, &edge_list);
        let result: Vec<(VertexId, u64, VertexId)> = g.bfs_iter(0).collect();
        let mut result_set = HashSet::new();
        result_set.extend(result);
        let mut expect = HashSet::new();
        expect.insert((0, 0, usize::MAX));
        expect.insert((1, 1, 0));
        expect.insert((2, 2, 1));
        expect.insert((3, 1, 0));
        expect.insert((4, 2, 3));
        expect.insert((5, 3, 4));
        assert_eq!(result_set, expect);
    }
}
<commit_msg>Added implementation of augmenting path<commit_after>use std::collections::{HashMap, VecDeque};
use std::iter::Iterator;
use std::u64;
use std::usize;

pub type VertexId = usize;

pub trait Property : Copy {}
impl<T> Property for T where T: Copy {}

/// Represent a Graph structure
#[derive(Debug)]
pub struct Graph<V: Property, E: Property> {
    pub vertexes: HashMap<VertexId, Vertex<V>>,
    pub edges: HashMap<(VertexId, VertexId), E>,
    adjacency_matrix: Vec<Vec<bool>>,
}

#[derive(Debug)]
pub struct Vertex<V: Property> {
    pub value: V,
    pub neighbors: Vec<VertexId>,
}

#[derive(Debug, Copy, Clone)]
pub struct FlowEdge {
    pub capacity: i64,
    pub flow: i64
}

pub struct BfsIterator<'a, V: 'a + Property, E: 'a + Property, F> {
    queue: VecDeque<VertexId>,
    graph: &'a Graph<V, E>,
    distances: Vec<u64>,
    parents: Vec<VertexId>,
    predicate: F
}

impl<'a, V: Property, E: Property, F> BfsIterator<'a, V, E, F> {
    fn new(graph: &'a Graph<V, E>, source: VertexId, predicate: F) -> BfsIterator<'a, V, E, F> {
        let mut queue = VecDeque::new();
        queue.push_back(source);
        let mut distances = vec![u64::MAX; graph.n_vertexes()];
        let parents = vec![usize::MAX; graph.n_vertexes()];
        distances[source] = 0;
        BfsIterator {
            graph: graph,
            queue: queue,
            distances: distances,
            parents: parents,
            predicate: predicate
        }
    }
}

/// Iterator for a breadth first search over a graph
/// Returns in order a tuple of (vertex, distance, parent)
impl<'a, V: Property, E: Property, F> Iterator for BfsIterator<'a, V, E, F>
    where F: Fn(V, E, V) -> bool {
    type Item = (VertexId, u64, VertexId);
    fn next(&mut self) -> Option<(VertexId, u64, VertexId)> {
        let g = self.graph;
        match self.queue.pop_front() {
            Some(vertex) => {
                for v in self.graph.adjacent_vertexes(&vertex) {
                    let predicate = &self.predicate;
                    let pred = predicate(g.vertexes[&vertex].value, g.edges[&(vertex, *v)], g.vertexes[v].value);
                    if self.distances[*v] == u64::MAX && pred {
                        self.distances[*v] = self.distances[vertex] + 1;
                        self.parents[*v] = vertex;
                        self.queue.push_back(*v);
                    }
                }
                Some((vertex, self.distances[vertex], self.parents[vertex]))
            }
            _ => None
        }
    }
}

impl<'a, V: Property, E: Property> Graph<V, E> {
    pub fn new(vertex_list: &Vec<(VertexId, V)>, edge_list: &Vec<(VertexId, VertexId, E)>) -> Graph<V, E> {
        let mut vertexes: HashMap<VertexId, Vertex<V>> = HashMap::new();
        for v in vertex_list {
            vertexes.insert(v.0,
                            Vertex {
                                value: v.1,
                                neighbors: Vec::new(),
                            });
        }
        let n_vertexes: usize = vertexes.len();

        let mut adjacency_matrix: Vec<Vec<bool>> = vec![vec![false; n_vertexes]; n_vertexes];
        let mut edges: HashMap<(VertexId, VertexId), E> = HashMap::new();
        for edge in edge_list {
            adjacency_matrix[edge.0][edge.1] = true;
            vertexes.get_mut(&edge.0).unwrap().neighbors.push(edge.1);
            edges.insert((edge.0, edge.1), edge.2);
        }

        Graph {
            vertexes: vertexes,
            edges: edges,
            adjacency_matrix: adjacency_matrix,
        }
    }
    pub fn size(&self) -> (usize, usize) {
        (self.vertexes.len(), self.edges.len())
    }
    pub fn n_vertexes(&self) -> usize {
        self.vertexes.len()
    }
    pub fn n_edges(&self) -> usize {
        self.edges.len()
    }
    pub fn adjacent_vertexes(&self, vertex: &VertexId) -> &Vec<VertexId> {
        &self.vertexes[vertex].neighbors
    }
    pub fn bfs_iter(&self, source: VertexId) -> BfsIterator<V, E, fn(V, E, V) -> bool> {
        BfsIterator::new(self, source, bfs_true_predicate)
    }
    pub fn bfs_iter_predicate<F>(&'a self, source: VertexId, predicate: F) -> BfsIterator<V, E, F>
    where F: Fn(V, E, V) -> bool {
        BfsIterator::new(self, source, predicate)
    }
}

pub fn path_from_visited(source: VertexId,
                         sink: VertexId,
                         visited: &Vec<(VertexId, u64, VertexId)>) -> Vec<VertexId> {
    let mut node_parent_map: HashMap<VertexId, VertexId> = HashMap::new();
    for node in visited {
        node_parent_map.insert(node.0, node.2);
    }
    let mut path: Vec<VertexId> = Vec::new();
    let mut node = sink;
    loop {
        path.insert(0, node);
        if node == source {
            break;
        }
        node = node_parent_map[&node];
    }
    path
}

pub trait FlowGraph<V> {
    fn augmenting_path(&self, source: VertexId, sink: VertexId) -> Option<Vec<VertexId>>;
}

impl<'a, V: Property> FlowGraph<V> for Graph<V, FlowEdge> {
    fn augmenting_path(&self, source: VertexId, sink: VertexId) -> Option<Vec<VertexId>> {
        let bfs_edges: Vec<(VertexId, u64, VertexId)> = BfsIterator::new(self, source, flow_predicate).collect();
        match bfs_edges.iter().any(|element| element.0 == sink) {
            true => {
                Some(path_from_visited(source, sink, &bfs_edges))
            },
            _ => None
        }
    }
}

fn bfs_true_predicate<'a, V: Property, E: Property>(_: V, _: E, _: V) -> bool {
    true
}

fn flow_predicate<'a, V: Property>(_: V, edge: FlowEdge, _: V) -> bool {
    edge.capacity - edge.flow > 0
}

#[cfg(test)]
mod tests {
    use Graph;
    use FlowGraph;
    use VertexId;
    use FlowEdge;
    use path_from_visited;
    use std::collections::HashSet;
    use std::usize;

    #[test]
    fn test_new_graph() {
        let vertex_list = vec![(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)];
        let edge_list = vec![(0, 1, 5), (0, 2, 2), (2, 3, 3), (4, 3, 1)];
        let g = Graph::new(&vertex_list, &edge_list);
        assert_eq!(g.size(), (5, 4));
        for k in 0..5 {
            assert!(g.vertexes.contains_key(&k));
        }
        assert_eq!(g.edges[&(0, 1)], 5);
        assert_eq!(g.edges[&(0, 2)], 2);
        assert_eq!(g.edges[&(2, 3)], 3);
        assert_eq!(g.edges[&(4, 3)], 1);
    }

    #[test]
    fn test_bfs() {
        let vertex_list = vec![(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0)];
        let edge_list = vec![(0, 1, 1), (1, 2, 1), (0, 3, 1), (3, 4, 1), (4, 1, 0), (4, 5, 1), (5, 2, 1)];
        let g = Graph::new(&vertex_list, &edge_list);
        let result: Vec<(VertexId, u64, VertexId)> = g.bfs_iter(0).collect();
        let mut result_set = HashSet::new();
        result_set.extend(result);
        let mut expect = HashSet::new();
        expect.insert((0, 0, usize::MAX));
        expect.insert((1, 1, 0));
        expect.insert((2, 2, 1));
        expect.insert((3, 1, 0));
        expect.insert((4, 2, 3));
        expect.insert((5, 3, 4));
        assert_eq!(result_set, expect);
    }

    #[test]
    fn test_augmenting_path() {
        let vertex_list = vec![(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)];
        let edge_list = vec![
            (0, 1, FlowEdge{flow: 0, capacity: 1}),
            (0, 2, FlowEdge{flow: 0, capacity: 1}),
            (1, 3, FlowEdge{flow: 0, capacity: 1}),
            (1, 5, FlowEdge{flow: 0, capacity: 1}),
            (2, 5, FlowEdge{flow: 0, capacity: 1}),
            (2, 6, FlowEdge{flow: 0, capacity: 1}),
            (3, 4, FlowEdge{flow: 0, capacity: 1})
        ];
        let g = Graph::new(&vertex_list, &edge_list);
        let result = g.augmenting_path(0, 4);
        assert_eq!(result.unwrap(), [0, 1, 3, 4]);
    }

    #[test]
    fn test_path_from_visited() {
        let source = 0;
        let sink = 4;
        let visited = vec![(0, 0, usize::MAX), (1, 1, 0), (2, 1, 0), (5, 2, 1), (3, 2, 1), (4, 3, 3), (6, 2, 2)];
        let path = path_from_visited(source, sink, &visited);
        assert_eq!(path, [0, 1, 3, 4]);
    }
}
<|endoftext|>


<commit_before>//! Numbers provides safe, modular, and fast high-dimensional matrix computations.

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]
#![feature(custom_derive)]
#![feature(test)]
#![feature(plugin)]
#![plugin(clippy)]
#![allow(match_bool)]

extern crate blas;
extern crate lapack;
extern crate rand;
extern crate zipWith;
extern crate num;
extern crate test;

pub mod matrixerror;
pub mod operations;
pub mod eigenvalues;
pub mod solvers;
pub mod factorizations;
pub mod rank;

use matrixerror::MatrixError;
use rand::{thread_rng, Rng, Rand};
use std::cmp::*;
use std::ops::{Add, Sub, Mul, Div};
use num::traits::{Num, Zero, One};
use zipWith::IntoZipWith;

enum MatrixTypes<T, U, R> where
    T: RectMat,
    U: SqMat,
    R: NonSingularMat
{
    Rectangle(T),
    Square(U),
    NonSingularMat(R)
}

trait RectMat : Num + Rand + Clone{
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<   Self, MatrixError>;
    fn random(r_size : usize, c_size: usize) -> Self ;
    fn replace(&mut self,row: usize, col:usize, value :f64) -> ();
    fn zeros (r_size : usize, c_size : usize) -> Self;
    fn diag_mat (a : Vec<f64>) -> Self;
    fn get_element(&self, row : usize, col : usize) -> f64;
    fn get_ind(&self, row :usize, col : usize) -> usize;
    fn transpose(&self) -> Self;
    fn diagonal (&self) -> Vec<f64>;
    fn tri (row_size:usize, col_size : usize, k : usize, upper_or_lower : Triangular) -> Result<Self,MatrixError>;
}

trait SqMat: RectMat{
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<   Self, MatrixError>;
    fn diag_mat (a : Vec<f64>) -> Self;
    fn identity(row_size : usize) -> Self;
    fn pseudoinverse(a: &mut Self) ->Result<Self,MatrixError>;
}

trait NonSingularMat : SqMat{
    fn inverse(a : &mut Self ) ->Result<Self,MatrixError>;
}

/// Generic Matrix object.
#[derive(Debug, Clone, Rand, Num)]
pub struct Matrix {
    pub elements : Vec<f64>,
    pub row_size : usize,
    pub col_size : usize,
    pub transpose : Trans,
}

impl RectMat for Matrix{

    /// Create rectangular matrix
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<Matrix, MatrixError>{
        if r_size * c_size != e.len(){
            return Err(MatrixError :: MalformedMatrix)
        }
        Ok(Matrix {
            elements : e,
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        })
    }

    fn random(r_size : usize, c_size : usize) -> Matrix{
        let e = rand::thread_rng()
        .gen_iter::<f64>()
        .take(r_size*c_size)
        .collect::<Vec<f64>>();

        Matrix {
            elements : e,
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        }
    }

    fn replace(&mut self,row: usize, col:usize, value : f64) -> () {
        let ind = self.get_ind(row,col);
        self.elements[ind] = value;
    }

    /// Create matrix with all zeros.
    fn zeros (r_size : usize, c_size : usize) -> Matrix{
        Matrix {
            elements : vec![Zero::zero();r_size*c_size],
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        }
    }

    /// Map an index in a matrix to index in its corresponding 1-d vector.
    fn get_ind(&self, row :usize, col : usize) -> usize{
        if self.transpose == Trans :: Transpose{
            return (row-1)+ (col-1)*self.row_size
        }
        (col-1) +(row-1)*self.col_size
    }

    /// Get an element from the matrix.
    fn get_element(&self, row : usize, col : usize) -> f64{
        let elem = &self.elements[self.get_ind(row,col)];
        elem.to_owned()
    }
    /// Transpose the matrix.
    /// We're not actually changing anything in memory; we just flag the matrix as transpose to change pointer reference to elements.
    fn transpose(&self) -> Matrix {
        Matrix {
            elements : self.elements.clone(),
            row_size : self.col_size,
            col_size : self.row_size,
            transpose : match self.transpose { Trans :: Transpose => Trans :: Regular, Trans :: Regular => Trans :: Transpose}
        }
    }

    /// Get the diagonal of a matrix.
    fn diagonal (&self) -> Vec<f64>{
        let mut diag : Vec<f64> = Vec :: new();
        for elem in 1..min(self.row_size,self.col_size){
            diag.push(self.get_element(elem,elem));
        }
        diag
    }

    /// Get a triangular matrix with specified dimensions above or below specified diagonal.
    fn tri (row_size:usize, col_size : usize, k : usize, upper_or_lower : Triangular) -> Matrix{
        let mut mat : Matrix = Matrix :: zeros(row_size, col_size);
        match k {
        x if x > row_size => Err(MatrixError :: IndexError),
        x if x > col_size => Err(MatrixError :: IndexError),
        }
        for i in 1..row_size+1{
            for j in 1..col_size+1{
                match upper_or_lower{

                    Triangular::Upper =>{
                        if i <= j + k{
                            mat.replace(i,j,One::one());
                        }
                    }
                    Triangular::Lower => {
                        if i >= j + k{
                            mat.replace(i,j,One::one());
                        }
                    }

                }
            }
        }
        mat
    }

}

impl SqMat for Matrix {

        /// Create square matrix
        fn new(e : Vec<f64>, rc_size : usize) -> Result<Matrix, MatrixError>{
            if rc_size * rc_size != e.len(){
                return Err(MatrixError :: MalformedMatrix)
            }
            Ok(Matrix {
                elements : e,
                row_size : rc_size,
                col_size : rc_size,
                transpose : Trans :: Regular,
            })
        }

        /// Create a diagonal matrix of specified row size.

        fn diag_mat (a : Vec<f64>) -> Matrix {
            let mut mat = Matrix :: zeros(a.len(),a.len());
            for i in 1..a.len()+1{
                let e = &a[i-1];
                mat.replace(i, i, e.to_owned());
            }
            mat
        }

        /// Create an square identity matrix of specified row size.
        fn identity(row_size : usize) -> Matrix {
              Matrix :: diag_mat(vec![One::one(); row_size])
        }

        fn pseudoinverse(a: &mut Matrix) ->Result<Matrix,MatrixError> {
            let (mut u,mut e, mut vt) = try!(factorizations::svd(a));
            let inv_e = try!(a.matrix_map(&|x : &f64| if x > &0.0 { x.recip()} else { 0.0 },&mut e));
            let mut d = try!(operations::dot(&mut u, &mut inv_e.transpose()));
            operations::dot (&mut d, &mut vt)
        }

}

impl NonSingularMat for Matrix {

    fn inverse(a : &mut Matrix ) ->Result<MatrixError,MatrixError> {

            let (l, ipiv) = factorizations::lufact (a);
            let n = l.col_size;
            let lda = l.row_size;
            let mut work = vec![0.0; 4 * n];
            let iwork = n as isize * 4;
            let mut info = 0;
            lapack::dgetri(n, &mut l.elements, lda, &ipiv,&mut work, iwork, &mut info);
            match info {
                x if x > 0 => return Err(MatrixError::LapackComputationError),
                0 => { let m = Ok(l.to_owned()); return m}
                x if x < 0 => return  Err(MatrixError::LapackInputError),
                _ => return Err(MatrixError::UnknownError),
            };

        Err(MatrixError::SingularMatrix)
    }

}

/// Triangular represents two variants of triangular matrices : Upper and Lower. Use this enum
/// for functions that require specification of a triangular matrix output.
#[derive(Debug, Clone)]
pub enum Triangular{
    Upper,
    Lower
}

/// Norm provides four variants of matrix norms.
#[derive(Debug, Clone)]
pub enum Norm{
    OneNorm,
    InfinityNorm,
    FrobeniusNorm,
    MaxAbsValue
}
/// For relevant functions, Eig represents the option to output either just eigenvalues or
/// both eigenvalues and eigenvectors.
#[derive(Debug, Clone)]
pub enum Eig {
    Eigenvalues,
    EigenvaluesAndEigenvectors,
}

/// Condition provides four matrix conditions to determine the feasibility of inversion
#[derive(Debug, Clone, PartialEq)]
pub enum Condition {
    WellConditioned,
    IllConditioned,
    Singular,
    NotAvailable
}

/// Trans enumerates transpose/non-transpose matrices
#[derive(Debug, Clone , PartialEq)]
pub enum Trans {
    Transpose,
    Regular
}

/// Type declaration of Singular Value Decomposition Output
pub type SVD = (Matrix, Matrix, Matrix);

impl<'a, 'b> Add<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn add(self, other: &Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }

            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x+y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular})

    }
}

impl<'a, 'b> Sub<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn sub(self, other: &'b Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }
        Ok(Matrix {
        elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x-y).collect(),
        row_size : self.row_size,
        col_size : other.col_size,
        transpose : Trans :: Regular})
    }

}

impl<'a, 'b> Div<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn div(self, other: &'b Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }
            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x/y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular}
        )
        }
    }

impl<'a, 'b> Mul <&'b Matrix> for &'a Matrix {
    type Output =Result<Matrix, MatrixError>;

    fn mul(self, other: &'b Matrix) ->Result<Matrix, MatrixError>{

        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }

            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x*y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular})

        }
    }

impl PartialEq for Matrix{
    fn eq(&self, other: &Matrix) -> bool {
         (self.elements == other.elements)
       & (self.row_size == other.row_size)
       & (self.col_size == other.col_size)
       & (self.transpose  == other.transpose)
   }
}

#[macro_export]
macro_rules! matrix_equal {
    ( $x:expr , $y : expr) => (
        {
            assert!($x.row_size == $y.row_size);
            assert!($x.col_size == $y.col_size);
            assert!($x.transpose  == $y.transpose);
            if let Ok(s) = &$x - &$y{
                for elem in s.elements{
                    assert!(elem.abs() < 1e-6)
                }
            }
        }

    )
    }
<commit_msg>rewrite for type safety<commit_after>//! Numbers provides safe, modular, and fast high-dimensional matrix computations.

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]
#![feature(custom_derive)]
#![feature(test)]
#![feature(plugin)]
#![plugin(clippy)]
#![allow(match_bool)]

extern crate blas;
extern crate lapack;
extern crate rand;
extern crate zipWith;
extern crate num;
extern crate test;

pub mod matrixerror;
pub mod operations;
pub mod eigenvalues;
pub mod solvers;
pub mod factorizations;
pub mod rank;

use matrixerror::MatrixError;
use rand::{thread_rng, Rng, Rand};
use std::cmp::*;
use std::ops::{Add, Sub, Mul, Div};
use num::traits::{Num, Zero, One};
use zipWith::IntoZipWith;

trait RectMat : Num + Rand + Clone{
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<   Self, MatrixError>;
    fn random(r_size : usize, c_size: usize) -> Self ;
    fn replace(&mut self,row: usize, col:usize, value :f64) -> ();
    fn zeros (r_size : usize, c_size : usize) -> Self;
    fn diag_mat (a : Vec<f64>) -> Self;
    fn get_element(&self, row : usize, col : usize) -> f64;
    fn get_ind(&self, row :usize, col : usize) -> usize;
    fn transpose(&self) -> Self;
    fn diagonal (&self) -> Vec<f64>;
    fn tri (row_size:usize, col_size : usize, k : usize, upper_or_lower : Triangular) -> Result<Self,MatrixError>;
}

trait SqMat: RectMat{
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<   Self, MatrixError>;
    fn diag_mat (a : Vec<f64>) -> Self;
    fn identity(row_size : usize) -> Self;
    fn pseudoinverse(a: &mut Self) ->Result<Self,MatrixError>;
}

trait NonSingularMat : SqMat{
    fn inverse(a : &mut Self ) ->Result<Self,MatrixError>;
}

/// Generic Matrix object.
#[derive(Debug, Clone, Rand, Num)]
pub struct Matrix {
    pub elements : Vec<f64>,
    pub row_size : usize,
    pub col_size : usize,
    pub transpose : Trans,
}

impl RectMat for Matrix{

    /// Create rectangular matrix
    fn new(e : Vec<f64>, r_size : usize, c_size : usize) -> Result<Matrix, MatrixError>{
        if r_size * c_size != e.len(){
            return Err(MatrixError :: MalformedMatrix)
        }
        Ok(Matrix {
            elements : e,
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        })
    }

    fn random(r_size : usize, c_size : usize) -> Matrix{
        let e = rand::thread_rng()
        .gen_iter::<f64>()
        .take(r_size*c_size)
        .collect::<Vec<f64>>();

        Matrix {
            elements : e,
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        }
    }

    fn replace(&mut self,row: usize, col:usize, value : f64) -> () {
        let ind = self.get_ind(row,col);
        self.elements[ind] = value;
    }

    /// Create matrix with all zeros.
    fn zeros (r_size : usize, c_size : usize) -> Matrix{
        Matrix {
            elements : vec![Zero::zero();r_size*c_size],
            row_size : r_size,
            col_size : c_size,
            transpose : Trans :: Regular,
        }
    }

    /// Map an index in a matrix to index in its corresponding 1-d vector.
    fn get_ind(&self, row :usize, col : usize) -> usize{
        if self.transpose == Trans :: Transpose{
            return (row-1)+ (col-1)*self.row_size
        }
        (col-1) +(row-1)*self.col_size
    }

    /// Get an element from the matrix.
    fn get_element(&self, row : usize, col : usize) -> f64{
        let elem = &self.elements[self.get_ind(row,col)];
        elem.to_owned()
    }
    /// Transpose the matrix.
    /// We're not actually changing anything in memory; we just flag the matrix as transpose to change pointer reference to elements.
    fn transpose(&self) -> Matrix {
        Matrix {
            elements : self.elements.clone(),
            row_size : self.col_size,
            col_size : self.row_size,
            transpose : match self.transpose { Trans :: Transpose => Trans :: Regular, Trans :: Regular => Trans :: Transpose}
        }
    }

    /// Get the diagonal of a matrix.
    fn diagonal (&self) -> Vec<f64>{
        let mut diag : Vec<f64> = Vec :: new();
        for elem in 1..min(self.row_size,self.col_size){
            diag.push(self.get_element(elem,elem));
        }
        diag
    }

    /// Get a triangular matrix with specified dimensions above or below specified diagonal.
    fn tri (row_size:usize, col_size : usize, k : usize, upper_or_lower : Triangular) -> Matrix{
        let mut mat : Matrix = Matrix :: zeros(row_size, col_size);
        match k {
        x if x > row_size => Err(MatrixError :: IndexError),
        x if x > col_size => Err(MatrixError :: IndexError),
        }
        for i in 1..row_size+1{
            for j in 1..col_size+1{
                match upper_or_lower{

                    Triangular::Upper =>{
                        if i <= j + k{
                            mat.replace(i,j,One::one());
                        }
                    }
                    Triangular::Lower => {
                        if i >= j + k{
                            mat.replace(i,j,One::one());
                        }
                    }

                }
            }
        }
        mat
    }

}

impl SqMat for Matrix {

        /// Create square matrix
        fn new(e : Vec<f64>, rc_size : usize) -> Result<Matrix, MatrixError>{
            if rc_size * rc_size != e.len(){
                return Err(MatrixError :: MalformedMatrix)
            }
            Ok(Matrix {
                elements : e,
                row_size : rc_size,
                col_size : rc_size,
                transpose : Trans :: Regular,
            })
        }

        /// Create a diagonal matrix of specified row size.

        fn diag_mat (a : Vec<f64>) -> Matrix {
            let mut mat = Matrix :: zeros(a.len(),a.len());
            for i in 1..a.len()+1{
                let e = &a[i-1];
                mat.replace(i, i, e.to_owned());
            }
            mat
        }

        /// Create an square identity matrix of specified row size.
        fn identity(row_size : usize) -> Matrix {
              Matrix :: diag_mat(vec![One::one(); row_size])
        }

        fn pseudoinverse(a: &mut Matrix) ->Result<Matrix,MatrixError> {
            let (mut u,mut e, mut vt) = try!(factorizations::svd(a));
            let inv_e = try!(a.matrix_map(&|x : &f64| if x > &0.0 { x.recip()} else { 0.0 },&mut e));
            let mut d = try!(operations::dot(&mut u, &mut inv_e.transpose()));
            operations::dot (&mut d, &mut vt)
        }

}

impl NonSingularMat for Matrix {

    fn inverse(a : &mut Matrix ) ->Result<MatrixError,MatrixError> {

            let (l, ipiv) = factorizations::lufact (a);
            let n = l.col_size;
            let lda = l.row_size;
            let mut work = vec![0.0; 4 * n];
            let iwork = n as isize * 4;
            let mut info = 0;
            lapack::dgetri(n, &mut l.elements, lda, &ipiv,&mut work, iwork, &mut info);
            match info {
                x if x > 0 => return Err(MatrixError::LapackComputationError),
                0 => { let m = Ok(l.to_owned()); return m}
                x if x < 0 => return  Err(MatrixError::LapackInputError),
                _ => return Err(MatrixError::UnknownError),
            };

        Err(MatrixError::SingularMatrix)
    }

}

/// Triangular represents two variants of triangular matrices : Upper and Lower. Use this enum
/// for functions that require specification of a triangular matrix output.
#[derive(Debug, Clone)]
pub enum Triangular{
    Upper,
    Lower
}

/// Norm provides four variants of matrix norms.
#[derive(Debug, Clone)]
pub enum Norm{
    OneNorm,
    InfinityNorm,
    FrobeniusNorm,
    MaxAbsValue
}
/// For relevant functions, Eig represents the option to output either just eigenvalues or
/// both eigenvalues and eigenvectors.
#[derive(Debug, Clone)]
pub enum Eig {
    Eigenvalues,
    EigenvaluesAndEigenvectors,
}

/// Condition provides four matrix conditions to determine the feasibility of inversion
#[derive(Debug, Clone, PartialEq)]
pub enum Condition {
    WellConditioned,
    IllConditioned,
    Singular,
    NotAvailable
}

/// Trans enumerates transpose/non-transpose matrices
#[derive(Debug, Clone , PartialEq)]
pub enum Trans {
    Transpose,
    Regular
}

/// Type declaration of Singular Value Decomposition Output
pub type SVD = (Matrix, Matrix, Matrix);

impl<'a, 'b> Add<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn add(self, other: &Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }

            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x+y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular})

    }
}

impl<'a, 'b> Sub<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn sub(self, other: &'b Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }
        Ok(Matrix {
        elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x-y).collect(),
        row_size : self.row_size,
        col_size : other.col_size,
        transpose : Trans :: Regular})
    }

}

impl<'a, 'b> Div<&'b Matrix> for &'a Matrix {
    type Output = Result<Matrix, MatrixError>;

    fn div(self, other: &'b Matrix) -> Result<Matrix, MatrixError> {
        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }
            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x/y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular}
        )
        }
    }

impl<'a, 'b> Mul <&'b Matrix> for &'a Matrix {
    type Output =Result<Matrix, MatrixError>;

    fn mul(self, other: &'b Matrix) ->Result<Matrix, MatrixError>{

        if self.col_size != other.col_size{
             return Err(MatrixError::MismatchedDimensions)
         }

            Ok(Matrix {
            elements : self.elements.clone().zip_with(other.elements.clone(), |x,y| x*y).collect(),
            row_size : self.row_size,
            col_size : other.col_size,
            transpose : Trans :: Regular})

        }
    }

impl PartialEq for Matrix{
    fn eq(&self, other: &Matrix) -> bool {
         (self.elements == other.elements)
       & (self.row_size == other.row_size)
       & (self.col_size == other.col_size)
       & (self.transpose  == other.transpose)
   }
}

#[macro_export]
macro_rules! matrix_equal {
    ( $x:expr , $y : expr) => (
        {
            assert!($x.row_size == $y.row_size);
            assert!($x.col_size == $y.col_size);
            assert!($x.transpose  == $y.transpose);
            if let Ok(s) = &$x - &$y{
                for elem in s.elements{
                    assert!(elem.abs() < 1e-6)
                }
            }
        }

    )
    }
<|endoftext|>


<commit_before>extern crate futures;
extern crate hyper;
extern crate mktemp;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate tera;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_service;
extern crate tokio_process;

mod error;
mod papers;
mod workspace;
pub mod server;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>🔥 Remove placeholder test<commit_after>extern crate futures;
extern crate hyper;
extern crate mktemp;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate tera;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_service;
extern crate tokio_process;

mod error;
mod papers;
mod workspace;
pub mod server;
<|endoftext|>


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

use chrono::prelude::{DateTime, Utc};
use chrono::Duration;
use std::sync::{Arc, RwLock};

use chain;
use common::types::{Error, SyncState, SyncStatus};
use core::core::hash::Hashed;
use core::global;
use p2p::{self, Peer};
use util::LOGGER;

/// Fast sync has 3 "states":
/// * syncing headers
/// * once all headers are sync'd, requesting the txhashset state
/// * once we have the state, get blocks after that
///
/// The StateSync struct implements and monitors the middle step.
pub struct StateSync {
	sync_state: Arc<SyncState>,
	peers: Arc<p2p::Peers>,
	chain: Arc<chain::Chain>,
	archive_mode: bool,

	prev_fast_sync: Option<DateTime<Utc>>,
	fast_sync_peer: Option<Arc<RwLock<Peer>>>,
}

impl StateSync {
	pub fn new(
		sync_state: Arc<SyncState>,
		peers: Arc<p2p::Peers>,
		chain: Arc<chain::Chain>,
		archive_mode: bool,
	) -> StateSync {
		StateSync {
			sync_state,
			peers,
			chain,
			archive_mode,
			prev_fast_sync: None,
			fast_sync_peer: None,
		}
	}

	/// Check whether state sync should run and triggers a state download when
	/// it's time (we have all headers). Returns true as long as state sync
	/// needs monitoring, false when it's either done or turned off.
	pub fn check_run(
		&mut self,
		header_head: &chain::Tip,
		head: &chain::Tip,
		highest_height: u64,
	) -> bool {
		let need_state_sync = !self.archive_mode
			&& highest_height.saturating_sub(head.height) > global::cut_through_horizon() as u64;
		if !need_state_sync {
			return false;
		}

		let mut sync_need_restart = false;

		// check sync error
		{
			let clone = self.sync_state.sync_error();
			if let Some(ref sync_error) = *clone.read().unwrap() {
				error!(
					LOGGER,
					"fast_sync: error = {:?}. restart fast sync", sync_error
				);
				sync_need_restart = true;
			}
			drop(clone);
		}

		// check peer connection status of this sync
		if let Some(ref peer) = self.fast_sync_peer {
			if let Ok(p) = peer.try_read() {
				if !p.is_connected() && SyncStatus::TxHashsetDownload == self.sync_state.status() {
					sync_need_restart = true;
					info!(
						LOGGER,
						"fast_sync: peer connection lost: {:?}. restart", p.info.addr,
					);
				}
			}
		}

		if sync_need_restart {
			self.fast_sync_reset();
			self.sync_state.clear_sync_error();
		}

		// run fast sync if applicable, normally only run one-time, except restart in error
		if header_head.height == highest_height {
			let (go, download_timeout) = self.fast_sync_due();

			if download_timeout && SyncStatus::TxHashsetDownload == self.sync_state.status() {
				error!(
					LOGGER,
					"fast_sync: TxHashsetDownload status timeout in 10 minutes!"
				);
				self.sync_state
					.set_sync_error(Error::P2P(p2p::Error::Timeout));
			}

			if go {
				self.fast_sync_peer = None;
				match self.request_state(&header_head) {
					Ok(peer) => {
						self.fast_sync_peer = Some(peer);
					}
					Err(e) => self.sync_state.set_sync_error(Error::P2P(e)),
				}
				self.sync_state.update(SyncStatus::TxHashsetDownload);

			}
		}
		true
	}

	fn request_state(&self, header_head: &chain::Tip) -> Result<Arc<RwLock<Peer>>, p2p::Error> {
		let horizon = global::cut_through_horizon() as u64;

		if let Some(peer) = self.peers.most_work_peer() {
			if let Ok(p) = peer.try_read() {
				// ask for txhashset at 90% of horizon, this still leaves time for download
				// and validation to happen and stay within horizon
				let mut txhashset_head = self
					.chain
					.get_block_header(&header_head.prev_block_h)
					.unwrap();
				for _ in 0..(horizon - horizon / 10) {
					txhashset_head = self
						.chain
						.get_block_header(&txhashset_head.previous)
						.unwrap();
				}
				let bhash = txhashset_head.hash();
				debug!(
					LOGGER,
					"fast_sync: before txhashset request, header head: {} / {}, txhashset_head: {} / {}",
					header_head.height,
					header_head.last_block_h,
					txhashset_head.height,
					bhash
				);
				if let Err(e) = p.send_txhashset_request(txhashset_head.height, bhash) {
					error!(LOGGER, "fast_sync: send_txhashset_request err! {:?}", e);
					return Err(e);
				}
				return Ok(peer.clone());
			}
		}
		Err(p2p::Error::PeerException)
	}

	// For now this is a one-time thing (it can be slow) at initial startup.
	fn fast_sync_due(&mut self) -> (bool, bool) {
		let now = Utc::now();
		let mut download_timeout = false;

		match self.prev_fast_sync {
			None => {
				self.prev_fast_sync = Some(now);
				(true, download_timeout)
			}
			Some(prev) => {
				if now - prev > Duration::minutes(10) {
					download_timeout = true;
				}
				(false, download_timeout)
			}
		}
	}

	fn fast_sync_reset(&mut self) {
		self.prev_fast_sync = None;
		self.fast_sync_peer = None;
	}
}
<commit_msg>rustfmt<commit_after>// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use chrono::prelude::{DateTime, Utc};
use chrono::Duration;
use std::sync::{Arc, RwLock};

use chain;
use common::types::{Error, SyncState, SyncStatus};
use core::core::hash::Hashed;
use core::global;
use p2p::{self, Peer};
use util::LOGGER;

/// Fast sync has 3 "states":
/// * syncing headers
/// * once all headers are sync'd, requesting the txhashset state
/// * once we have the state, get blocks after that
///
/// The StateSync struct implements and monitors the middle step.
pub struct StateSync {
	sync_state: Arc<SyncState>,
	peers: Arc<p2p::Peers>,
	chain: Arc<chain::Chain>,
	archive_mode: bool,

	prev_fast_sync: Option<DateTime<Utc>>,
	fast_sync_peer: Option<Arc<RwLock<Peer>>>,
}

impl StateSync {
	pub fn new(
		sync_state: Arc<SyncState>,
		peers: Arc<p2p::Peers>,
		chain: Arc<chain::Chain>,
		archive_mode: bool,
	) -> StateSync {
		StateSync {
			sync_state,
			peers,
			chain,
			archive_mode,
			prev_fast_sync: None,
			fast_sync_peer: None,
		}
	}

	/// Check whether state sync should run and triggers a state download when
	/// it's time (we have all headers). Returns true as long as state sync
	/// needs monitoring, false when it's either done or turned off.
	pub fn check_run(
		&mut self,
		header_head: &chain::Tip,
		head: &chain::Tip,
		highest_height: u64,
	) -> bool {
		let need_state_sync = !self.archive_mode
			&& highest_height.saturating_sub(head.height) > global::cut_through_horizon() as u64;
		if !need_state_sync {
			return false;
		}

		let mut sync_need_restart = false;

		// check sync error
		{
			let clone = self.sync_state.sync_error();
			if let Some(ref sync_error) = *clone.read().unwrap() {
				error!(
					LOGGER,
					"fast_sync: error = {:?}. restart fast sync", sync_error
				);
				sync_need_restart = true;
			}
			drop(clone);
		}

		// check peer connection status of this sync
		if let Some(ref peer) = self.fast_sync_peer {
			if let Ok(p) = peer.try_read() {
				if !p.is_connected() && SyncStatus::TxHashsetDownload == self.sync_state.status() {
					sync_need_restart = true;
					info!(
						LOGGER,
						"fast_sync: peer connection lost: {:?}. restart", p.info.addr,
					);
				}
			}
		}

		if sync_need_restart {
			self.fast_sync_reset();
			self.sync_state.clear_sync_error();
		}

		// run fast sync if applicable, normally only run one-time, except restart in error
		if header_head.height == highest_height {
			let (go, download_timeout) = self.fast_sync_due();

			if download_timeout && SyncStatus::TxHashsetDownload == self.sync_state.status() {
				error!(
					LOGGER,
					"fast_sync: TxHashsetDownload status timeout in 10 minutes!"
				);
				self.sync_state
					.set_sync_error(Error::P2P(p2p::Error::Timeout));
			}

			if go {
				self.fast_sync_peer = None;
				match self.request_state(&header_head) {
					Ok(peer) => {
						self.fast_sync_peer = Some(peer);
					}
					Err(e) => self.sync_state.set_sync_error(Error::P2P(e)),
				}
				self.sync_state.update(SyncStatus::TxHashsetDownload);
			}
		}
		true
	}

	fn request_state(&self, header_head: &chain::Tip) -> Result<Arc<RwLock<Peer>>, p2p::Error> {
		let horizon = global::cut_through_horizon() as u64;

		if let Some(peer) = self.peers.most_work_peer() {
			if let Ok(p) = peer.try_read() {
				// ask for txhashset at 90% of horizon, this still leaves time for download
				// and validation to happen and stay within horizon
				let mut txhashset_head = self
					.chain
					.get_block_header(&header_head.prev_block_h)
					.unwrap();
				for _ in 0..(horizon - horizon / 10) {
					txhashset_head = self
						.chain
						.get_block_header(&txhashset_head.previous)
						.unwrap();
				}
				let bhash = txhashset_head.hash();
				debug!(
					LOGGER,
					"fast_sync: before txhashset request, header head: {} / {}, txhashset_head: {} / {}",
					header_head.height,
					header_head.last_block_h,
					txhashset_head.height,
					bhash
				);
				if let Err(e) = p.send_txhashset_request(txhashset_head.height, bhash) {
					error!(LOGGER, "fast_sync: send_txhashset_request err! {:?}", e);
					return Err(e);
				}
				return Ok(peer.clone());
			}
		}
		Err(p2p::Error::PeerException)
	}

	// For now this is a one-time thing (it can be slow) at initial startup.
	fn fast_sync_due(&mut self) -> (bool, bool) {
		let now = Utc::now();
		let mut download_timeout = false;

		match self.prev_fast_sync {
			None => {
				self.prev_fast_sync = Some(now);
				(true, download_timeout)
			}
			Some(prev) => {
				if now - prev > Duration::minutes(10) {
					download_timeout = true;
				}
				(false, download_timeout)
			}
		}
	}

	fn fast_sync_reset(&mut self) {
		self.prev_fast_sync = None;
		self.fast_sync_peer = None;
	}
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
extern crate serialize;
extern crate chrono;

//use std::collections::HashMap;
use serialize::json;
use serialize::json::{
    Json,
    String,
    F64,
    U64,
    I64,
    List,
    Null,
};
use std::io;
use chrono::NaiveDateTime;

#[deriving(Show)]
pub struct Event {
    client: Client,
    check: Check,
    occurences: Vec<i32>,
    action: String,
}

#[deriving(Show)]
pub struct Client {
    name: String,
    address: String,
    subscriptions: Vec<String>,
    timestamp: NaiveDateTime,
    additional: Json
}

#[deriving(Show)]
pub struct Check {
    name: String,
    issued: NaiveDateTime,
    output: String,
    status: i8,
    command: String,
    subscribers: Vec<String>,
    interval: i32,
    handler: Option<String>,
    handlers: Option<Vec<String>>,
    history: Vec<i8>,
    flapping: bool,
    additional: Json
}

#[deriving(Show)]
pub enum SensuError {
    InitError(String),
    EventError(String)
}

macro_rules! jk(
    ($j:ident->$k:expr $p:ident) => (
        match $j.find($k) {
            Some(value) => match value {
                &$p(ref v) => v.clone(),
                _ => return Err(EventError(format!("Wrong type for key: {}", value)))
            },
            None => return Err(EventError(format!("couldn't find {} in event", $k)))
        }
    )
)

pub fn read_stdin() -> Result<String, SensuError> {
    match io::stdin().read_to_end() {
        Ok(input) => Ok(input.to_string()),
        Err(e) => return Err(InitError(format!("couldn't read stdin: {}", e)))
    }
}

pub fn read_event(input: &str) -> Result<Client, SensuError> {
    let event = match json::from_str(input) {
        Ok(v) => v,
        Err(e) => return Err(InitError(format!("couldn't parse json: {}", e)))
    };

    let client = try!(read_client(event));
    Ok(client)
}

fn read_client(input: Json) -> Result<Client, SensuError> {
    let event = match input.find("client") {
        Some(client) => client,
        None => return Err(InitError("No client in event".into_string()))
    };

    let unverified_subs = jk!(event->"subscriptions" List);
    let mut subs: Vec<String> = Vec::new();
    for sub in unverified_subs.iter() {
        match *sub {
            json::String(ref s) => subs.push(s.clone()),
            _ => return Err(EventError(format!("Invalid subscription type {}", sub)))
        }
    }

    let client = Client {
        name: jk!(event->"name" String),
        address: jk!(event->"address" String),
        subscriptions: subs,
        timestamp: NaiveDateTime::from_num_seconds_from_unix_epoch(
            match event.find("timestamp") {
                Some(value) => match value {
                    &I64(ref v) => v.clone(),
                    &U64(ref v) => v.clone() as i64,
                    &F64(ref v) => v.clone() as i64,
                    _ => return Err(EventError(format!("Wrong type for key: {}", value)))
                },
                None => return Err(EventError("couldn't find timestamp in event".into_string()))
            }, 0),
        additional: Null
    };
    Ok(client)
}

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

    #[test]
    fn can_build_client() {
        let client = read_event(r#"{
            "client": {
                "name": "hello",
                "address": "192.168.1.1",
                "subscriptions": ["one", "two"],
                "timestamp": 127897
            }
        }"#);
        match client {
            Ok(cl) => println!("{}", cl),
            Err(e) => panic!("ERROR: {}", e)
        }
    }
}
<commit_msg>Test only the client part of read_event<commit_after>#![feature(macro_rules)]
extern crate serialize;
extern crate chrono;

//use std::collections::HashMap;
use serialize::json;
use serialize::json::{
    Json,
    String,
    F64,
    U64,
    I64,
    List,
    Null,
};
use std::io;
use chrono::NaiveDateTime;

#[deriving(Show)]
pub struct Event {
    client: Client,
    check: Check,
    occurences: Vec<i32>,
    action: String,
}

#[deriving(Show)]
pub struct Client {
    name: String,
    address: String,
    subscriptions: Vec<String>,
    timestamp: NaiveDateTime,
    additional: Json
}

#[deriving(Show)]
pub struct Check {
    name: String,
    issued: NaiveDateTime,
    output: String,
    status: i8,
    command: String,
    subscribers: Vec<String>,
    interval: i32,
    handler: Option<String>,
    handlers: Option<Vec<String>>,
    history: Vec<i8>,
    flapping: bool,
    additional: Json
}

#[deriving(Show)]
pub enum SensuError {
    InitError(String),
    EventError(String)
}

macro_rules! jk(
    ($j:ident->$k:expr $p:ident) => (
        match $j.find($k) {
            Some(value) => match value {
                &$p(ref v) => v.clone(),
                _ => return Err(EventError(format!("Wrong type for key: {}", value)))
            },
            None => return Err(EventError(format!("couldn't find {} in event", $k)))
        }
    )
)

pub fn read_stdin() -> Result<String, SensuError> {
    match io::stdin().read_to_end() {
        Ok(input) => Ok(input.to_string()),
        Err(e) => return Err(InitError(format!("couldn't read stdin: {}", e)))
    }
}

pub fn read_event(input: &str) -> Result<Client, SensuError> {
    let event = match json::from_str(input) {
        Ok(v) => v,
        Err(e) => return Err(InitError(format!("couldn't parse json: {}", e)))
    };

    let client = try!(read_client(event));
    Ok(client)
}

fn read_client(input: Json) -> Result<Client, SensuError> {
    let event = match input.find("client") {
        Some(client) => client,
        None => return Err(InitError("No client in event".into_string()))
    };

    let unverified_subs = jk!(event->"subscriptions" List);
    let mut subs: Vec<String> = Vec::new();
    for sub in unverified_subs.iter() {
        match *sub {
            json::String(ref s) => subs.push(s.clone()),
            _ => return Err(EventError(format!("Invalid subscription type {}", sub)))
        }
    }

    let client = Client {
        name: jk!(event->"name" String),
        address: jk!(event->"address" String),
        subscriptions: subs,
        timestamp: NaiveDateTime::from_num_seconds_from_unix_epoch(
            match event.find("timestamp") {
                Some(value) => match value {
                    &I64(ref v) => v.clone(),
                    &U64(ref v) => v.clone() as i64,
                    &F64(ref v) => v.clone() as i64,
                    _ => return Err(EventError(format!("Wrong type for key: {}", value)))
                },
                None => return Err(EventError("couldn't find timestamp in event".into_string()))
            }, 0),
        additional: Null
    };
    Ok(client)
}

#[cfg(test)]
mod build_objects {
    use serialize::json;
    use super::read_client;

    #[test]
    fn can_build_client() {
        let event = json::from_str(r#"{
            "client": {
                "name": "hello",
                "address": "192.168.1.1",
                "subscriptions": ["one", "two"],
                "timestamp": 127897
            }
        }"#).unwrap();
        let client = read_client(event);
        match client {
            Ok(cl) => println!("Parsed: {}", cl),
            Err(e) => panic!("ERROR: {}", e)
        }
    }
}
<|endoftext|>


<commit_before>#![feature(core, hash)]

extern crate semver;

use std::collections::HashMap;
use std::error::Error;
use std::old_io::net::ip::IpAddr;

pub use self::typemap::TypeMap;
mod typemap;

#[derive(PartialEq, Show, Clone, Copy)]
pub enum Scheme {
    Http,
    Https
}

#[derive(PartialEq, Show, Clone, Copy)]
pub enum Host<'a> {
    Name(&'a str),
    Ip(IpAddr)
}

#[derive(PartialEq, Hash, Eq, Show, Clone, Copy)]
pub enum Method {
    Get,
    Post,
    Put,
    Delete,
    Head,
    Connect,
    Options,
    Trace,

    // RFC-5789
    Patch,
    Purge,

    // WebDAV, Subversion, UPNP
    Other(&'static str)
}

/// A Dictionary for extensions provided by the server or middleware
pub type Extensions = TypeMap;

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method(&self) -> Method;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<u64>;

    /// The request's headers, as conduit::Headers.
    fn headers<'a>(&'a self) -> &'a Headers;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;

    /// A readable map of extensions
    fn extensions<'a>(&'a self) -> &'a Extensions;

    /// A mutable map of extensions
    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions;
}

pub trait Headers {
    /// Find the value of a given header. Multi-line headers are represented
    /// as an array.
    fn find(&self, key: &str) -> Option<Vec<&str>>;

    /// Returns true if a particular header exists
    fn has(&self, key: &str) -> bool;

    /// Iterate over all of the available headers.
    fn all(&self) -> Vec<(&str, Vec<&str>)>;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (u32, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, Vec<String>>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

/// A Handler takes a request and returns a response or an error.
/// By default, a bare function implements `Handler`.
pub trait Handler : Sync + Send {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>>;
}

impl<F> Handler for F
    where F: Fn(&mut Request) -> Result<Response, Box<Error+Send>> + Sync + Send,
{
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>> {
        (*self)(request)
    }
}
<commit_msg>Update with associated type for `FnMut`<commit_after>#![feature(core, hash)]

extern crate semver;

use std::collections::HashMap;
use std::error::Error;
use std::old_io::net::ip::IpAddr;

pub use self::typemap::TypeMap;
mod typemap;

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Scheme {
    Http,
    Https
}

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Host<'a> {
    Name(&'a str),
    Ip(IpAddr)
}

#[derive(PartialEq, Hash, Eq, Debug, Clone, Copy)]
pub enum Method {
    Get,
    Post,
    Put,
    Delete,
    Head,
    Connect,
    Options,
    Trace,

    // RFC-5789
    Patch,
    Purge,

    // WebDAV, Subversion, UPNP
    Other(&'static str)
}

/// A Dictionary for extensions provided by the server or middleware
pub type Extensions = TypeMap;

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method(&self) -> Method;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<u64>;

    /// The request's headers, as conduit::Headers.
    fn headers<'a>(&'a self) -> &'a Headers;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;

    /// A readable map of extensions
    fn extensions<'a>(&'a self) -> &'a Extensions;

    /// A mutable map of extensions
    fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions;
}

pub trait Headers {
    /// Find the value of a given header. Multi-line headers are represented
    /// as an array.
    fn find(&self, key: &str) -> Option<Vec<&str>>;

    /// Returns true if a particular header exists
    fn has(&self, key: &str) -> bool;

    /// Iterate over all of the available headers.
    fn all(&self) -> Vec<(&str, Vec<&str>)>;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (u32, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, Vec<String>>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

/// A Handler takes a request and returns a response or an error.
/// By default, a bare function implements `Handler`.
pub trait Handler: Sync + Send {
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>>;
}

impl<F, E> Handler for F
    where F: Fn(&mut Request) -> Result<Response, E> + Sync + Send,
          E: Error + Send
{
    fn call(&self, request: &mut Request) -> Result<Response, Box<Error+Send>> {
        (*self)(request).map_err(|e| Box::new(e) as Box<Error+Send>)
    }
}
<|endoftext|>


<commit_before>//! This crate is a port of
//! [Haskell's QuickCheck](http://hackage.haskell.org/package/QuickCheck).
//!
//! For detailed examples, please see the
//! [README](https://github.com/BurntSushi/quickcheck).

#![crate_name = "quickcheck"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/quickcheck")]

#![allow(unused_features)]
#![feature(collections, core, io, std_misc)]

#[cfg(feature = "collect_impls")]
extern crate collect;
#[macro_use] extern crate log;
extern crate rand;

pub use arbitrary::{
    Arbitrary, Gen, StdGen, Shrinker,
    empty_shrinker, single_shrinker,
};
pub use tester::{QuickCheck, Testable, TestResult, quickcheck};

mod arbitrary;
mod tester;

#[cfg(test)]
mod tests;
<commit_msg>rustup<commit_after>//! This crate is a port of
//! [Haskell's QuickCheck](http://hackage.haskell.org/package/QuickCheck).
//!
//! For detailed examples, please see the
//! [README](https://github.com/BurntSushi/quickcheck).

#![crate_name = "quickcheck"]
#![doc(html_root_url = "http://burntsushi.net/rustdoc/quickcheck")]

#![allow(unused_features)]
#![feature(collections, core, hash, io, std_misc)]

#[cfg(feature = "collect_impls")]
extern crate collect;
#[macro_use] extern crate log;
extern crate rand;

pub use arbitrary::{
    Arbitrary, Gen, StdGen, Shrinker,
    empty_shrinker, single_shrinker,
};
pub use tester::{QuickCheck, Testable, TestResult, quickcheck};

mod arbitrary;
mod tester;

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>// Copyright 2016 Mikkel Kroman <mk@uplink.io>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
//! SoundCloud API library
//!
//! This soundcloud library provides an interface where you can query soundcloud for information
//! about tracks and users.
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate url;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;

/// The static host address for the API.
pub const API_HOST: &'static str = "api.soundcloud.com";

pub mod error;
pub mod client;
pub mod track;

// Re-export commonly used resources.
pub use track::Track;
pub use client::{User, Comment, App};
pub use client::Client;

<commit_msg>Pub-export the error type<commit_after>// Copyright 2016 Mikkel Kroman <mk@uplink.io>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
//! SoundCloud API library
//!
//! This soundcloud library provides an interface where you can query soundcloud for information
//! about tracks and users.
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate url;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;

/// The static host address for the API.
pub const API_HOST: &'static str = "api.soundcloud.com";

pub mod error;
pub mod client;
pub mod track;

// Re-export commonly used resources.
pub use track::Track;
pub use client::{User, Comment, App};
pub use client::Client;
pub use error::Error;

<|endoftext|>


<commit_before>use std::fs;
use std::io;
use std::io::{Write,Read};
use std::path::PathBuf;
#[macro_use]
extern crate json;

struct Config {
    class_name: String,
    master_repo: String,
    description: String
}

struct Student {
    name: String,
    repo: String
}

pub fn new(name: &str) {
    match fs::create_dir(name) {
        Ok(v) => init(name),
        Err(e) => println!("Couldn't create: {}",e)
    }
}

pub fn init(path: &str) {
    println!("initalizing at {}", path);
    let config: Config = get_init_options();
    let config_json = object!{
        "className" => config.class_name.trim(),
        "description" => config.description.trim(),
        "masterRepo" => config.master_repo.trim(),
        "students" => json::JsonValue::new_array()
    };
    write_config(json::stringify_pretty(config_json,4), path)
}

pub fn add() {
    let mut f = fs::File::open("gitclass.json").unwrap();
    let mut config_str = String::new();
    f.read_to_string(&mut config_str);
    let mut config_json = json::parse(config_str.as_str()).unwrap();
    let student = get_student_details();
    let student_json = object!(
        "name" => student.name.trim(),
        "repo" => student.repo.trim()
    );
    config_json["students"].push(student_json);
    write_config(json::stringify_pretty(config_json,4), "./");
}

fn write_config(data: String, path: &str) {
    let mut init_path: PathBuf = PathBuf::from(path);
    init_path.push("gitclass.json");
    let mut f = fs::File::create(init_path.as_path()).unwrap();
    // let out_str = json::stringify_pretty(obj, 4);
    println!("{}",data);
    f.write(data.as_bytes());
}

fn get_init_options() -> Config {
    let mut class_name = String::new();
    println!("Enter your class's name: ");
    io::stdin().read_line(&mut class_name);
    let mut master_repo = String::new();
    println!("Enter the master repo: ");
    io::stdin().read_line(&mut master_repo);
    println!("Enter the description: ");
    let mut description = String::new();
    io::stdin().read_line(&mut description);
    return Config {
        class_name: class_name,
        master_repo: master_repo,
        description: description
    }
}

fn get_student_details() -> Student {
    let mut name = String::new();
    println!("Student name: ");
    io::stdin().read_line(&mut name);
    let mut repo = String::new();
    println!("Student repo: ");
    io::stdin().read_line(&mut repo);
    return Student {
        name: name,
        repo: repo
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Add student functionality<commit_after>use std::fs;
use std::io;
use std::io::{Write,Read};
use std::path::PathBuf;
#[macro_use]
extern crate json;
extern crate git2;
use git2::Repository;

struct Config {
    class_name: String,
    master_repo: String,
    description: String
}

struct Student {
    name: String,
    repo: String
}

pub fn new(name: &str) {
    match fs::create_dir(name) {
        Ok(v) => init(name),
        Err(e) => println!("Couldn't create: {}",e)
    }
}

pub fn init(path: &str) {
    println!("initalizing at {}", path);
    let config: Config = get_init_options();
    let config_json = object!{
        "className" => config.class_name.trim(),
        "description" => config.description.trim(),
        "masterRepo" => config.master_repo.trim(),
        "students" => json::JsonValue::new_array()
    };
    write_config(json::stringify_pretty(config_json,4), path)
}

pub fn add() {
    let mut f = fs::File::open("gitclass.json").unwrap();
    let mut config_str = String::new();
    f.read_to_string(&mut config_str);
    let mut config_json = json::parse(config_str.as_str()).unwrap();
    let student = get_student_details();
    let student_json = object!(
        "name" => student.name.trim(),
        "repo" => student.repo.trim()
    );
    config_json["students"].push(student_json);
    write_config(json::stringify_pretty(config_json,4), "./");
    clone_repo(student.repo.as_str(), student.name.as_str());
}

fn write_config(data: String, path: &str) {
    let mut init_path: PathBuf = PathBuf::from(path);
    init_path.push("gitclass.json");
    let mut f = fs::File::create(init_path.as_path()).unwrap();
    // let out_str = json::stringify_pretty(obj, 4);
    println!("{}",data);
    f.write(data.as_bytes());
}

fn get_init_options() -> Config {
    let mut class_name = String::new();
    println!("Enter your class's name: ");
    io::stdin().read_line(&mut class_name);
    let mut master_repo = String::new();
    println!("Enter the master repo: ");
    io::stdin().read_line(&mut master_repo);
    println!("Enter the description: ");
    let mut description = String::new();
    io::stdin().read_line(&mut description);
    return Config {
        class_name: class_name,
        master_repo: master_repo,
        description: description
    }
}

fn get_student_details() -> Student {
    let mut name = String::new();
    println!("Student name: ");
    io::stdin().read_line(&mut name);
    let mut repo = String::new();
    println!("Student repo: ");
    io::stdin().read_line(&mut repo);
    return Student {
        name: name,
        repo: repo
    }
}

fn clone_repo(url: &str, path: &str) -> git2::Repository {
    match Repository::clone(url.trim(), path.trim()) {
        Ok(repo) => repo,
        Err(e) => panic!("failed to clone: {}", e),
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Terminal formatting library.
//!
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
//! Terminal][ansi] to provide color printing, among other things. There are two implementations,
//! the `TerminfoTerminal`, which uses control characters from a
//! [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
//! API][win].
//!
//! # Examples
//!
//! ```no_run
//! # #![allow(unstable)]
//! extern crate term;
//!
//! fn main() {
//!     let mut t = term::stdout().unwrap();
//!
//!     t.fg(term::color::GREEN).unwrap();
//!     (write!(t, "hello, ")).unwrap();
//!
//!     t.fg(term::color::RED).unwrap();
//!     (writeln!(t, "world!")).unwrap();
//!
//!     assert!(t.reset().unwrap());
//! }
//! ```
//!
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![feature(int_uint)]
#![deny(missing_docs)]
#![allow(unstable)]

#[macro_use] extern crate log;

pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
pub use win::WinConsole;

use std::io::{IoResult, LineBufferedWriter};
use std::io::stdio::StdWriter;

pub mod terminfo;

#[cfg(windows)]
mod win;

/// Alias for stderr/stdout terminals.
pub type StdTerminal = Terminal<LineBufferedWriter<StdWriter>> + Send;

#[cfg(not(windows))]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    })
}

#[cfg(windows)]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }).or_else(|| WinConsole::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }))
}

#[cfg(not(windows))]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    })
}

#[cfg(windows)]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }).or_else(|| WinConsole::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }))
}

/// Terminal color definitions
pub mod color {
    /// Number for a terminal color
    pub type Color = u16;

    pub const BLACK:   Color = 0;
    pub const RED:     Color = 1;
    pub const GREEN:   Color = 2;
    pub const YELLOW:  Color = 3;
    pub const BLUE:    Color = 4;
    pub const MAGENTA: Color = 5;
    pub const CYAN:    Color = 6;
    pub const WHITE:   Color = 7;

    pub const BRIGHT_BLACK:   Color = 8;
    pub const BRIGHT_RED:     Color = 9;
    pub const BRIGHT_GREEN:   Color = 10;
    pub const BRIGHT_YELLOW:  Color = 11;
    pub const BRIGHT_BLUE:    Color = 12;
    pub const BRIGHT_MAGENTA: Color = 13;
    pub const BRIGHT_CYAN:    Color = 14;
    pub const BRIGHT_WHITE:   Color = 15;
}

/// Terminal attributes for use with term.attr().
///
/// Most attributes can only be turned on and must be turned off with term.reset().
/// The ones that can be turned off explicitly take a boolean value.
/// Color is also represented as an attribute for convenience.
#[derive(Copy)]
pub enum Attr {
    /// Bold (or possibly bright) mode
    Bold,
    /// Dim mode, also called faint or half-bright. Often not supported
    Dim,
    /// Italics mode. Often not supported
    Italic(bool),
    /// Underline mode
    Underline(bool),
    /// Blink mode
    Blink,
    /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
    Standout(bool),
    /// Reverse mode, inverts the foreground and background colors
    Reverse,
    /// Secure mode, also called invis mode. Hides the printed text
    Secure,
    /// Convenience attribute to set the foreground color
    ForegroundColor(color::Color),
    /// Convenience attribute to set the background color
    BackgroundColor(color::Color)
}

/// A terminal with similar capabilities to an ANSI Terminal
/// (foreground/background colors etc).
pub trait Terminal<T: Writer>: Writer {
    /// Sets the foreground color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn fg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the background color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn bg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
    /// there was an I/O error.
    fn attr(&mut self, attr: Attr) -> IoResult<bool>;

    /// Returns whether the given terminal attribute is supported.
    fn supports_attr(&self, attr: Attr) -> bool;

    /// Resets all terminal attributes and color to the default.
    ///
    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
    /// was an I/O error.
    fn reset(&mut self) -> IoResult<bool>;

    /// Gets an immutable reference to the stream inside
    fn get_ref<'a>(&'a self) -> &'a T;

    /// Gets a mutable reference to the stream inside
    fn get_mut<'a>(&'a mut self) -> &'a mut T;
}

/// A terminal which can be unwrapped.
pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
    /// Returns the contained stream, destroying the `Terminal`
    fn unwrap(self) -> T;
}
<commit_msg>Attr: derive a few more traits<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Terminal formatting library.
//!
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
//! Terminal][ansi] to provide color printing, among other things. There are two implementations,
//! the `TerminfoTerminal`, which uses control characters from a
//! [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
//! API][win].
//!
//! # Examples
//!
//! ```no_run
//! # #![allow(unstable)]
//! extern crate term;
//!
//! fn main() {
//!     let mut t = term::stdout().unwrap();
//!
//!     t.fg(term::color::GREEN).unwrap();
//!     (write!(t, "hello, ")).unwrap();
//!
//!     t.fg(term::color::RED).unwrap();
//!     (writeln!(t, "world!")).unwrap();
//!
//!     assert!(t.reset().unwrap());
//! }
//! ```
//!
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]
#![feature(int_uint)]
#![deny(missing_docs)]
#![allow(unstable)]

#[macro_use] extern crate log;

pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
pub use win::WinConsole;

use std::io::{IoResult, LineBufferedWriter};
use std::io::stdio::StdWriter;

pub mod terminfo;

#[cfg(windows)]
mod win;

/// Alias for stderr/stdout terminals.
pub type StdTerminal = Terminal<LineBufferedWriter<StdWriter>> + Send;

#[cfg(not(windows))]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    })
}

#[cfg(windows)]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }).or_else(|| WinConsole::new(std::io::stdout()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }))
}

#[cfg(not(windows))]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    })
}

#[cfg(windows)]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StdTerminal>> {
    TerminfoTerminal::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }).or_else(|| WinConsole::new(std::io::stderr()).map(|t| {
        Box::new(t) as Box<StdTerminal>
    }))
}

/// Terminal color definitions
pub mod color {
    /// Number for a terminal color
    pub type Color = u16;

    pub const BLACK:   Color = 0;
    pub const RED:     Color = 1;
    pub const GREEN:   Color = 2;
    pub const YELLOW:  Color = 3;
    pub const BLUE:    Color = 4;
    pub const MAGENTA: Color = 5;
    pub const CYAN:    Color = 6;
    pub const WHITE:   Color = 7;

    pub const BRIGHT_BLACK:   Color = 8;
    pub const BRIGHT_RED:     Color = 9;
    pub const BRIGHT_GREEN:   Color = 10;
    pub const BRIGHT_YELLOW:  Color = 11;
    pub const BRIGHT_BLUE:    Color = 12;
    pub const BRIGHT_MAGENTA: Color = 13;
    pub const BRIGHT_CYAN:    Color = 14;
    pub const BRIGHT_WHITE:   Color = 15;
}

/// Terminal attributes for use with term.attr().
///
/// Most attributes can only be turned on and must be turned off with term.reset().
/// The ones that can be turned off explicitly take a boolean value.
/// Color is also represented as an attribute for convenience.
#[derive(Show, PartialEq, Eq, Copy)]
pub enum Attr {
    /// Bold (or possibly bright) mode
    Bold,
    /// Dim mode, also called faint or half-bright. Often not supported
    Dim,
    /// Italics mode. Often not supported
    Italic(bool),
    /// Underline mode
    Underline(bool),
    /// Blink mode
    Blink,
    /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
    Standout(bool),
    /// Reverse mode, inverts the foreground and background colors
    Reverse,
    /// Secure mode, also called invis mode. Hides the printed text
    Secure,
    /// Convenience attribute to set the foreground color
    ForegroundColor(color::Color),
    /// Convenience attribute to set the background color
    BackgroundColor(color::Color)
}

/// A terminal with similar capabilities to an ANSI Terminal
/// (foreground/background colors etc).
pub trait Terminal<T: Writer>: Writer {
    /// Sets the foreground color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn fg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the background color to the given color.
    ///
    /// If the color is a bright color, but the terminal only supports 8 colors,
    /// the corresponding normal color will be used instead.
    ///
    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
    /// if there was an I/O error.
    fn bg(&mut self, color: color::Color) -> IoResult<bool>;

    /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
    /// there was an I/O error.
    fn attr(&mut self, attr: Attr) -> IoResult<bool>;

    /// Returns whether the given terminal attribute is supported.
    fn supports_attr(&self, attr: Attr) -> bool;

    /// Resets all terminal attributes and color to the default.
    ///
    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
    /// was an I/O error.
    fn reset(&mut self) -> IoResult<bool>;

    /// Gets an immutable reference to the stream inside
    fn get_ref<'a>(&'a self) -> &'a T;

    /// Gets a mutable reference to the stream inside
    fn get_mut<'a>(&'a mut self) -> &'a mut T;
}

/// A terminal which can be unwrapped.
pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
    /// Returns the contained stream, destroying the `Terminal`
    fn unwrap(self) -> T;
}
<|endoftext|>