<commit_before>use std::collections::VecDeque;
use std::collections::HashSet;

/// A graph is represeted by as a weighted
/// [Adjenceny matrix](http://en.wikipedia.org/wiki/Adjacency_matrix)
pub struct Graph {
  /// The underlaying graph represented here with weights as an i32 (should
  /// probably be generic) the graph is represented as an
  /// [Adjenceny matrix](http://en.wikipedia.org/wiki/Adjacency_matrix) of
  /// Optionals, where None indicates that there doesn't exist a vertex and
  /// Some<i32> indicates that There is a vertex of weight i32.
  graph: Vec<Vec<Option<i32>>>
}
impl Graph {
  /// `new` allows for initializing the graph struct with a given adjecency matrix
  ///
  /// ## Arguments
  /// * `input` - an adjecency matrix in made out of a two-dimensional `Vec` of
  ///    weights. Weights are represented as `i32`:s and can thus be positive or
  ///    negative numbers.
  ///
  /// ## Example
  /// ```ignore
  ///  let rawgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None],
  ///                      vec![   None,  Some(0),     None,     None,     None,     None],
  ///                      vec![   None,     None,  Some(0),     None,     None,     None],
  ///                      vec![   None,     None,     None,  Some(0), Some(50),     None],
  ///                      vec![   None,     None, Some(20),     None,  Some(0), Some(50)],
  ///                      vec![   None,     None,     None,     None,     None,  Some(0)]];
  /// let g = Graph::new(rawgraph);
  /// ```
  pub fn new(input: Vec<Vec<Option<i32>>>) -> Graph { Graph { graph: input } }

  /*
  1  procedure BFS(G,v) is
  2      let Q be a queue
  3      Q.push(v)
  4      label v as discovered
  5      while Q is not empty
  6         v ← Q.pop()
  7         for all edges from v to w in G.adjacentEdges(v) do
  8             if w is not labeled as discovered
  9                 Q.push(w)
  10                label w as discovered
  */
  /// `breadth_first_search` implements breadth first search from `start` to the
  /// `target` and returns the path found as a `VecDeque<usize>` of nodes. This
  /// is an optional type as there might not be a path.
  ///
  /// **NOTE** as this is breadth first search this search ignores any assigned
  /// weight to nodes.
  ///
  /// ## Arguments
  /// * `start`  - an `usize` designating the start node, or row in the adjecency matrix
  /// * `target` - an `usize` designating the target node, or row in the adjecency matrix
  ///
  /// ## Returns
  /// Either the found path between start and target as a `VecDeque` of `usize`:s
  /// or `None` if there is no path.
  pub fn breadth_first_search(&self, start: usize, target: usize) -> Option<VecDeque<usize>> {
    return self.inner_search(start, target, true)
  }

  /// `depth_first_search` implements depth first search from `start` to the
  /// `target` and returns the path found as a `VecDeque<usize>` of nodes. This
  /// is an optional type as there might not be a path.
  ///
  /// **NOTE** as this is depth first search this search ignores any assigned
  /// weight to nodes.
  ///
  /// ## Arguments
  /// * `start`  - an `usize` designating the start node, or row in the adjecency matrix
  /// * `target` - an `usize` designating the target node, or row in the adjecency matrix
  ///
  /// ## Returns
  /// Either the found path between start and target as a `VecDeque` of `usize`:s
  /// or `None` if there is no path.
  pub fn depth_first_search(&self, start: usize, target: usize) -> Option<VecDeque<usize>> {
    return self.inner_search(start, target, false)
  }

  fn inner_search(&self, start: usize, target: usize, bfs: bool) -> Option<VecDeque<usize>>  {
    let mut q: VecDeque<usize> = VecDeque::new();
    let mut discovered: HashSet<usize> = HashSet::new();
    let mut prev: Vec<usize> = Vec::with_capacity(self.graph.len());
    let mut pathfound = false;
    for _ in (0..self.graph.len()) { prev.push(0); }

    q.push_back(start);
    discovered.insert(start);

    while !q.is_empty() {
      let mut v: Option<usize>;
      if bfs {
        v = q.pop_front()
      } else {
        v = q.pop_back();
      }
      match v {
        None => {}, // q is empty
        Some(v) => { // we are working on a new layer, branch the queue?
          if !discovered.contains(&v) {
            discovered.insert(v);
          }
          if v == target {
            pathfound = true;
          }
          for i in (0..self.graph[v].len()) {
            match self.graph[v][i] {
              None => {}, // no vertex between v and i
              Some(_) => {
                if !discovered.contains(&i) {
                  q.push_back(i);
                  prev[i]=v; //track prev (v) on i
                }
              }
            }
          }
        }
      }
    }
    if pathfound {
      let mut path: VecDeque<usize> = VecDeque::new();
      let mut curr = target;
      // backtrack over the prev array to construct the path
      while curr != start {
        path.push_front(curr);
        curr = prev[curr];
      }
      path.push_front(start);
      return Some(path)
    }
    return None
  }
}

#[test]
fn breadth_first_search_test() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0), Some(50),  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 6;
  let g = Graph::new(testgraph);
  let res = g.breadth_first_search(start, target);
  match res {
    None => {
      println!("Breadth first search returned None");
      assert!(false);
    }
    Some(result) => {
      println!("Breadth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
    }
  }
}

#[test]
fn breadth_first_search_test_no_valid_path() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0),     None,  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 5; // There is no valid path between 0 and 5
  let g = Graph::new(testgraph);
  let res = g.breadth_first_search(start, target);

  // The expected return value is None
  match res {
    None => {
      println!("Breadth first search returned None");
      assert!(true);
    }
    Some(result) => {
      println!("Breadth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
      assert!(false);
    }
  }
}

#[test]
fn depth_first_search_test() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0), Some(50),  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 6;
  let g = Graph::new(testgraph);
  let res = g.depth_first_search(start, target);
  match res {
    None => {
      println!("Depth first search returned None");
      assert!(false);
    }
    Some(result) => {
      println!("Depth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
    }
  }
}

#[test]
fn depth_first_search_test_no_valid_path() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0),     None,  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 5; // There is no valid path between 0 and 5
  let g = Graph::new(testgraph);
  let res = g.depth_first_search(start, target);

  // The expected return value is None
  match res {
    None => {
      println!("Depth first search returned None");
      assert!(true);
    }
    Some(result) => {
      println!("Depth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
      assert!(false);
    }
  }
}
<commit_msg>Cleaned up formatting slightly<commit_after>use std::collections::VecDeque;
use std::collections::HashSet;

/// A graph is represeted by as a weighted
/// [Adjenceny matrix](http://en.wikipedia.org/wiki/Adjacency_matrix)
pub struct Graph {
  /// The underlaying graph represented here with weights as an i32 (should
  /// probably be generic) the graph is represented as an
  /// [Adjenceny matrix](http://en.wikipedia.org/wiki/Adjacency_matrix) of
  /// Optionals, where None indicates that there doesn't exist a vertex and
  /// Some<i32> indicates that There is a vertex of weight i32.
  graph: Vec<Vec<Option<i32>>>
}
impl Graph {
  /// `new` allows for initializing the graph struct with a given adjecency matrix
  ///
  /// ## Arguments
  /// * `input` - an adjecency matrix in made out of a two-dimensional `Vec` of
  ///    weights. Weights are represented as `i32`:s and can thus be positive or
  ///    negative numbers.
  ///
  /// ## Example
  /// ```ignore
  ///  let rawgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None],
  ///                      vec![   None,  Some(0),     None,     None,     None,     None],
  ///                      vec![   None,     None,  Some(0),     None,     None,     None],
  ///                      vec![   None,     None,     None,  Some(0), Some(50),     None],
  ///                      vec![   None,     None, Some(20),     None,  Some(0), Some(50)],
  ///                      vec![   None,     None,     None,     None,     None,  Some(0)]];
  /// let g = Graph::new(rawgraph);
  /// ```
  pub fn new(input: Vec<Vec<Option<i32>>>) -> Graph { Graph { graph: input } }

  /// `breadth_first_search` implements breadth first search from `start` to the
  /// `target` and returns the path found as a `VecDeque<usize>` of nodes. This
  /// is an optional type as there might not be a path.
  ///
  /// **NOTE** as this is breadth first search this search ignores any assigned
  /// weight to nodes.
  ///
  /// ## Arguments
  /// * `start`  - an `usize` designating the start node, or row in the adjecency matrix
  /// * `target` - an `usize` designating the target node, or row in the adjecency matrix
  ///
  /// ## Returns
  /// Either the found path between start and target as a `VecDeque` of `usize`:s
  /// or `None` if there is no path.
  pub fn breadth_first_search(&self, start: usize, target: usize) -> Option<VecDeque<usize>> {
    return self.inner_search(start, target, true)
  }

  /// `depth_first_search` implements depth first search from `start` to the
  /// `target` and returns the path found as a `VecDeque<usize>` of nodes. This
  /// is an optional type as there might not be a path.
  ///
  /// **NOTE** as this is depth first search this search ignores any assigned
  /// weight to nodes.
  ///
  /// ## Arguments
  /// * `start`  - an `usize` designating the start node, or row in the adjecency matrix
  /// * `target` - an `usize` designating the target node, or row in the adjecency matrix
  ///
  /// ## Returns
  /// Either the found path between start and target as a `VecDeque` of `usize`:s
  /// or `None` if there is no path.
  pub fn depth_first_search(&self, start: usize, target: usize) -> Option<VecDeque<usize>> {
    return self.inner_search(start, target, false)
  }

  fn inner_search(&self, start: usize, target: usize, bfs: bool) -> Option<VecDeque<usize>>  {
    let mut q: VecDeque<usize> = VecDeque::new();
    let mut discovered: HashSet<usize> = HashSet::new();
    let mut prev: Vec<usize> = Vec::with_capacity(self.graph.len());
    let mut pathfound = false;
    for _ in (0..self.graph.len()) { prev.push(0); }

    q.push_back(start);
    discovered.insert(start);

    while !q.is_empty() {
      let mut v: Option<usize>;
      if bfs {
        v = q.pop_front()
      } else {
        v = q.pop_back();
      }
      match v {
        None => {}, // q is empty
        Some(v) => { // we are working on a new layer
          if !discovered.contains(&v) { discovered.insert(v); }
          if v == target { pathfound = true; }
          for i in (0..self.graph[v].len()) {
            match self.graph[v][i] {
              None => {}, // no vertex between v and i
              Some(_) => {
                if !discovered.contains(&i) {
                  q.push_back(i);
                  prev[i]=v; //track prev (v) on i
                }
              }
            }
          }
        }
      }
    }
    if pathfound {
      let mut path: VecDeque<usize> = VecDeque::new();
      let mut curr = target;
      // backtrack over the prev array to construct the path
      while curr != start {
        path.push_front(curr);
        curr = prev[curr];
      }
      path.push_front(start);
      return Some(path)
    }
    return None
  }
}

#[test]
fn breadth_first_search_test() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0), Some(50),  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 6;
  let g = Graph::new(testgraph);
  let res = g.breadth_first_search(start, target);
  match res {
    None => {
      println!("Breadth first search returned None");
      assert!(false);
    }
    Some(result) => {
      println!("Breadth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
    }
  }
}

#[test]
fn breadth_first_search_test_no_valid_path() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0),     None,  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 5; // There is no valid path between 0 and 5
  let g = Graph::new(testgraph);
  let res = g.breadth_first_search(start, target);

  // The expected return value is None
  match res {
    None => {
      println!("Breadth first search returned None");
      assert!(true);
    }
    Some(result) => {
      println!("Breadth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
      assert!(false);
    }
  }
}

#[test]
fn depth_first_search_test() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0), Some(50),  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 6;
  let g = Graph::new(testgraph);
  let res = g.depth_first_search(start, target);
  match res {
    None => {
      println!("Depth first search returned None");
      assert!(false);
    }
    Some(result) => {
      println!("Depth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
    }
  }
}

#[test]
fn depth_first_search_test_no_valid_path() {
  let testgraph = vec![vec![Some(0), Some(20), Some(80), Some(50),     None,     None, None],
                       vec![   None,  Some(0),     None,     None,     None,     None, None],
                       vec![   None,     None,  Some(0),     None,     None,     None,  Some(50)],
                       vec![   None,     None,     None,  Some(0), Some(50),     None, None],
                       vec![   None,     None, Some(20),     None,  Some(0),     None,  Some(40)],
                       vec![   None,     None,     None,     None,     None,  Some(0), None],
                       vec![   None,     None,     None,     None,     None,     None, Some(0)]];
  let start: usize = 0;
  let target: usize = 5; // There is no valid path between 0 and 5
  let g = Graph::new(testgraph);
  let res = g.depth_first_search(start, target);

  // The expected return value is None
  match res {
    None => {
      println!("Depth first search returned None");
      assert!(true);
    }
    Some(result) => {
      println!("Depth first search returned something: {:?}", result);
      assert_eq!(result[result.len()-1], target);
      assert_eq!(result[0], start);
      assert!(false);
    }
  }
}
<|endoftext|>


<commit_before>

pub mod graph {
    use std::collections::HashMap;
    use std::ops::Deref;
    use std::mem;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        // we transmute our Boxed vertex into a pointer later
        vertices: HashMap<i64, *mut Vertex>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, *mut Vertex> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;

            let mut v = Vertex::new(new_id);

            let ptr: *mut Vertex = unsafe { mem::transmute(v) };

            self.vertices.insert(new_id, ptr);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64)  {
        }
    }

    /*
    * storing in & out edges seperately should cut down on the number of "things" i have to traverse
    * if a vertex has 10k edges (5k in and out 5k out) then doing something like
    *   g(v).outV()
    * should be ok
    */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,

        // pointers on both sides, yay
        pub out_edges: Vec<*mut Edge>,
        pub in_edges:  Vec<*mut Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {
            Box::new(Vertex{id:id,
                            out_edges: Vec::new(),
                            in_edges: Vec::new()})
        }
    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Vertex,
    }

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Vertex;
            let out_vertex: &mut Vertex;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

            let mut edge: *mut Edge = unsafe { mem::transmute(e) };

            in_vertex.out_edges.push(edge);
            out_vertex.in_edges.push(edge);
        }

        pub fn query(self) {

        }
    }

    impl Deref for VertexProxy {
        type Target = Vertex;

        fn deref<'a>(&'a self) -> &'a Vertex {
            unsafe {
                &*(self.v)
            }
        }
    }

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Vertex,
        to_vertex: *const Vertex
    }

}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

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

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

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

        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct
    }
}
<commit_msg>edge proxy with deref<commit_after>

pub mod graph {
    use std::collections::HashMap;
    use std::ops::Deref;
    use std::mem;

    #[derive(Debug)]
    pub struct Graph {
        elements: i64,
        // we transmute our Boxed vertex into a pointer later
        vertices: HashMap<i64, *mut Vertex>,
    }

    impl Graph {
        pub fn new() -> Box<Graph> {
            let vertices: HashMap<i64, *mut Vertex> = HashMap::new();
            Box::new(Graph{elements:0, vertices:vertices})
        }

        pub fn add_vertex(&mut self) -> VertexProxy {
            let new_id = self.elements + 1;
            self.elements += 1;

            let mut v = Vertex::new(new_id);

            let ptr: *mut Vertex = unsafe { mem::transmute(v) };

            self.vertices.insert(new_id, ptr);

            // return the proxy which knows it's own id
            VertexProxy{id:new_id, v: ptr}
        }
        pub fn get(vertex_id:i64)  {
        }
    }

    /*
    * storing in & out edges seperately should cut down on the number of "things" i have to traverse
    * if a vertex has 10k edges (5k in and out 5k out) then doing something like
    *   g(v).outV()
    * should be ok
    */
    #[derive(Debug)]
    pub struct Vertex {
        pub id: i64,

        // pointers on both sides, yay
        pub out_edges: Vec<*mut Edge>,
        pub in_edges:  Vec<*mut Edge>,
    }

    impl Vertex {
        pub fn new(id: i64) -> Box<Vertex> {
            Box::new(Vertex{id:id,
                            out_edges: Vec::new(),
                            in_edges: Vec::new()})
        }
    }

    pub struct VertexProxy {
        pub id: i64,
        pub v: *mut Vertex,
    }

    impl VertexProxy {
        pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) {
            let in_vertex: &mut Vertex;
            let out_vertex: &mut Vertex;

            unsafe {
                in_vertex =  &mut *(self.v);
                out_vertex = &mut *(to_vertex.v);
            }

            // create the edge
            let mut e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

            let mut edge: *mut Edge = unsafe { mem::transmute(e) };

            in_vertex.out_edges.push(edge);
            out_vertex.in_edges.push(edge);
        }

        pub fn query(self) {

        }
    }

    impl Deref for VertexProxy {
        type Target = Vertex;

        fn deref<'a>(&'a self) -> &'a Vertex {
            unsafe {
                &*(self.v)
            }
        }
    }

    #[derive(Debug)]
    pub struct Edge {
        from_vertex: *const Vertex,
        to_vertex: *const Vertex
    }

    struct EdgeProxy {
        edge: *mut Edge
    }

    impl Deref for EdgeProxy {
        type Target = Edge;
        fn deref<'a>(&'a self) -> &'a Edge {
            unsafe { &*(self.edge) }
        }
    }

}

mod tests {
    use graph::{Graph, Vertex};

    #[test]
    fn test_unsafe_vertex() {
        let v = Vertex::new(1);

        let out_edges = &v.out_edges;
        let in_edges = &v.in_edges;
    }

    #[test]
    fn test_deref() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();
        let vertex = &*v1;
        assert!(vertex.id == 1);
    }

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

        assert_eq!(v1.id, 1);

        unsafe {
            let vertex = &*v1;
            assert_eq!((*v1).id, 1);
        }

        let v2 = g.add_vertex();
        assert!(v2.id == 2);
    }

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

        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);
        v1.add_edge(&mut v2);

        assert_eq!(v1.out_edges.len(), v2.in_edges.len());

        // ensure the vertex and edge pointers are correct
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
#[macro_use] extern crate log;
extern crate serde;
extern crate serde_json;
extern crate uuid;

pub mod core;
pub mod error;
pub mod priority;
pub mod result;
pub mod status;
pub mod task;

<commit_msg>Add missing modules<commit_after>extern crate chrono;
#[macro_use] extern crate log;
extern crate serde;
extern crate serde_json;
extern crate uuid;

pub mod core;
pub mod error;
pub mod priority;
pub mod project;
pub mod result;
pub mod status;
pub mod tag;
pub mod task;

<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate gl;
extern crate piston;
extern crate shader_version;

// External crates.
use std::sync::mpsc::Receiver;
use std::collections::VecDeque;
use glfw::Context;
use piston::input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use piston::window::{
    Window,
    AdvancedWindow,
    OpenGLWindow,
    ProcAddress,
    WindowSettings,
    Size
};

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: VecDeque<Input>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(mut win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::WindowHint::ContextVersion(major as u32, minor as u32));
        if opengl >= OpenGL::_3_2 {
            if cfg!(target_os = "macos") {
                glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
            }
            glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
        }
        if settings.get_samples() != 0 {
            glfw.window_hint(glfw::WindowHint::Samples(settings.get_samples() as u32));
        }

        if settings.get_vsync() {
            glfw.set_swap_interval(1);
        } else {
            glfw.set_swap_interval(0);
        }

        // Create GLFW window.
        let (mut window, events) = glfw.create_window(
            settings.get_size().width,
            settings.get_size().height,
            &settings.get_title(), glfw::WindowMode::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: settings.get_title(),
            exit_on_esc: settings.get_exit_on_esc(),
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::WindowEvent::Char(ch) => {
                    self.event_queue.push_back(Input::Text(ch.to_string()));
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::CursorPos(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => self.event_queue.push_back(
                            Input::Move(Motion::MouseRelative(x - lx, y - ly))
                        ),
                        None => ()
                    }
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::WindowEvent::Scroll(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseScroll(x, y)));
                }
                glfw::WindowEvent::Size(w, h) => {
                    self.event_queue.push_back(Input::Resize(w as u32, h as u32));
                }
                glfw::WindowEvent::Focus(focus) => {
                    self.event_queue.push_back(Input::Focus(focus));
                }
                _ => ()
            }
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }

    fn capture_cursor(&mut self, enabled: bool) {
        if enabled {
            self.window.set_cursor_mode(glfw::CursorMode::Disabled);
        } else {
            self.window.set_cursor_mode(glfw::CursorMode::Normal);
            self.last_mouse_pos = None;
        }
    }
}

impl Window for GlfwWindow {
    type Event = Input;

    fn size(&self) -> Size {
        let (w, h) = self.window.get_size();
        Size { width: w as u32, height: h as u32 }
    }

    fn draw_size(&self) -> Size {
        let (w, h) = self.window.get_framebuffer_size();
        Size { width: w as u32, height: h as u32 }
    }

    fn should_close(&self) -> bool {
        self.window.should_close()
    }

    fn swap_buffers(&mut self) {
        self.window.swap_buffers()
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.poll_event()
    }
}

impl AdvancedWindow for GlfwWindow {
    fn get_title(&self) -> String {
        self.title.clone()
    }

    fn set_title(&mut self, value: String) {
        self.window.set_title(&value)
    }

    fn get_exit_on_esc(&self) -> bool {
        self.exit_on_esc
    }

    fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value
    }

    fn set_capture_cursor(&mut self, value: bool) {
        self.capture_cursor(value)
    }
}

impl OpenGLWindow for GlfwWindow {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.window.get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.window.is_current()
    }

    fn make_current(&mut self) {
        self.window.make_current()
    }
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    use piston::input::keyboard::Key;

    match keycode {
        glfw::Key::Num0 => Key::D0,
        glfw::Key::Num1 => Key::D1,
        glfw::Key::Num2 => Key::D2,
        glfw::Key::Num3 => Key::D3,
        glfw::Key::Num4 => Key::D4,
        glfw::Key::Num5 => Key::D5,
        glfw::Key::Num6 => Key::D6,
        glfw::Key::Num7 => Key::D7,
        glfw::Key::Num8 => Key::D8,
        glfw::Key::Num9 => Key::D9,
        glfw::Key::A => Key::A,
        glfw::Key::B => Key::B,
        glfw::Key::C => Key::C,
        glfw::Key::D => Key::D,
        glfw::Key::E => Key::E,
        glfw::Key::F => Key::F,
        glfw::Key::G => Key::G,
        glfw::Key::H => Key::H,
        glfw::Key::I => Key::I,
        glfw::Key::J => Key::J,
        glfw::Key::K => Key::K,
        glfw::Key::L => Key::L,
        glfw::Key::M => Key::M,
        glfw::Key::N => Key::N,
        glfw::Key::O => Key::O,
        glfw::Key::P => Key::P,
        glfw::Key::Q => Key::Q,
        glfw::Key::R => Key::R,
        glfw::Key::S => Key::S,
        glfw::Key::T => Key::T,
        glfw::Key::U => Key::U,
        glfw::Key::V => Key::V,
        glfw::Key::W => Key::W,
        glfw::Key::X => Key::X,
        glfw::Key::Y => Key::Y,
        glfw::Key::Z => Key::Z,
        glfw::Key::Apostrophe => Key::Unknown,
        glfw::Key::Backslash => Key::Backslash,
        glfw::Key::Backspace => Key::Backspace,
        glfw::Key::CapsLock => Key::CapsLock,
        glfw::Key::Delete => Key::Delete,
        glfw::Key::Comma => Key::Comma,
        glfw::Key::Down => Key::Down,
        glfw::Key::End => Key::End,
        glfw::Key::Enter => Key::Return,
        glfw::Key::Equal => Key::Equals,
        glfw::Key::Escape => Key::Escape,
        glfw::Key::F1 => Key::F1,
        glfw::Key::F2 => Key::F2,
        glfw::Key::F3 => Key::F3,
        glfw::Key::F4 => Key::F4,
        glfw::Key::F5 => Key::F5,
        glfw::Key::F6 => Key::F6,
        glfw::Key::F7 => Key::F7,
        glfw::Key::F8 => Key::F8,
        glfw::Key::F9 => Key::F9,
        glfw::Key::F10 => Key::F10,
        glfw::Key::F11 => Key::F11,
        glfw::Key::F12 => Key::F12,
        glfw::Key::F13 => Key::F13,
        glfw::Key::F14 => Key::F14,
        glfw::Key::F15 => Key::F15,
        glfw::Key::F16 => Key::F16,
        glfw::Key::F17 => Key::F17,
        glfw::Key::F18 => Key::F18,
        glfw::Key::F19 => Key::F19,
        glfw::Key::F20 => Key::F20,
        glfw::Key::F21 => Key::F21,
        glfw::Key::F22 => Key::F22,
        glfw::Key::F23 => Key::F23,
        glfw::Key::F24 => Key::F24,
        // Possibly next code.
        glfw::Key::F25 => Key::Unknown,
        glfw::Key::Kp0 => Key::NumPad0,
        glfw::Key::Kp1 => Key::NumPad1,
        glfw::Key::Kp2 => Key::NumPad2,
        glfw::Key::Kp3 => Key::NumPad3,
        glfw::Key::Kp4 => Key::NumPad4,
        glfw::Key::Kp5 => Key::NumPad5,
        glfw::Key::Kp6 => Key::NumPad6,
        glfw::Key::Kp7 => Key::NumPad7,
        glfw::Key::Kp8 => Key::NumPad8,
        glfw::Key::Kp9 => Key::NumPad9,
        glfw::Key::KpDecimal => Key::NumPadDecimal,
        glfw::Key::KpDivide => Key::NumPadDivide,
        glfw::Key::KpMultiply => Key::NumPadMultiply,
        glfw::Key::KpSubtract => Key::NumPadMinus,
        glfw::Key::KpAdd => Key::NumPadPlus,
        glfw::Key::KpEnter => Key::NumPadEnter,
        glfw::Key::KpEqual => Key::NumPadEquals,
        glfw::Key::LeftShift => Key::LShift,
        glfw::Key::LeftControl => Key::LCtrl,
        glfw::Key::LeftAlt => Key::LAlt,
        glfw::Key::LeftSuper => Key::LGui,
        glfw::Key::RightShift => Key::RShift,
        glfw::Key::RightControl => Key::RCtrl,
        glfw::Key::RightAlt => Key::RAlt,
        glfw::Key::RightSuper => Key::RGui,
        // Map to backslash?
        glfw::Key::GraveAccent => Key::Unknown,
        glfw::Key::Home => Key::Home,
        glfw::Key::Insert => Key::Insert,
        glfw::Key::Left => Key::Left,
        glfw::Key::LeftBracket => Key::LeftBracket,
        glfw::Key::Menu => Key::Menu,
        glfw::Key::Minus => Key::Minus,
        glfw::Key::NumLock => Key::NumLockClear,
        glfw::Key::PageDown => Key::PageDown,
        glfw::Key::PageUp => Key::PageUp,
        glfw::Key::Pause => Key::Pause,
        glfw::Key::Period => Key::Period,
        glfw::Key::PrintScreen => Key::PrintScreen,
        glfw::Key::Right => Key::Right,
        glfw::Key::RightBracket => Key::RightBracket,
        glfw::Key::ScrollLock => Key::ScrollLock,
        glfw::Key::Semicolon => Key::Semicolon,
        glfw::Key::Slash => Key::Slash,
        glfw::Key::Space => Key::Space,
        glfw::Key::Tab => Key::Tab,
        glfw::Key::Up => Key::Up,
        glfw::Key::World1 => Key::Unknown,
        glfw::Key::World2 => Key::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> MouseButton {
    match mouse_button {
        glfw::MouseButton::Button1 => MouseButton::Left,
        glfw::MouseButton::Button2 => MouseButton::Right,
        glfw::MouseButton::Button3 => MouseButton::Middle,
        glfw::MouseButton::Button4 => MouseButton::X1,
        glfw::MouseButton::Button5 => MouseButton::X2,
        glfw::MouseButton::Button6 => MouseButton::Button6,
        glfw::MouseButton::Button7 => MouseButton::Button7,
        glfw::MouseButton::Button8 => MouseButton::Button8,
    }
}
<commit_msg>Set swap interval when there is a current context<commit_after>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate gl;
extern crate piston;
extern crate shader_version;

// External crates.
use std::sync::mpsc::Receiver;
use std::collections::VecDeque;
use glfw::Context;
use piston::input::{
    keyboard,
    MouseButton,
    Button,
    Input,
    Motion,
};
use piston::window::{
    Window,
    AdvancedWindow,
    OpenGLWindow,
    ProcAddress,
    WindowSettings,
    Size
};

pub use shader_version::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: VecDeque<Input>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(mut win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::WindowHint::ContextVersion(major as u32, minor as u32));
        if opengl >= OpenGL::_3_2 {
            if cfg!(target_os = "macos") {
                glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
            }
            glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
        }
        if settings.get_samples() != 0 {
            glfw.window_hint(glfw::WindowHint::Samples(settings.get_samples() as u32));
        }

        // Create GLFW window.
        let (mut window, events) = glfw.create_window(
            settings.get_size().width,
            settings.get_size().height,
            &settings.get_title(), glfw::WindowMode::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        if settings.get_vsync() {
            glfw.set_swap_interval(1);
        } else {
            glfw.set_swap_interval(0);
        }

        // Load the OpenGL function pointers.
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: VecDeque::new(),
            last_mouse_pos: None,
            title: settings.get_title(),
            exit_on_esc: settings.get_exit_on_esc(),
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::WindowEvent::Key(glfw::Key::Escape, _, glfw::Action::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::WindowEvent::Char(ch) => {
                    self.event_queue.push_back(Input::Text(ch.to_string()));
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::Key(key, _, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Press, _) => {
                    self.event_queue.push_back(
                        Input::Press(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::MouseButton(button, glfw::Action::Release, _) => {
                    self.event_queue.push_back(
                        Input::Release(Button::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::WindowEvent::CursorPos(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => self.event_queue.push_back(
                            Input::Move(Motion::MouseRelative(x - lx, y - ly))
                        ),
                        None => ()
                    }
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::WindowEvent::Scroll(x, y) => {
                    self.event_queue.push_back(Input::Move(Motion::MouseScroll(x, y)));
                }
                glfw::WindowEvent::Size(w, h) => {
                    self.event_queue.push_back(Input::Resize(w as u32, h as u32));
                }
                glfw::WindowEvent::Focus(focus) => {
                    self.event_queue.push_back(Input::Focus(focus));
                }
                _ => ()
            }
        }
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }

    fn capture_cursor(&mut self, enabled: bool) {
        if enabled {
            self.window.set_cursor_mode(glfw::CursorMode::Disabled);
        } else {
            self.window.set_cursor_mode(glfw::CursorMode::Normal);
            self.last_mouse_pos = None;
        }
    }
}

impl Window for GlfwWindow {
    type Event = Input;

    fn size(&self) -> Size {
        let (w, h) = self.window.get_size();
        Size { width: w as u32, height: h as u32 }
    }

    fn draw_size(&self) -> Size {
        let (w, h) = self.window.get_framebuffer_size();
        Size { width: w as u32, height: h as u32 }
    }

    fn should_close(&self) -> bool {
        self.window.should_close()
    }

    fn swap_buffers(&mut self) {
        self.window.swap_buffers()
    }

    fn poll_event(&mut self) -> Option<Input> {
        self.poll_event()
    }
}

impl AdvancedWindow for GlfwWindow {
    fn get_title(&self) -> String {
        self.title.clone()
    }

    fn set_title(&mut self, value: String) {
        self.window.set_title(&value)
    }

    fn get_exit_on_esc(&self) -> bool {
        self.exit_on_esc
    }

    fn set_exit_on_esc(&mut self, value: bool) {
        self.exit_on_esc = value
    }

    fn set_capture_cursor(&mut self, value: bool) {
        self.capture_cursor(value)
    }
}

impl OpenGLWindow for GlfwWindow {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.window.get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.window.is_current()
    }

    fn make_current(&mut self) {
        self.window.make_current()
    }
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    use piston::input::keyboard::Key;

    match keycode {
        glfw::Key::Num0 => Key::D0,
        glfw::Key::Num1 => Key::D1,
        glfw::Key::Num2 => Key::D2,
        glfw::Key::Num3 => Key::D3,
        glfw::Key::Num4 => Key::D4,
        glfw::Key::Num5 => Key::D5,
        glfw::Key::Num6 => Key::D6,
        glfw::Key::Num7 => Key::D7,
        glfw::Key::Num8 => Key::D8,
        glfw::Key::Num9 => Key::D9,
        glfw::Key::A => Key::A,
        glfw::Key::B => Key::B,
        glfw::Key::C => Key::C,
        glfw::Key::D => Key::D,
        glfw::Key::E => Key::E,
        glfw::Key::F => Key::F,
        glfw::Key::G => Key::G,
        glfw::Key::H => Key::H,
        glfw::Key::I => Key::I,
        glfw::Key::J => Key::J,
        glfw::Key::K => Key::K,
        glfw::Key::L => Key::L,
        glfw::Key::M => Key::M,
        glfw::Key::N => Key::N,
        glfw::Key::O => Key::O,
        glfw::Key::P => Key::P,
        glfw::Key::Q => Key::Q,
        glfw::Key::R => Key::R,
        glfw::Key::S => Key::S,
        glfw::Key::T => Key::T,
        glfw::Key::U => Key::U,
        glfw::Key::V => Key::V,
        glfw::Key::W => Key::W,
        glfw::Key::X => Key::X,
        glfw::Key::Y => Key::Y,
        glfw::Key::Z => Key::Z,
        glfw::Key::Apostrophe => Key::Unknown,
        glfw::Key::Backslash => Key::Backslash,
        glfw::Key::Backspace => Key::Backspace,
        glfw::Key::CapsLock => Key::CapsLock,
        glfw::Key::Delete => Key::Delete,
        glfw::Key::Comma => Key::Comma,
        glfw::Key::Down => Key::Down,
        glfw::Key::End => Key::End,
        glfw::Key::Enter => Key::Return,
        glfw::Key::Equal => Key::Equals,
        glfw::Key::Escape => Key::Escape,
        glfw::Key::F1 => Key::F1,
        glfw::Key::F2 => Key::F2,
        glfw::Key::F3 => Key::F3,
        glfw::Key::F4 => Key::F4,
        glfw::Key::F5 => Key::F5,
        glfw::Key::F6 => Key::F6,
        glfw::Key::F7 => Key::F7,
        glfw::Key::F8 => Key::F8,
        glfw::Key::F9 => Key::F9,
        glfw::Key::F10 => Key::F10,
        glfw::Key::F11 => Key::F11,
        glfw::Key::F12 => Key::F12,
        glfw::Key::F13 => Key::F13,
        glfw::Key::F14 => Key::F14,
        glfw::Key::F15 => Key::F15,
        glfw::Key::F16 => Key::F16,
        glfw::Key::F17 => Key::F17,
        glfw::Key::F18 => Key::F18,
        glfw::Key::F19 => Key::F19,
        glfw::Key::F20 => Key::F20,
        glfw::Key::F21 => Key::F21,
        glfw::Key::F22 => Key::F22,
        glfw::Key::F23 => Key::F23,
        glfw::Key::F24 => Key::F24,
        // Possibly next code.
        glfw::Key::F25 => Key::Unknown,
        glfw::Key::Kp0 => Key::NumPad0,
        glfw::Key::Kp1 => Key::NumPad1,
        glfw::Key::Kp2 => Key::NumPad2,
        glfw::Key::Kp3 => Key::NumPad3,
        glfw::Key::Kp4 => Key::NumPad4,
        glfw::Key::Kp5 => Key::NumPad5,
        glfw::Key::Kp6 => Key::NumPad6,
        glfw::Key::Kp7 => Key::NumPad7,
        glfw::Key::Kp8 => Key::NumPad8,
        glfw::Key::Kp9 => Key::NumPad9,
        glfw::Key::KpDecimal => Key::NumPadDecimal,
        glfw::Key::KpDivide => Key::NumPadDivide,
        glfw::Key::KpMultiply => Key::NumPadMultiply,
        glfw::Key::KpSubtract => Key::NumPadMinus,
        glfw::Key::KpAdd => Key::NumPadPlus,
        glfw::Key::KpEnter => Key::NumPadEnter,
        glfw::Key::KpEqual => Key::NumPadEquals,
        glfw::Key::LeftShift => Key::LShift,
        glfw::Key::LeftControl => Key::LCtrl,
        glfw::Key::LeftAlt => Key::LAlt,
        glfw::Key::LeftSuper => Key::LGui,
        glfw::Key::RightShift => Key::RShift,
        glfw::Key::RightControl => Key::RCtrl,
        glfw::Key::RightAlt => Key::RAlt,
        glfw::Key::RightSuper => Key::RGui,
        // Map to backslash?
        glfw::Key::GraveAccent => Key::Unknown,
        glfw::Key::Home => Key::Home,
        glfw::Key::Insert => Key::Insert,
        glfw::Key::Left => Key::Left,
        glfw::Key::LeftBracket => Key::LeftBracket,
        glfw::Key::Menu => Key::Menu,
        glfw::Key::Minus => Key::Minus,
        glfw::Key::NumLock => Key::NumLockClear,
        glfw::Key::PageDown => Key::PageDown,
        glfw::Key::PageUp => Key::PageUp,
        glfw::Key::Pause => Key::Pause,
        glfw::Key::Period => Key::Period,
        glfw::Key::PrintScreen => Key::PrintScreen,
        glfw::Key::Right => Key::Right,
        glfw::Key::RightBracket => Key::RightBracket,
        glfw::Key::ScrollLock => Key::ScrollLock,
        glfw::Key::Semicolon => Key::Semicolon,
        glfw::Key::Slash => Key::Slash,
        glfw::Key::Space => Key::Space,
        glfw::Key::Tab => Key::Tab,
        glfw::Key::Up => Key::Up,
        glfw::Key::World1 => Key::Unknown,
        glfw::Key::World2 => Key::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> MouseButton {
    match mouse_button {
        glfw::MouseButton::Button1 => MouseButton::Left,
        glfw::MouseButton::Button2 => MouseButton::Right,
        glfw::MouseButton::Button3 => MouseButton::Middle,
        glfw::MouseButton::Button4 => MouseButton::X1,
        glfw::MouseButton::Button5 => MouseButton::X2,
        glfw::MouseButton::Button6 => MouseButton::Button6,
        glfw::MouseButton::Button7 => MouseButton::Button7,
        glfw::MouseButton::Button8 => MouseButton::Button8,
    }
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]

extern crate libc;

pub mod wrapper;

use libc::{uint64_t, c_double, c_int};

/// Typedef for the window completion callback function.
#[repr(C)]
pub type heartbeat_window_complete = extern fn(*const heartbeat_context,
                                               *const heartbeat_record,
                                               uint64_t);

/// Time data.
#[repr(C)]
pub struct heartbeat_time_data {
    total_time: uint64_t,
    window_time: uint64_t,
}

/// Work data.
#[repr(C)]
pub struct heartbeat_work_data {
    total_work: uint64_t,
    window_work: uint64_t,
}

/// Energy data
#[repr(C)]
pub struct heartbeat_energy_data {
    total_energy: uint64_t,
    window_energy: uint64_t,
}

/// A heartbeat record with current rates (performance and power).
#[repr(C)]
pub struct heartbeat_record {
    pub id: uint64_t,
    pub user_tag: uint64_t,

    pub work: uint64_t,
    pub start_time: uint64_t,
    pub end_time: uint64_t,
    pub global_perf: c_double,
    pub window_perf: c_double,
    pub instant_perf: c_double,

    pub start_energy: uint64_t,
    pub end_energy: uint64_t,
    pub global_pwr: c_double,
    pub window_pwr: c_double,
    pub instant_pwr: c_double,
}

/// A `heartbeat_context` is used for tracking performance/power of recurring jobs.
#[repr(C)]
pub struct heartbeat_context {
    counter: uint64_t,
    buffer_index: uint64_t,
    read_index: uint64_t,
    window_size: uint64_t,
    window_buffer: *mut heartbeat_record,
    hwc_callback: heartbeat_window_complete,

    td: heartbeat_time_data,
    wd: heartbeat_work_data,
    ed: heartbeat_energy_data,
}

extern "C" {
    // Core functions

    pub fn heartbeat_init(hb: *mut heartbeat_context,
                          window_size: uint64_t,
                          window_buffer: *mut heartbeat_record,
                          hwc_callback: Option<heartbeat_window_complete>) -> c_int;

    pub fn heartbeat(hb: *mut heartbeat_context,
                     user_tag: uint64_t,
                     work: uint64_t,
                     start_time: uint64_t,
                     end_time: uint64_t);

    pub fn heartbeat_pow(hb: *mut heartbeat_context,
                         user_tag: uint64_t,
                         work: uint64_t,
                         start_time: uint64_t,
                         end_time: uint64_t,
                         start_energy: uint64_t,
                         end_energy: uint64_t);

    pub fn heartbeat_log_window_buffer(hb: *const heartbeat_context,
                                       fd: c_int,
                                       print_header: c_int) -> c_int;

    // Utility functions

    pub fn hb_get_window_size(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_user_tag(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_time(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_time(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_global_work(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_work(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_rate(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_window_rate(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_instant_rate(hb: *const heartbeat_context) -> c_double;

    pub fn hb_get_global_energy(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_energy(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_power(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_window_power(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_instant_power(hb: *const heartbeat_context) -> c_double;
}
<commit_msg>Data types are simplified<commit_after>#![allow(non_camel_case_types)]

extern crate libc;

pub mod wrapper;

use libc::{uint64_t, c_double, c_int};

/// Typedef for the window completion callback function.
#[repr(C)]
pub type heartbeat_window_complete = extern fn(*const heartbeat_context,
                                               *const heartbeat_record,
                                               uint64_t);

/// Unsigned global and window data.
#[repr(C)]
pub struct heartbeat_udata {
    global: uint64_t,
    window: uint64_t,
}

/// A heartbeat record with current rates (performance and power).
#[repr(C)]
pub struct heartbeat_record {
    pub id: uint64_t,
    pub user_tag: uint64_t,

    pub work: uint64_t,
    pub start_time: uint64_t,
    pub end_time: uint64_t,
    pub global_perf: c_double,
    pub window_perf: c_double,
    pub instant_perf: c_double,

    pub start_energy: uint64_t,
    pub end_energy: uint64_t,
    pub global_pwr: c_double,
    pub window_pwr: c_double,
    pub instant_pwr: c_double,
}

/// A `heartbeat_context` is used for tracking performance/power of recurring jobs.
#[repr(C)]
pub struct heartbeat_context {
    counter: uint64_t,
    buffer_index: uint64_t,
    read_index: uint64_t,
    window_size: uint64_t,
    window_buffer: *mut heartbeat_record,
    hwc_callback: heartbeat_window_complete,

    td: heartbeat_udata,
    wd: heartbeat_udata,
    ed: heartbeat_udata,
}

extern "C" {
    // Core functions

    pub fn heartbeat_init(hb: *mut heartbeat_context,
                          window_size: uint64_t,
                          window_buffer: *mut heartbeat_record,
                          hwc_callback: Option<heartbeat_window_complete>) -> c_int;

    pub fn heartbeat(hb: *mut heartbeat_context,
                     user_tag: uint64_t,
                     work: uint64_t,
                     start_time: uint64_t,
                     end_time: uint64_t);

    pub fn heartbeat_pow(hb: *mut heartbeat_context,
                         user_tag: uint64_t,
                         work: uint64_t,
                         start_time: uint64_t,
                         end_time: uint64_t,
                         start_energy: uint64_t,
                         end_energy: uint64_t);

    pub fn heartbeat_log_window_buffer(hb: *const heartbeat_context,
                                       fd: c_int,
                                       print_header: c_int) -> c_int;

    // Utility functions

    pub fn hb_get_window_size(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_user_tag(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_time(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_time(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_global_work(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_work(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_rate(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_window_rate(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_instant_rate(hb: *const heartbeat_context) -> c_double;

    pub fn hb_get_global_energy(hb: *const heartbeat_context) -> uint64_t;
    pub fn hb_get_window_energy(hb: *const heartbeat_context) -> uint64_t;

    pub fn hb_get_global_power(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_window_power(hb: *const heartbeat_context) -> c_double;
    pub fn hb_get_instant_power(hb: *const heartbeat_context) -> c_double;
}
<|endoftext|>


<commit_before>// Copyright 2017 Kai Strempel
//
// 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.

#![crate_type = "lib"]
#![crate_name = "docker"]

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate curl;

#[macro_use]
mod common;
mod error;

pub mod images;
pub mod networks;
pub mod containers;

use std::str::*;
use std::cell::RefCell;

use curl::easy::Easy;

use error::DockerError;
use images::ImagesClient;
use containers::ContainersClient;
use networks::NetworksClient;

use std::error::Error;

pub struct Client {
    api_url: String,
    curl : RefCell<Easy>
}

impl Client {

    pub fn new(api_url: &str) -> Client {
        let client = Client {
            api_url : String::from_str(api_url).unwrap(),
            curl : RefCell::new(Easy::new())
        };
        client.set_curl_client();

        client
    }

    pub fn from_env() -> Client {
        Client::new("http:///v1.26/")
    }

    fn set_curl_client(&self) -> ()  {
        let mut curl = self.curl.borrow_mut();
        let _ = curl.unix_socket("/var/run/docker.sock");
    }

    fn get(&self, url: &str) -> Result<String, DockerError> {
        let mut result = Vec::new();
        let real_url = format!("{}{}", self.api_url, url);
        let mut curl = self.curl.borrow_mut();
        match curl.url(real_url.as_str()) {
            Ok(_) => {
                let mut transfer = curl.transfer();
                transfer.write_function(|data| {
                    result.extend_from_slice(data);
                    Ok(data.len())
                }).unwrap();
                transfer.perform().unwrap();
            },
            Err(err) => {
                print!("Mein Text {}", err.description());
            }
        };

        Ok(String::from_utf8(result).unwrap())
    }

    pub fn images(&self) -> ImagesClient {
        ImagesClient::new(self)
    }
    pub fn containers(&self) -> ContainersClient {
        ContainersClient::new(self)
    }

    pub fn networks(&self) -> NetworksClient {
        NetworksClient::new(self)
    }
}
<commit_msg>fix the tests<commit_after>// Copyright 2017 Kai Strempel
//
// 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.

#![crate_type = "lib"]
#![crate_name = "docker"]

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate curl;

#[macro_use]
mod common;
mod error;

pub mod images;
pub mod networks;
pub mod containers;

use std::str::*;
use std::cell::RefCell;

use curl::easy::Easy;

use error::DockerError;
use images::ImagesClient;
use containers::ContainersClient;
use networks::NetworksClient;

use std::error::Error;

pub struct Client {
    api_url: String,
    curl : RefCell<Easy>
}

impl Client {

    pub fn new(api_url: &str) -> Client {
        let client = Client {
            api_url : String::from_str(api_url).unwrap(),
            curl : RefCell::new(Easy::new())
        };
        client.set_curl_client();

        client
    }

    pub fn from_env() -> Client {
        Client::new("http://v1.26/")
    }

    fn set_curl_client(&self) -> ()  {
        let mut curl = self.curl.borrow_mut();
        let _ = curl.unix_socket("/var/run/docker.sock");
    }

    fn get(&self, url: &str) -> Result<String, DockerError> {
        let mut result = Vec::new();
        let real_url = format!("{}{}", self.api_url, url);
        let mut curl = self.curl.borrow_mut();
        match curl.url(real_url.as_str()) {
            Ok(_) => {
                let mut transfer = curl.transfer();
                transfer.write_function(|data| {
                    result.extend_from_slice(data);
                    Ok(data.len())
                }).unwrap();
                transfer.perform().unwrap();
            },
            Err(err) => {
                print!("Mein Text {}", err.description());
            }
        };

        Ok(String::from_utf8(result).unwrap())
    }

    pub fn images(&self) -> ImagesClient {
        ImagesClient::new(self)
    }
    pub fn containers(&self) -> ContainersClient {
        ContainersClient::new(self)
    }

    pub fn networks(&self) -> NetworksClient {
        NetworksClient::new(self)
    }
}
<|endoftext|>


<commit_before>//! Functions to find the difference between to texts (strings).

#![crate_name = "text_diff"]

#![feature(step_by)]

// I can basically feel the karma already
#![deny(missing_docs)]

mod lcs;
mod merge;

use lcs::lcs;
use merge::merge;

/// Defines the contents of a changeset
/// Changesets will be delivered in order of appearance in the original string
/// Sequences of the same kind will be grouped into one Difference
#[derive(PartialEq, Debug)]
pub enum Difference {
    /// Sequences that are the same
    Same(String),
    /// Sequences that are an addition (don't appear in the first string)
    Add(String),
    /// Sequences that are a removal (don't appear in the second string)
    Rem(String)
}

/// Calculates the edit distance and the changeset for two given strings
/// The first string is assumed to be the "original", the second to be an
/// edited version of the first
pub fn diff(orig: &str, edit: &str) -> (i32, Vec<Difference>) {
    let (dist, common) = lcs(orig, edit);
    (dist, merge(orig, edit, &common))
}

<commit_msg>Visual diff<commit_after>//! Functions to find the difference between to texts (strings).

#![crate_name = "text_diff"]

#![feature(step_by)]

// I can basically feel the karma already
#![deny(missing_docs)]

mod lcs;
mod merge;

use lcs::lcs;
use merge::merge;

/// Defines the contents of a changeset
/// Changesets will be delivered in order of appearance in the original string
/// Sequences of the same kind will be grouped into one Difference
#[derive(PartialEq, Debug)]
pub enum Difference {
    /// Sequences that are the same
    Same(String),
    /// Sequences that are an addition (don't appear in the first string)
    Add(String),
    /// Sequences that are a removal (don't appear in the second string)
    Rem(String)
}

/// Calculates the edit distance and the changeset for two given strings
/// The first string is assumed to be the "original", the second to be an
/// edited version of the first
pub fn diff(orig: &str, edit: &str) -> (i32, Vec<Difference>) {
    let (dist, common) = lcs(orig, edit);
    (dist, merge(orig, edit, &common))
}

/// Generates a visual diffset
pub fn visual_diff(orig: &str, edit: &str) -> String {
    let (_, changeset) = diff(orig, edit);
    let mut ret = String::new();

    for seq in changeset {
        match seq {
            Difference::Same(ref x) => {
                ret.push_str(x);
            },
            Difference::Add(ref x) => {
                ret.push_str("\x1B[92m");
                ret.push_str(x);
                ret.push_str("\x1B[0m");
            },
            Difference::Rem(ref x) => {
                ret.push_str("\x1B[91m");
                ret.push_str(x);
                ret.push_str("\x1B[0m");
            }
        }
    }
    println!("{}", ret);

    ret
}

#[test]
fn test_visual_diff() {
    assert_eq!(visual_diff("test", "tost"), "t\x1B[92mo\x1B[0m\x1B[91me\x1B[0mst".to_string());
}
<|endoftext|>


<commit_before>use std::iter::Peekable;
use std::vec::IntoIter;

#[derive(Debug,PartialEq,Clone)]
pub enum Token {
    Number(String),
    String(String),
    Name(String),
    ParenOpening,
    ParenClosing,
}

pub fn tokenizer(input: &str) -> Result<Vec<Token>, String> {
    let mut tokens: Vec<Token> = vec![];

    let mut char_iter = input.chars().peekable();
    while let Some(c) = char_iter.next() {
        match c {
            c if c.is_whitespace() => continue,
            '(' => tokens.push(Token::ParenOpening),
            ')' => tokens.push(Token::ParenClosing),
            '0'...'9' => {
                let mut value = String::new();
                value.push(c);

                while let Some(&'0'...'9') = char_iter.peek() {
                    value.push(char_iter.next().unwrap());
                }

                tokens.push(Token::Number(value));
            }
            'a'...'z' => {
                let mut value = String::new();
                value.push(c);

                while let Some(&'a'...'z') = char_iter.peek() {
                    value.push(char_iter.next().unwrap());
                }

                tokens.push(Token::Name(value));
            }
            '"' => {
                let mut value = String::new();
                // ignore opening "

                while match char_iter.peek() {
                    Some(&'"') | None => false,
                    _ => true,
                } {
                    value.push(char_iter.next().unwrap());
                }
                tokens.push(Token::String(value));

                // skip closing ""
                char_iter.next().unwrap();
            }
            _ => return Err(format!("I don't know what this character is: {}", c)),
        }
    }

    Ok(tokens)
}

#[derive(Debug,PartialEq)]
pub enum Ast {
    Programm { body: Vec<Ast> },
    CallExpression { name: String, params: Vec<Ast> },
    StringLiteral(String),
    NumberLiteral(String),
    SomethingElse,
}

pub fn parser(tokens: Vec<Token>) -> Result<Ast, String> {
    fn walk(token: Token, token_iter: &mut Peekable<IntoIter<Token>>) -> Result<Ast, String> {
        match token {
            Token::Number(value) => Ok(Ast::NumberLiteral(value)),
            Token::String(value) => Ok(Ast::StringLiteral(value)),
            Token::ParenOpening => {
                if let Some(token) = token_iter.next() {
                    match token {
                        Token::Name(name) => {
                            let mut params: Vec<Ast> = vec![];

                            while match token_iter.peek() {
                                Some(&Token::ParenClosing) |
                                None => false,
                                _ => true,
                            } {
                                match walk(token_iter.next().unwrap(), token_iter) {
                                    Ok(nodes) => params.push(nodes),
                                    Err(value) => return Err(value),
                                }
                            }

                            // skip Token::ParenClosing
                            token_iter.next().unwrap();

                            Ok(Ast::CallExpression {
                                name: name,
                                params: params,
                            })
                        }
                        _ => {
                            return Err(format!("{:?} isn't followed by a {:?}.",
                                               Token::ParenOpening,
                                               Token::Name("example".to_string())))
                        }
                    }
                } else {
                    return Err(format!("{:?} isn't followed by a node.", Token::ParenOpening));
                }
            }
            _ => return Err(format!("I don't know what this token is: {:?}", token)),
        }
    }

    let mut body: Vec<Ast> = vec![];

    let mut token_iter = tokens.into_iter().peekable();
    while let Some(token) = token_iter.next() {
        match walk(token, &mut token_iter) {
            Ok(nodes) => body.push(nodes),
            Err(value) => return Err(value),
        }
    }

    Ok(Ast::Programm { body: body })
}
<commit_msg>remove old code<commit_after>use std::iter::Peekable;
use std::vec::IntoIter;

#[derive(Debug,PartialEq,Clone)]
pub enum Token {
    Number(String),
    String(String),
    Name(String),
    ParenOpening,
    ParenClosing,
}

pub fn tokenizer(input: &str) -> Result<Vec<Token>, String> {
    let mut tokens: Vec<Token> = vec![];

    let mut char_iter = input.chars().peekable();
    while let Some(c) = char_iter.next() {
        match c {
            c if c.is_whitespace() => continue,
            '(' => tokens.push(Token::ParenOpening),
            ')' => tokens.push(Token::ParenClosing),
            '0'...'9' => {
                let mut value = String::new();
                value.push(c);

                while let Some(&'0'...'9') = char_iter.peek() {
                    value.push(char_iter.next().unwrap());
                }

                tokens.push(Token::Number(value));
            }
            'a'...'z' => {
                let mut value = String::new();
                value.push(c);

                while let Some(&'a'...'z') = char_iter.peek() {
                    value.push(char_iter.next().unwrap());
                }

                tokens.push(Token::Name(value));
            }
            '"' => {
                let mut value = String::new();
                // ignore opening "

                while match char_iter.peek() {
                    Some(&'"') | None => false,
                    _ => true,
                } {
                    value.push(char_iter.next().unwrap());
                }
                tokens.push(Token::String(value));

                // skip closing ""
                char_iter.next().unwrap();
            }
            _ => return Err(format!("I don't know what this character is: {}", c)),
        }
    }

    Ok(tokens)
}

#[derive(Debug,PartialEq)]
pub enum Ast {
    Programm { body: Vec<Ast> },
    CallExpression { name: String, params: Vec<Ast> },
    StringLiteral(String),
    NumberLiteral(String),
}

pub fn parser(tokens: Vec<Token>) -> Result<Ast, String> {
    fn walk(token: Token, token_iter: &mut Peekable<IntoIter<Token>>) -> Result<Ast, String> {
        match token {
            Token::Number(value) => Ok(Ast::NumberLiteral(value)),
            Token::String(value) => Ok(Ast::StringLiteral(value)),
            Token::ParenOpening => {
                if let Some(token) = token_iter.next() {
                    match token {
                        Token::Name(name) => {
                            let mut params: Vec<Ast> = vec![];

                            while match token_iter.peek() {
                                Some(&Token::ParenClosing) |
                                None => false,
                                _ => true,
                            } {
                                match walk(token_iter.next().unwrap(), token_iter) {
                                    Ok(nodes) => params.push(nodes),
                                    Err(value) => return Err(value),
                                }
                            }

                            // skip Token::ParenClosing
                            token_iter.next().unwrap();

                            Ok(Ast::CallExpression {
                                name: name,
                                params: params,
                            })
                        }
                        _ => {
                            return Err(format!("{:?} isn't followed by a {:?}.",
                                               Token::ParenOpening,
                                               Token::Name("example".to_string())))
                        }
                    }
                } else {
                    return Err(format!("{:?} isn't followed by a node.", Token::ParenOpening));
                }
            }
            _ => return Err(format!("I don't know what this token is: {:?}", token)),
        }
    }

    let mut body: Vec<Ast> = vec![];

    let mut token_iter = tokens.into_iter().peekable();
    while let Some(token) = token_iter.next() {
        match walk(token, &mut token_iter) {
            Ok(nodes) => body.push(nodes),
            Err(value) => return Err(value),
        }
    }

    Ok(Ast::Programm { body: body })
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

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

use std::io::{self, Error};
use std::os::unix::io::RawFd;

bitflags! {
    pub struct ControlOptions: i32 {
        /// Indicates an addition to the interest list.
        const EPOLL_CTL_ADD = libc::EPOLL_CTL_ADD;
        /// Indicates a modification of flags for an interest already in list.
        const EPOLL_CTL_MOD = libc::EPOLL_CTL_MOD;
        /// Indicates a removal of an interest from the list.
        const EPOLL_CTL_DEL = libc::EPOLL_CTL_DEL;
    }
}

bitflags! {
    pub struct Events: u32 {
        /// Sets the Edge Triggered behavior for the associated file descriptor.
        ///
        /// The default behavior for epoll is Level Triggered.
        const EPOLLET      = libc::EPOLLET as u32;
        /// The associated file is available for read operations.
        const EPOLLIN      = libc::EPOLLIN as u32;
        /// Error condition happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; is not necessary to set it in events.
        const EPOLLERR     = libc::EPOLLERR as u32;
        /// Hang up happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; it is not necessary to set it in events.
        /// Note that when reading from a channel such as a pipe or a stream socket, this event
        /// merely indicates that the peer closed its end of the channel. Subsequent reads from
        /// the channel will return 0 (end of file) only after all outstanding data in the
        /// channel has been consumed.
        const EPOLLHUP     = libc::EPOLLHUP as u32;
        /// The associated file is available for write operations.
        const EPOLLOUT     = libc::EPOLLOUT as u32;
        /// There is urgent data available for read operations.
        const EPOLLPRI     = libc::EPOLLPRI as u32;
        /// Stream socket peer closed connection, or shut down writing half of connection.
        ///
        /// This flag is especially useful for writing simple code to detect peer shutdown when
        /// using Edge Triggered monitoring.
        const EPOLLRDHUP   = libc::EPOLLRDHUP as u32;
        /// If `EPOLLONESHOT` and `EPOLLET` are clear and the process has the `CAP_BLOCK_SUSPEND`
        /// capability, ensure that the system does not enter "suspend" or "hibernate" while this
        /// event is pending or being processed.
        ///
        /// The event is considered as being "processed" from the time when it is returned by
        /// a call to `wait` until the next call to `wait` on the same `EpollInstance`
        /// descriptor, the closure of that file descriptor, the removal of the event file
        /// descriptor with `EPOLL_CTL_DEL`, or the clearing of `EPOLLWAKEUP` for the event file
        /// descriptor with `EPOLL_CTL_MOD`.
        const EPOLLWAKEUP  = libc::EPOLLWAKEUP as u32;
        /// Sets the one-shot behavior for the associated file descriptor.
        ///
        /// This means that after an event is pulled out with `wait` the associated file
        /// descriptor is internally disabled and no other events will be reported by the epoll
        /// interface.  The user must call `ctl` with `EPOLL_CTL_MOD` to rearm the file
        /// descriptor with a new event mask.
        const EPOLLONESHOT = libc::EPOLLONESHOT as u32;
    }
}

/// 'libc::epoll_event' equivalent.
#[repr(C)]
#[repr(packed)]
#[derive(Clone, Copy)]
pub struct Event {
    pub events: u32,
    pub data: u64
}

impl Event {
    pub fn new(events: Events, data: u64) -> Event {
        Event { events: events.bits(), data: data }
    }
}

/// Creates a new epoll file descriptor.
///
/// If `cloexec` is true, `FD_CLOEXEC` will be set on the returned file descriptor.
///
/// ## Notes
///
/// * `epoll_create1()` is the underlying syscall.
pub fn create(cloexec: bool) -> io::Result<RawFd> {
    let flags = if cloexec { libc::EPOLL_CLOEXEC } else { 0 };
    unsafe { cvt(libc::epoll_create1(flags)) }
}

/// Safe wrapper for `libc::epoll_ctl`
pub fn ctl(epfd: RawFd,
           op: ControlOptions,
           fd: RawFd,
           mut event: Event)
           -> io::Result<()>
{
    let e = &mut event as *mut _ as *mut libc::epoll_event;
    unsafe { try!(cvt(libc::epoll_ctl(epfd, op.bits, fd, e))) };
    Ok(())
}

/// Safe wrapper for `libc::epoll_wait`
///
/// ## Notes
///
/// * If `timeout` is negative, it will block until an event is received.
pub fn wait(epfd: RawFd,
            timeout: i32,
            buf: &mut [Event])
            -> io::Result<usize>
{
    let timeout = if timeout < -1 { -1 } else { timeout };
    let num_events = unsafe {
        try!(cvt(libc::epoll_wait(epfd,
                                  buf.as_mut_ptr() as *mut libc::epoll_event,
                                  buf.len() as i32,
                                  timeout))) as usize
    };
    Ok(num_events)
}

fn cvt(result: libc::c_int) -> io::Result<libc::c_int> {
    if result < 0 { Err(Error::last_os_error()) } else { Ok(result) }
}
<commit_msg>Changed ControlOptions to enum instead of bitflags. Closes #7.<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

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

use std::io::{self, Error};
use std::os::unix::io::RawFd;

#[allow(non_camel_case_types)]
pub enum ControlOptions {
    /// Indicates an addition to the interest list.
    EPOLL_CTL_ADD = libc::EPOLL_CTL_ADD as isize,
    /// Indicates a modification of flags for an interest already in list.
    EPOLL_CTL_MOD = libc::EPOLL_CTL_MOD as isize,
    /// Indicates a removal of an interest from the list.
    EPOLL_CTL_DEL = libc::EPOLL_CTL_DEL as isize
}

bitflags! {
    pub struct Events: u32 {
        /// Sets the Edge Triggered behavior for the associated file descriptor.
        ///
        /// The default behavior for epoll is Level Triggered.
        const EPOLLET      = libc::EPOLLET as u32;
        /// The associated file is available for read operations.
        const EPOLLIN      = libc::EPOLLIN as u32;
        /// Error condition happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; is not necessary to set it in events.
        const EPOLLERR     = libc::EPOLLERR as u32;
        /// Hang up happened on the associated file descriptor.
        ///
        /// `wait` will always wait for this event; it is not necessary to set it in events.
        /// Note that when reading from a channel such as a pipe or a stream socket, this event
        /// merely indicates that the peer closed its end of the channel. Subsequent reads from
        /// the channel will return 0 (end of file) only after all outstanding data in the
        /// channel has been consumed.
        const EPOLLHUP     = libc::EPOLLHUP as u32;
        /// The associated file is available for write operations.
        const EPOLLOUT     = libc::EPOLLOUT as u32;
        /// There is urgent data available for read operations.
        const EPOLLPRI     = libc::EPOLLPRI as u32;
        /// Stream socket peer closed connection, or shut down writing half of connection.
        ///
        /// This flag is especially useful for writing simple code to detect peer shutdown when
        /// using Edge Triggered monitoring.
        const EPOLLRDHUP   = libc::EPOLLRDHUP as u32;
        /// If `EPOLLONESHOT` and `EPOLLET` are clear and the process has the `CAP_BLOCK_SUSPEND`
        /// capability, ensure that the system does not enter "suspend" or "hibernate" while this
        /// event is pending or being processed.
        ///
        /// The event is considered as being "processed" from the time when it is returned by
        /// a call to `wait` until the next call to `wait` on the same `EpollInstance`
        /// descriptor, the closure of that file descriptor, the removal of the event file
        /// descriptor with `EPOLL_CTL_DEL`, or the clearing of `EPOLLWAKEUP` for the event file
        /// descriptor with `EPOLL_CTL_MOD`.
        const EPOLLWAKEUP  = libc::EPOLLWAKEUP as u32;
        /// Sets the one-shot behavior for the associated file descriptor.
        ///
        /// This means that after an event is pulled out with `wait` the associated file
        /// descriptor is internally disabled and no other events will be reported by the epoll
        /// interface.  The user must call `ctl` with `EPOLL_CTL_MOD` to rearm the file
        /// descriptor with a new event mask.
        const EPOLLONESHOT = libc::EPOLLONESHOT as u32;
    }
}

/// 'libc::epoll_event' equivalent.
#[repr(C)]
#[repr(packed)]
#[derive(Clone, Copy)]
pub struct Event {
    pub events: u32,
    pub data: u64
}

impl Event {
    pub fn new(events: Events, data: u64) -> Event {
        Event { events: events.bits(), data: data }
    }
}

/// Creates a new epoll file descriptor.
///
/// If `cloexec` is true, `FD_CLOEXEC` will be set on the returned file descriptor.
///
/// ## Notes
///
/// * `epoll_create1()` is the underlying syscall.
pub fn create(cloexec: bool) -> io::Result<RawFd> {
    let flags = if cloexec { libc::EPOLL_CLOEXEC } else { 0 };
    unsafe { cvt(libc::epoll_create1(flags)) }
}

/// Safe wrapper for `libc::epoll_ctl`
pub fn ctl(epfd: RawFd,
           op: ControlOptions,
           fd: RawFd,
           mut event: Event)
           -> io::Result<()>
{
    let e = &mut event as *mut _ as *mut libc::epoll_event;
    unsafe { try!(cvt(libc::epoll_ctl(epfd, op as i32, fd, e))) };
    Ok(())
}

/// Safe wrapper for `libc::epoll_wait`
///
/// ## Notes
///
/// * If `timeout` is negative, it will block until an event is received.
pub fn wait(epfd: RawFd,
            timeout: i32,
            buf: &mut [Event])
            -> io::Result<usize>
{
    let timeout = if timeout < -1 { -1 } else { timeout };
    let num_events = unsafe {
        try!(cvt(libc::epoll_wait(epfd,
                                  buf.as_mut_ptr() as *mut libc::epoll_event,
                                  buf.len() as i32,
                                  timeout))) as usize
    };
    Ok(num_events)
}

fn cvt(result: libc::c_int) -> io::Result<libc::c_int> {
    if result < 0 { Err(Error::last_os_error()) } else { Ok(result) }
}
<|endoftext|>