<commit_before>//! A memory allocation arena specialized for types implement Copy.
//!
//! An `Arena` can allocate objects more efficiently than a
//! general-purpose allocator, but the objects cannot be
//! deallocated until the `Arena` itself is destroyed.
//!
//! To actually allocate out of an `Arena` after creating it,
//! use its `allocator()` method to create an `Allocator`.
//!
//! # Examples
//!
//! ```
//! use copy_arena::Arena;
//!
//! let mut arena = Arena::new();
//! let mut allocator = arena.allocator();
//!
//! let a: &mut i32 = allocator.alloc(5);
//! let b: &mut f64 = allocator.alloc_default();
//! let c: &mut [u8] = allocator.alloc_slice(b"some text");
//! let b: &mut [usize] = allocator.alloc_slice_fn(10, |idx| idx + 1);
//! let e: &mut [u32] = allocator.alloc_slice_default(10);
//! ```

use std::mem;
use std::cmp;
use std::usize;
use std::default::Default;
use std::slice;
use std::fmt;

struct Chunk {
    data: Vec<u8>,
    next: Option<Box<Chunk>>,
}

impl Chunk {
    fn attempt_alloc(&mut self, size: usize, align: usize) -> Option<*mut u8> {
        let start = round_up(self.data.len(), align);

        if size <= self.data.capacity() && start <= self.data.capacity() - size {
            Some(unsafe {
                self.data.set_len(start + size);
                self.data.as_mut_ptr().offset(start as isize)
            })
        } else {
            None
        }
    }
}

/// Holds the backing memory for allocated objects out of itself.
///
/// Actual allocation into the `Arena` happens via an `Allocator` returned
/// from `allocator()`.
pub struct Arena {
    head: Chunk,
}

impl Arena {
    /// Construct a new Arena. This _does_ allocate an block of memory.
    pub fn new() -> Arena {
        Arena::with_capacity(1000)
    }

    /// Construct a new Arena with the given initial capacity.
    ///
    /// The chosen capacity does not limit the final size of the arena.
    pub fn with_capacity(capacity: usize) -> Arena {
        Arena {
            head: Chunk{
                data: Vec::with_capacity(capacity),
                next: None,
            }
        }
    }

    fn add_chunk(&mut self, chunk_size: usize) {
        let mut new_head = Chunk {
            data: Vec::with_capacity(chunk_size),
            next: None,
        };

        mem::swap(&mut self.head, &mut new_head);
        self.head.next = Some(Box::new(new_head));
    }

    /// Construct an Allocator for this arena.
    pub fn allocator(&mut self) -> Allocator {
        Allocator {
            arena: self
        }
    }

    /// Get the number of bytes of memory that have been allocated
    /// in service of this arena. Not all of this capacity is necessarily
    /// useful, since asked-for memory may not perfectly fit in the
    /// underlying blocks allocated.
    pub fn capacity(&self) -> usize {
        let mut iter: &Chunk = &self.head;
        let mut total_capacity = 0;
        loop {
            total_capacity += iter.data.capacity();
            match iter.next {
                None => { return total_capacity; }
                Some(ref next) => { iter = next; }
            }
        }
    }
}

impl fmt::Debug for Arena {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_fmt(format_args!("Arena {{ capacity_bytes: {} }}", self.capacity()))
    }
}

/// Allows allocation out of arena.
#[derive(Debug)]
pub struct Allocator<'a> {
    arena: &'a mut Arena,
}

#[inline]
fn round_up(base: usize, align: usize) -> usize {
    (base + (align - 1)) & !(align - 1)
}

impl<'a> Allocator<'a> {
    fn alloc_raw(&mut self, size: usize, align: usize) -> &'a mut u8 {
        loop {
            match self.arena.head.attempt_alloc(size, align) {
                Some(x) => { return unsafe { mem::transmute(x) } },
                None => {
                    // Double the current allocation (or the asked for one), but don't overflow.
                    let minimum_reasonable = cmp::max(self.arena.head.data.len(), size);
                    let new_chunk_size = 2 * cmp::min(minimum_reasonable, usize::MAX/2);
                    self.arena.add_chunk(new_chunk_size);
                }
            }
        }
    }

    /// Allocate a copy of an object
    pub fn alloc<T: Copy>(&mut self, elem: T) -> &'a mut T {
        let memory = self.alloc_raw(mem::size_of::<T>(), mem::min_align_of::<T>());
        let res: &'a mut T = unsafe { mem::transmute(memory) };
        *res = elem;
        res
    }

    /// Allocate a default-valued object
    pub fn alloc_default<T: Copy+Default>(&mut self) -> &'a mut T {
        self.alloc(Default::default())
    }

    /// Allocate and leave uninitialized a slice of the given length
    fn alloc_slice_raw<T>(&mut self, len: usize) -> &'a mut [T] {
        let element_size = cmp::max(mem::size_of::<T>(), mem::min_align_of::<T>());
        assert_eq!(mem::size_of::<[T;7]>(), 7 * element_size);
        let byte_count = element_size.checked_mul(len).expect("Arena slice size overflow");
        let memory = self.alloc_raw(byte_count, mem::min_align_of::<T>());
        let res: &'a mut [T] = unsafe { slice::from_raw_parts_mut( mem::transmute(memory), len) };
        res
    }

    /// Allocate a copy of a slice
    pub fn alloc_slice<T: Copy>(&mut self, elems: &[T]) -> &'a mut [T] {
        let mut slice = self.alloc_slice_raw(elems.len());
        for (dest, src) in slice.iter_mut().zip(elems.iter()) {
            *dest = *src;
        }
        slice
    }

    /// Allocate and populate a slice, creating each element as a function
    /// of its index.
    pub fn alloc_slice_fn<T: Copy, F>(&mut self, len: usize, mut f: F)-> &'a mut [T]
        where F: FnMut(usize) -> T
    {
        let mut slice = self.alloc_slice_raw(len);
        for (idx, dest) in slice.iter_mut().enumerate() {
            *dest = f(idx)
        }
        slice
    }

    /// Allocate a slice populated by default-valued elements.
    pub fn alloc_slice_default<T: Copy+Default>(&mut self, len: usize)-> &'a mut [T] {
        self.alloc_slice_fn(len, |_| Default::default())
    }
}

#[test]
fn construct_simple() {
    let mut arena = Arena::with_capacity(4);
    let mut allocator = arena.allocator();

    let x: &mut i32 = allocator.alloc(44);
    let y: &mut u8 = allocator.alloc(3);
    let z: &mut u32 = allocator.alloc(0x11223344);
    let w: &mut f64 = allocator.alloc_default();
    assert_eq!(*x, 44);
    assert_eq!(*y, 3);
    assert_eq!(*z, 0x11223344);
    assert_eq!(*w, 0.0);
}

#[test]
fn construct_slices() {
    let mut arena = Arena::with_capacity(4);
    let mut allocator = arena.allocator();

    let s = ::std::str::from_utf8(allocator.alloc_slice(b"abc")).unwrap();
    let xs: &[i32] = allocator.alloc_slice_fn(10, |idx| (idx as i32)*7);
    let ys: &[u64] = allocator.alloc_slice_default(4);

    assert_eq!(xs[9], 9*7);
    assert_eq!(s, "abc");
    assert_eq!(ys[0], 0);
}
<commit_msg>Add some more tests<commit_after>//! A memory allocation arena specialized for types implement Copy.
//!
//! An `Arena` can allocate objects more efficiently than a
//! general-purpose allocator, but the objects cannot be
//! deallocated until the `Arena` itself is destroyed.
//!
//! To actually allocate out of an `Arena` after creating it,
//! use its `allocator()` method to create an `Allocator`.
//!
//! # Examples
//!
//! ```
//! use copy_arena::Arena;
//!
//! let mut arena = Arena::new();
//! let mut allocator = arena.allocator();
//!
//! let a: &mut i32 = allocator.alloc(5);
//! let b: &mut f64 = allocator.alloc_default();
//! let c: &mut [u8] = allocator.alloc_slice(b"some text");
//! let b: &mut [usize] = allocator.alloc_slice_fn(10, |idx| idx + 1);
//! let e: &mut [u32] = allocator.alloc_slice_default(10);
//! ```

use std::mem;
use std::cmp;
use std::usize;
use std::default::Default;
use std::slice;
use std::fmt;

struct Chunk {
    data: Vec<u8>,
    next: Option<Box<Chunk>>,
}

impl Chunk {
    fn attempt_alloc(&mut self, size: usize, align: usize) -> Option<*mut u8> {
        let start = round_up(self.data.len(), align);

        if size <= self.data.capacity() && start <= self.data.capacity() - size {
            Some(unsafe {
                self.data.set_len(start + size);
                self.data.as_mut_ptr().offset(start as isize)
            })
        } else {
            None
        }
    }
}

/// Holds the backing memory for allocated objects out of itself.
///
/// Actual allocation into the `Arena` happens via an `Allocator` returned
/// from `allocator()`.
pub struct Arena {
    head: Chunk,
}

impl Arena {
    /// Construct a new Arena. This _does_ allocate an block of memory.
    pub fn new() -> Arena {
        Arena::with_capacity(1000)
    }

    /// Construct a new Arena with the given initial capacity.
    ///
    /// The chosen capacity does not limit the final size of the arena.
    pub fn with_capacity(capacity: usize) -> Arena {
        Arena {
            head: Chunk{
                data: Vec::with_capacity(capacity),
                next: None,
            }
        }
    }

    fn add_chunk(&mut self, chunk_size: usize) {
        let mut new_head = Chunk {
            data: Vec::with_capacity(chunk_size),
            next: None,
        };

        mem::swap(&mut self.head, &mut new_head);
        self.head.next = Some(Box::new(new_head));
    }

    /// Construct an Allocator for this arena.
    pub fn allocator(&mut self) -> Allocator {
        Allocator {
            arena: self
        }
    }

    /// Get the number of bytes of memory that have been allocated
    /// in service of this arena. Not all of this capacity is necessarily
    /// useful, since asked-for memory may not perfectly fit in the
    /// underlying blocks allocated.
    pub fn capacity(&self) -> usize {
        let mut iter: &Chunk = &self.head;
        let mut total_capacity = 0;
        loop {
            total_capacity += iter.data.capacity();
            match iter.next {
                None => { return total_capacity; }
                Some(ref next) => { iter = next; }
            }
        }
    }
}

impl fmt::Debug for Arena {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_fmt(format_args!("Arena {{ capacity_bytes: {} }}", self.capacity()))
    }
}

/// Allows allocation out of arena.
#[derive(Debug)]
pub struct Allocator<'a> {
    arena: &'a mut Arena,
}

#[inline]
fn round_up(base: usize, align: usize) -> usize {
    (base + (align - 1)) & !(align - 1)
}

impl<'a> Allocator<'a> {
    fn alloc_raw(&mut self, size: usize, align: usize) -> &'a mut u8 {
        loop {
            match self.arena.head.attempt_alloc(size, align) {
                Some(x) => { return unsafe { mem::transmute(x) } },
                None => {
                    // Double the current allocation (or the asked for one), but don't overflow.
                    let minimum_reasonable = cmp::max(self.arena.head.data.len(), size);
                    let new_chunk_size = 2 * cmp::min(minimum_reasonable, usize::MAX/2);
                    self.arena.add_chunk(new_chunk_size);
                }
            }
        }
    }

    /// Allocate a copy of an object
    pub fn alloc<T: Copy>(&mut self, elem: T) -> &'a mut T {
        let memory = self.alloc_raw(mem::size_of::<T>(), mem::min_align_of::<T>());
        let res: &'a mut T = unsafe { mem::transmute(memory) };
        *res = elem;
        res
    }

    /// Allocate a default-valued object
    pub fn alloc_default<T: Copy+Default>(&mut self) -> &'a mut T {
        self.alloc(Default::default())
    }

    /// Allocate and leave uninitialized a slice of the given length
    fn alloc_slice_raw<T>(&mut self, len: usize) -> &'a mut [T] {
        let element_size = cmp::max(mem::size_of::<T>(), mem::min_align_of::<T>());
        assert_eq!(mem::size_of::<[T;7]>(), 7 * element_size);
        let byte_count = element_size.checked_mul(len).expect("Arena slice size overflow");
        let memory = self.alloc_raw(byte_count, mem::min_align_of::<T>());
        let res: &'a mut [T] = unsafe { slice::from_raw_parts_mut( mem::transmute(memory), len) };
        res
    }

    /// Allocate a copy of a slice
    pub fn alloc_slice<T: Copy>(&mut self, elems: &[T]) -> &'a mut [T] {
        let mut slice = self.alloc_slice_raw(elems.len());
        for (dest, src) in slice.iter_mut().zip(elems.iter()) {
            *dest = *src;
        }
        slice
    }

    /// Allocate and populate a slice, creating each element as a function
    /// of its index.
    pub fn alloc_slice_fn<T: Copy, F>(&mut self, len: usize, mut f: F)-> &'a mut [T]
        where F: FnMut(usize) -> T
    {
        let mut slice = self.alloc_slice_raw(len);
        for (idx, dest) in slice.iter_mut().enumerate() {
            *dest = f(idx)
        }
        slice
    }

    /// Allocate a slice populated by default-valued elements.
    pub fn alloc_slice_default<T: Copy+Default>(&mut self, len: usize)-> &'a mut [T] {
        self.alloc_slice_fn(len, |_| Default::default())
    }
}

#[test]
fn construct_simple() {
    let mut arena = Arena::with_capacity(4);
    let mut allocator = arena.allocator();

    let x: &mut i32 = allocator.alloc(44);
    let y: &mut u8 = allocator.alloc(3);
    let z: &mut u32 = allocator.alloc(0x11223344);
    let w: &mut f64 = allocator.alloc_default();
    assert_eq!(*x, 44);
    assert_eq!(*y, 3);
    assert_eq!(*z, 0x11223344);
    assert_eq!(*w, 0.0);
}

#[test]
fn just_enough_capacity() {
    let mut arena = Arena::with_capacity(7);
    arena.allocator().alloc_slice_default::<u8>(7);

    assert!(arena.head.next.is_none());
    assert_eq!(arena.head.data.len(), 7);
}

#[test]
fn barely_too_little_capacity() {
    let mut arena = Arena::with_capacity(7);
    arena.allocator().alloc_slice_default::<u8>(8);

    assert!(arena.head.next.is_some());
    assert_eq!(arena.head.data.len(), 8);
}

#[test]
fn many_u8s() {
    let mut arena = Arena::with_capacity(52);
    for i in 0..100 {
        assert_eq!(*arena.allocator().alloc(4), 4u8);
        assert_eq!(arena.head.data.len(), (i % 52) + 1);
    }
    assert!(arena.head.data.capacity() > 52);
}

#[test]
fn zero_capacity() {
    let mut arena = Arena::with_capacity(0);
    assert_eq!(arena.head.data.capacity(), 0);

    assert_eq!(*arena.allocator().alloc(9u32), 9u32);

    assert!(arena.head.data.capacity()>=4);
    assert!(arena.head.data.len()==4);
}

#[test]
fn surprisingly_large() {
    // Make sure asking for an allocation that is larger than the
    // block we otherwise would have allocated works fine.
    let mut arena = Arena::with_capacity(10);

    {
        let mut allocator = arena.allocator();
        let x = allocator.alloc(7u32);
        let ys : &[u8] = allocator.alloc_slice_default(600);

        assert_eq!(*x, 7u32);
        assert_eq!(ys.len(), 600);
    }

    assert!(arena.head.next.is_some());
    assert!(arena.head.data.capacity() >= 600);
    assert_eq!(arena.head.data.len(), 600);
}

#[test]
fn construct_slices() {
    let mut arena = Arena::with_capacity(4);
    let mut allocator = arena.allocator();

    let s = ::std::str::from_utf8(allocator.alloc_slice(b"abc")).unwrap();
    let xs: &[i32] = allocator.alloc_slice_fn(10, |idx| (idx as i32)*7);
    let ys: &[u64] = allocator.alloc_slice_default(4);

    assert_eq!(xs[9], 9*7);
    assert_eq!(s, "abc");
    assert_eq!(ys[0], 0);
}
<|endoftext|>


<commit_before>
//  key
//      value
//  Key {
//      value: Value::String,
//      sub: Value::String
//  }
//
//  key
//      value1
//      value2
//  Key {
//      value: Value::String,
//      sub: Value::List(vec![Value::String, value::String])
//  }
//
//  key
//      value
//          sub
//      value
//  Key {
//      value: Value::String,
//      sub: Value::List(vec![Value::Key(Key {
//                                           value: Value::String
//                                           sub: Value::String
//                                       }),
//                            Value::String])
//  }
//

#[derive(Debug, PartialEq)]
pub struct Key {
    value: Value,
    sub: Value,
}

impl Key {
    fn add(&mut self, v: Value) {
        if self.sub.is_list() {
            self.sub.push(v);
            } else if self.sub.user {
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum Value {
    List(Vec<Value>),
    Bool(bool),
    Integer(i64),
    Float(f64),
    Date(String), // TODO
    Key(Box<Key>),
}

impl From<bool> for Value {
    fn from(b: bool) -> Value {
        Value::Bool(b)
    }
}

impl From<i64> for Value {
    fn from(i: i64) -> Value {
        Value::Integer(i)
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Value {
        Value::Float(f)
    }
}

impl<T> From<Vec<T>> for Value where Value: From<T> {
    fn from(v: Vec<T>) -> Value {
        Value::List(v.into_iter().map(|x| Value::from(x)).collect())
    }
}

impl Value {
    fn is_list(&v: Value) -> bool {
        match v {
            Value::List(_) => true,
            _ => false
        }
    }

    fn push(&mut self, v: Value) {
        match *self {
            Value::List(l) => l.push(v),
            _ => panic!("Called push on non-List")
        }
    }
}

<commit_msg>a whole lot<commit_after>
use std::ops::{Index, IndexMut};

#[derive(Debug)]
pub enum Error {
    KeyNotFound,
}

// top level key that contains everything is __top_level__
#[derive(Clone, Debug, PartialEq)]
pub struct Pair {
    pub key: Value,
    pub value: Vec<Pair>
}

impl Pair {
    pub fn new<T>(key: T) -> Pair where Value: From<T> {
        Pair {
            key: Value::from(key),
            value: vec![]
        }
    }

    pub fn add<T>(&mut self, val: T) where Value: From<T> {
        self.value.push(Pair::new(val));
    }

    pub fn add_pair(&mut self, p: Pair) {
        self.value.push(p);
    }

    pub fn get(&self, value: Value) -> Result<&Pair, Error> {
        let mut p = None;
        for (k, v) in self.value.iter().enumerate() {
            if v.key == value {
                p = Some(k);
            }
        }
        if p.is_some() {
            Ok(&self.value[p.unwrap()])
        } else {
            Err(Error::KeyNotFound)
        }
    }

    pub fn get_mut(&mut self, value: Value) -> Result<&mut Pair, Error> {
        let mut p = None;
        for (k, v) in self.value.iter().enumerate() {
            if v.key == value {
                p = Some(k);
            }
        }
        if p.is_some() {
            Ok(&mut self.value[p.unwrap()])
        } else {
            Err(Error::KeyNotFound)
        }
    }
}

impl Index<Value> for Pair {
    type Output = Pair;

    fn index(&self, value: Value) -> &Pair {
        self.get(value).expect("Did not find value in pair")
    }
}

impl IndexMut<Value> for Pair {
    fn index_mut(&mut self, value: Value) -> &mut Pair {
        self.get_mut(value).expect("Did not find value in pair")
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Value {
    String(String),
    List(Vec<Value>),
    Bool(bool),
    Integer(i64),
    Float(f64),
    Date(String), // TODO
}

impl From<String> for Value {
    fn from(s: String) -> Value {
        Value::String(s)
    }
}

impl<'a> From<&'a str> for Value {
    fn from(s: &'a str) -> Value {
        Value::String(s.to_owned())
    }
}

impl From<bool> for Value {
    fn from(b: bool) -> Value {
        Value::Bool(b)
    }
}

impl From<i64> for Value {
    fn from(i: i64) -> Value {
        Value::Integer(i)
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Value {
        Value::Float(f)
    }
}

impl<T> From<Vec<T>> for Value where Value: From<T> {
    fn from(v: Vec<T>) -> Value {
        Value::List(v.into_iter().map(Value::from).collect())
    }
}

<|endoftext|>


<commit_before>#![feature(slicing_syntax)]
extern crate test;

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{Writer, Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
pub use self::EdgeDirection::{Outgoing, Incoming};
mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, S: Writer> Hash<S> for Ptr<'b, T>
{
    fn hash(&self, st: &mut S)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

pub fn dijkstra<'a,
                Graph, N, K,
                F, Edges>(graph: &'a Graph, start: N, mut edges: F) -> HashMap<N, K>
where
    N: Copy + Clone + Eq + Hash + fmt::Show,
    K: Default + Add<Output=K> + Copy + PartialOrd + fmt::Show,
    F: FnMut(&'a Graph, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
{
    let mut visited = HashSet::new();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    loop {
        let MinScored(node_score, node) = match visit_next.pop() {
            None => break,
            Some(t) => t,
        };
        if visited.contains(&node) {
            continue
        }
        println!("Visiting {} with score={}", node, node_score);
        for (next, edge) in edges(graph, node) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(&next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next, node);
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next, node);
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        visited.insert(node);
    }
    println!("{}", predecessor);
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({})", self.0.get())
    }
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait GraphNeighbors<'a, N> {
    type Iter: Iterator<Item=N>;
    fn neighbors(&'a self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> GraphNeighbors<'a, N> for Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> GraphNeighbors<'a, N> for DiGraph<N, E>
where N: Copy + Clone + Hash + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(&'a self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E> GraphNeighbors<'a, ograph::NodeIndex> for OGraph<N, E>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n, EdgeDirection::Outgoing)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct Undirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> GraphNeighbors<'a, ograph::NodeIndex> for Undirected<&'b OGraph<N, E>>
{
    type Iter = ograph::NeighborsBoth<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::NeighborsBoth<'a, E>
    {
        OGraph::neighbors_both(self.0, n)
    }
}

impl<'a, 'b, N, E> GraphNeighbors<'a, ograph::NodeIndex> for Reversed<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable<N> {
    type Map: VisitMap<N>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E> Visitable<ograph::NodeIndex> for OGraph<N, E>
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Undirected<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Reversed<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N>
    where
        G: 'a,
        N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N>
    where
        G: 'a + GraphNeighbors<'a, N>,
        N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G, N> Iterator for BreadthFirst<'a, G, N>
    where
        G: 'a + GraphNeighbors<'a, N>,
        N: Copy + Eq + Hash,
        <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// A depth first traversal of a graph.
#[derive(Clone)]
pub struct DepthFirst<'a, G, N>
    where
        G: 'a,
        N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: Vec<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> DepthFirst<'a, G, N>
    where
        G: 'a + GraphNeighbors<'a, N>,
        N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> DepthFirst<'a, G, N>
    {
        DepthFirst{
            graph: graph,
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl<'a, G, N> Iterator for DepthFirst<'a, G, N>
    where
        G: 'a + GraphNeighbors<'a, N>,
        N: Copy + Eq + Hash,
        <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub fn depth_first_search<'a, G, N, F>(graph: &'a G, start: N, mut f: F) -> bool
    where
        G: 'a + GraphNeighbors<'a, N> + Visitable<N>,
        N: Clone,
        <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
        <G as Visitable<N>>::Map: VisitMap<N>,
        F: FnMut(N) -> bool,
{
    let mut stack = Vec::new();
    let mut visited = graph.visit_map();

    stack.push(start);
    while let Some(node) = stack.pop() {
        if !visited.visit(node.clone()) {
            continue;
        }

        for succ in graph.neighbors(node.clone()) {
            if !visited.contains(&succ) {
                stack.push(succ);
            }
        }

        if !f(node) {
            return false
        }
    }
    true
}

<commit_msg>Use less indented where syntax<commit_after>#![feature(slicing_syntax)]
extern crate test;

use std::default::Default;
use std::cmp::Ordering;
use std::cell::Cell;
use std::hash::{Writer, Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::collections::BitvSet;
use std::collections::BinaryHeap;
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};
use std::fmt;
use std::ops::{Add, Deref};

pub use scored::MinScored;
pub use digraph::DiGraph;
pub use graph::Graph;
pub use ograph::OGraph;
pub use self::EdgeDirection::{Outgoing, Incoming};
mod scored;
pub mod digraph;
pub mod graph;
pub mod ograph;

pub mod unionfind;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Show, PartialEq)]
pub enum EdgeDirection {
    /// A **Outgoing** edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An **Incoming** edge is an inbound edge *to* the current node.
    Incoming = 1
}

/// A reference that is hashed and compared by its pointer value.
pub struct Ptr<'b, T: 'b>(pub &'b T);

impl<'b, T> Copy for Ptr<'b, T> {}
impl<'b, T> Clone for Ptr<'b, T>
{
    fn clone(&self) -> Self { *self }
}

fn ptreq<T>(a: &T, b: &T) -> bool {
    a as *const _ == b as *const _
}

impl<'b, T> PartialEq for Ptr<'b, T>
{
    /// Ptr compares by pointer equality, i.e if they point to the same value
    fn eq(&self, other: &Ptr<'b, T>) -> bool {
        ptreq(self.0, other.0)
    }
}

impl<'b, T> PartialOrd for Ptr<'b, T>
{
    fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'b, T> Ord for Ptr<'b, T>
{
    /// Ptr is ordered by pointer value, i.e. an arbitrary but stable and total order.
    fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
        let a = self.0 as *const _;
        let b = other.0 as *const _;
        a.cmp(&b)
    }
}

impl<'b, T> Deref for Ptr<'b, T> {
    type Target = T;
    fn deref<'a>(&'a self) -> &'a T {
        self.0
    }
}

impl<'b, T> Eq for Ptr<'b, T> {}

impl<'b, T, S: Writer> Hash<S> for Ptr<'b, T>
{
    fn hash(&self, st: &mut S)
    {
        let ptr = (self.0) as *const _;
        ptr.hash(st)
    }
}

impl<'b, T: fmt::Show> fmt::Show for Ptr<'b, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

pub fn dijkstra<'a,
                Graph, N, K,
                F, Edges>(graph: &'a Graph, start: N, mut edges: F) -> HashMap<N, K>
where
    N: Copy + Clone + Eq + Hash + fmt::Show,
    K: Default + Add<Output=K> + Copy + PartialOrd + fmt::Show,
    F: FnMut(&'a Graph, N) -> Edges,
    Edges: Iterator<Item=(N, K)>,
{
    let mut visited = HashSet::new();
    let mut scores = HashMap::new();
    let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score: K = Default::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    loop {
        let MinScored(node_score, node) = match visit_next.pop() {
            None => break,
            Some(t) => t,
        };
        if visited.contains(&node) {
            continue
        }
        println!("Visiting {} with score={}", node, node_score);
        for (next, edge) in edges(graph, node) {
            if visited.contains(&next) {
                continue
            }
            let mut next_score = node_score + edge;
            match scores.entry(&next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    predecessor.insert(next, node);
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    predecessor.insert(next, node);
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        visited.insert(node);
    }
    println!("{}", predecessor);
    scores
}

#[derive(Show)]
pub struct Node<T>(pub T);

pub struct NodeCell<T: Copy>(pub Cell<T>);

impl<T: Copy> Deref for NodeCell<T> {
    type Target = Cell<T>;
    #[inline]
    fn deref(&self) -> &Cell<T> {
        &self.0
    }
}

impl<T: Copy + fmt::Show> fmt::Show for NodeCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Node({})", self.0.get())
    }
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait GraphNeighbors<'a, N> {
    type Iter: Iterator<Item=N>;
    fn neighbors(&'a self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> GraphNeighbors<'a, N> for Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> GraphNeighbors<'a, N> for DiGraph<N, E>
where N: Copy + Clone + Hash + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(&'a self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E> GraphNeighbors<'a, ograph::NodeIndex> for OGraph<N, E>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n, EdgeDirection::Outgoing)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct Undirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> GraphNeighbors<'a, ograph::NodeIndex> for Undirected<&'b OGraph<N, E>>
{
    type Iter = ograph::NeighborsBoth<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::NeighborsBoth<'a, E>
    {
        OGraph::neighbors_both(self.0, n)
    }
}

impl<'a, 'b, N, E> GraphNeighbors<'a, ograph::NodeIndex> for Reversed<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(&'a self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable<N> {
    type Map: VisitMap<N>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E> Visitable<ograph::NodeIndex> for OGraph<N, E>
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N, E> Visitable<N> for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Undirected<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

impl<'a, N, V: Visitable<N>> Visitable<N> for Reversed<&'a V>
{
    type Map = <V as Visitable<N>>::Map;
    fn visit_map(&self) -> <V as Visitable<N>>::Map {
        self.0.visit_map()
    }
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N> where
    G: 'a + GraphNeighbors<'a, N>,
    N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G, N> Iterator for BreadthFirst<'a, G, N> where
    G: 'a + GraphNeighbors<'a, N>,
    N: Copy + Eq + Hash,
    <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// A depth first traversal of a graph.
#[derive(Clone)]
pub struct DepthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash,
{
    pub graph: &'a G,
    pub stack: Vec<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> DepthFirst<'a, G, N> where
    G: 'a + GraphNeighbors<'a, N>,
    N: Copy + Eq + Hash,
{
    pub fn new(graph: &'a G, start: N) -> DepthFirst<'a, G, N>
    {
        DepthFirst{
            graph: graph,
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl<'a, G, N> Iterator for DepthFirst<'a, G, N> where
    G: 'a + GraphNeighbors<'a, N>,
    N: Copy + Eq + Hash,
    <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub fn depth_first_search<'a, G, N, F>(graph: &'a G, start: N, mut f: F) -> bool where
    G: 'a + GraphNeighbors<'a, N> + Visitable<N>,
    N: Clone,
    <G as GraphNeighbors<'a, N>>::Iter: Iterator<Item=N>,
    <G as Visitable<N>>::Map: VisitMap<N>,
    F: FnMut(N) -> bool,
{
    let mut stack = Vec::new();
    let mut visited = graph.visit_map();

    stack.push(start);
    while let Some(node) = stack.pop() {
        if !visited.visit(node.clone()) {
            continue;
        }

        for succ in graph.neighbors(node.clone()) {
            if !visited.contains(&succ) {
                stack.push(succ);
            }
        }

        if !f(node) {
            return false
        }
    }
    true
}

<|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);

/// 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;
}
<commit_msg>Added lock field<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,
    lock: c_int,
    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>//! A library providing a generic connection pool.
#![feature(unsafe_destructor)]
#![warn(missing_doc)]
#![doc(html_root_url="http://www.rust-ci.org/sfackler/r2d2/doc")]

use std::comm;
use std::cmp;
use std::collections::{Deque, RingBuf};
use std::sync::{Arc, Mutex};
use std::fmt;

pub use config::Config;

mod config;

/// A trait which provides database-specific functionality.
pub trait PoolManager<C, E>: Send+Sync {
    /// Attempts to create a new connection.
    fn connect(&self) -> Result<C, E>;

    /// Determines if the connection is still connected to the database.
    ///
    /// A standard implementation would check if a simple query like `SELECT 1`
    /// succeeds.
    fn is_valid(&self, conn: &C) -> bool;
}

/// An error type returned if pool creation fails.
#[deriving(PartialEq, Eq)]
pub enum NewPoolError<E> {
    /// The provided pool configuration was invalid.
    InvalidConfig(&'static str),
    /// The manager returned an error when creating a connection.
    ConnectionError(E),
}

impl<E: fmt::Show> fmt::Show for NewPoolError<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            InvalidConfig(ref error) => write!(f, "Invalid config: {}", error),
            ConnectionError(ref error) => write!(f, "Unable to create connections: {}", error),
        }
    }
}

enum Command<C> {
    AddConnection,
    TestConnection(C),
}

struct PoolInternals<C, E> {
    conns: RingBuf<C>,
    failed_conns: RingBuf<E>,
    num_conns: uint,
}

struct InnerPool<C, E, M> {
    config: Config,
    manager: M,
    internals: Mutex<PoolInternals<C, E>>,
}

/// A generic connection pool.
pub struct Pool<C, E, M> {
    helper_chan: Sender<Command<C>>,
    inner: Arc<InnerPool<C, E, M>>
}

impl<C: Send, E: Send, M: PoolManager<C, E>> Pool<C, E, M> {
    /// Creates a new connection pool.
    pub fn new(config: Config, manager: M) -> Result<Pool<C, E, M>, NewPoolError<E>> {
        match config.validate() {
            Ok(()) => {}
            Err(err) => return Err(InvalidConfig(err))
        }

        let mut internals = PoolInternals {
            conns: RingBuf::new(),
            failed_conns: RingBuf::new(),
            num_conns: config.initial_size,
        };

        for _ in range(0, config.initial_size) {
            match manager.connect() {
                Ok(conn) => internals.conns.push(conn),
                Err(err) => return Err(ConnectionError(err)),
            }
        }

        let inner = Arc::new(InnerPool {
            config: config,
            manager: manager,
            internals: Mutex::new(internals),
        });

        let (sender, receiver) = comm::channel();
        // FIXME :(
        let receiver = Arc::new(Mutex::new(receiver));

        for _ in range(0, config.helper_tasks) {
            let inner = inner.clone();
            let receiver = receiver.clone();
            spawn(proc() helper_task(receiver, inner));
        }

        Ok(Pool {
            helper_chan: sender,
            inner: inner,
        })
    }

    /// Retrieves a connection from the pool.
    pub fn get<'a>(&'a self) -> Result<PooledConnection<'a, C, E, M>, E> {
        let mut internals = self.inner.internals.lock();

        loop {
            match internals.conns.pop_front() {
                Some(conn) => {
                    if self.inner.config.test_on_check_out && !self.inner.manager.is_valid(&conn) {
                        internals.num_conns -= 1;
                        continue;
                    }

                    return Ok(PooledConnection {
                        pool: self,
                        conn: Some(conn)
                    })
                }
                None => {
                    match internals.failed_conns.pop_front() {
                        Some(err) => return Err(err),
                        None => {}
                    }

                    let new_conns = cmp::min(self.inner.config.max_size - internals.num_conns,
                                             self.inner.config.acquire_increment);
                    for _ in range(0, new_conns) {
                        self.helper_chan.send(AddConnection);
                        internals.num_conns += 1;
                    }

                    internals.cond.wait();
                }
            }
        }
    }

    fn put_back(&self, conn: C) {
        let mut internals = self.inner.internals.lock();
        internals.conns.push(conn);
        internals.cond.signal();
    }
}

fn helper_task<C: Send, E: Send, M: PoolManager<C, E>>(receiver: Arc<Mutex<Receiver<Command<C>>>>,
                                                       inner: Arc<InnerPool<C, E, M>>) {
    loop {
        let mut receiver = receiver.lock();
        let res = receiver.recv_opt();
        drop(receiver);

        match res {
            Ok(AddConnection) => add_connection(&*inner),
            Ok(TestConnection(conn)) => test_connection(&*inner, conn),
            Err(()) => break,
        }
    }
}

fn add_connection<C: Send, E: Send, M: PoolManager<C, E>>(inner: &InnerPool<C, E, M>) {
    let res = inner.manager.connect();
    let mut internals = inner.internals.lock();
    match res {
        Ok(conn) => {
            internals.conns.push(conn);
        }
        Err(err) => {
            internals.failed_conns.push(err);
            internals.num_conns -= 1;
        }
    }
    internals.cond.signal();
}

fn test_connection<C: Send, E: Send, M: PoolManager<C, E>>(inner: &InnerPool<C, E, M>, conn: C) {
    let is_valid = inner.manager.is_valid(&conn);
    let mut internals = inner.internals.lock();
    if is_valid {
        internals.conns.push(conn);
    } else {
        internals.num_conns -= 1;
    }
}

/// A smart pointer wrapping an underlying connection.
///
/// ## Note
///
/// Due to Rust bug [#15905](https://github.com/rust-lang/rust/issues/15905),
/// the connection cannot be automatically returned to its pool when the
/// `PooledConnection` drops out of scope. The `replace` method must be called,
/// or the `PooledConnection`'s destructor will `fail!()`.
pub struct PooledConnection<'a, C, E, M> {
    pool: &'a Pool<C, E, M>,
    conn: Option<C>,
}

impl<'a, C: Send, E: Send, M: PoolManager<C, E>> PooledConnection<'a, C, E, M> {
    /// Consumes the `PooledConnection`, returning the connection to its pool.
    ///
    /// This must be called before the `PooledConnection` drops out of scope or
    /// its destructor will `fail!()`.
    pub fn replace(mut self) {
        self.pool.put_back(self.conn.take_unwrap())
    }
}

#[unsafe_destructor]
impl<'a, C, E, M> Drop for PooledConnection<'a, C, E, M> {
    fn drop(&mut self) {
        if self.conn.is_some() {
            fail!("You must call conn.replace()");
        }
    }
}

impl<'a, C, E, M> Deref<C> for PooledConnection<'a, C, E, M> {
    fn deref(&self) -> &C {
        self.conn.get_ref()
    }
}
<commit_msg>Update to rust master<commit_after>//! A library providing a generic connection pool.
#![feature(unsafe_destructor)]
#![warn(missing_doc)]
#![doc(html_root_url="http://www.rust-ci.org/sfackler/r2d2/doc")]

use std::comm;
use std::cmp;
use std::collections::{Deque, RingBuf};
use std::sync::{Arc, Mutex};
use std::fmt;

pub use config::Config;

mod config;

/// A trait which provides database-specific functionality.
pub trait PoolManager<C, E>: Send+Sync {
    /// Attempts to create a new connection.
    fn connect(&self) -> Result<C, E>;

    /// Determines if the connection is still connected to the database.
    ///
    /// A standard implementation would check if a simple query like `SELECT 1`
    /// succeeds.
    fn is_valid(&self, conn: &C) -> bool;
}

/// An error type returned if pool creation fails.
#[deriving(PartialEq, Eq)]
pub enum NewPoolError<E> {
    /// The provided pool configuration was invalid.
    InvalidConfig(&'static str),
    /// The manager returned an error when creating a connection.
    ConnectionError(E),
}

impl<E: fmt::Show> fmt::Show for NewPoolError<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            InvalidConfig(ref error) => write!(f, "Invalid config: {}", error),
            ConnectionError(ref error) => write!(f, "Unable to create connections: {}", error),
        }
    }
}

enum Command<C> {
    AddConnection,
    TestConnection(C),
}

struct PoolInternals<C, E> {
    conns: RingBuf<C>,
    failed_conns: RingBuf<E>,
    num_conns: uint,
}

struct InnerPool<C, E, M> {
    config: Config,
    manager: M,
    internals: Mutex<PoolInternals<C, E>>,
}

/// A generic connection pool.
pub struct Pool<C, E, M> {
    helper_chan: Sender<Command<C>>,
    inner: Arc<InnerPool<C, E, M>>
}

impl<C: Send, E: Send, M: PoolManager<C, E>> Pool<C, E, M> {
    /// Creates a new connection pool.
    pub fn new(config: Config, manager: M) -> Result<Pool<C, E, M>, NewPoolError<E>> {
        match config.validate() {
            Ok(()) => {}
            Err(err) => return Err(InvalidConfig(err))
        }

        let mut internals = PoolInternals {
            conns: RingBuf::new(),
            failed_conns: RingBuf::new(),
            num_conns: config.initial_size,
        };

        for _ in range(0, config.initial_size) {
            match manager.connect() {
                Ok(conn) => internals.conns.push(conn),
                Err(err) => return Err(ConnectionError(err)),
            }
        }

        let inner = Arc::new(InnerPool {
            config: config,
            manager: manager,
            internals: Mutex::new(internals),
        });

        let (sender, receiver) = comm::channel();
        // FIXME :(
        let receiver = Arc::new(Mutex::new(receiver));

        for _ in range(0, config.helper_tasks) {
            let inner = inner.clone();
            let receiver = receiver.clone();
            spawn(proc() helper_task(receiver, inner));
        }

        Ok(Pool {
            helper_chan: sender,
            inner: inner,
        })
    }

    /// Retrieves a connection from the pool.
    pub fn get<'a>(&'a self) -> Result<PooledConnection<'a, C, E, M>, E> {
        let mut internals = self.inner.internals.lock();

        loop {
            match internals.conns.pop_front() {
                Some(conn) => {
                    if self.inner.config.test_on_check_out && !self.inner.manager.is_valid(&conn) {
                        internals.num_conns -= 1;
                        continue;
                    }

                    return Ok(PooledConnection {
                        pool: self,
                        conn: Some(conn)
                    })
                }
                None => {
                    match internals.failed_conns.pop_front() {
                        Some(err) => return Err(err),
                        None => {}
                    }

                    let new_conns = cmp::min(self.inner.config.max_size - internals.num_conns,
                                             self.inner.config.acquire_increment);
                    for _ in range(0, new_conns) {
                        self.helper_chan.send(AddConnection);
                        internals.num_conns += 1;
                    }

                    internals.cond.wait();
                }
            }
        }
    }

    fn put_back(&self, conn: C) {
        let mut internals = self.inner.internals.lock();
        internals.conns.push(conn);
        internals.cond.signal();
    }
}

fn helper_task<C: Send, E: Send, M: PoolManager<C, E>>(receiver: Arc<Mutex<Receiver<Command<C>>>>,
                                                       inner: Arc<InnerPool<C, E, M>>) {
    loop {
        let mut receiver = receiver.lock();
        let res = receiver.recv_opt();
        drop(receiver);

        match res {
            Ok(AddConnection) => add_connection(&*inner),
            Ok(TestConnection(conn)) => test_connection(&*inner, conn),
            Err(()) => break,
        }
    }
}

fn add_connection<C: Send, E: Send, M: PoolManager<C, E>>(inner: &InnerPool<C, E, M>) {
    let res = inner.manager.connect();
    let mut internals = inner.internals.lock();
    match res {
        Ok(conn) => {
            internals.conns.push(conn);
        }
        Err(err) => {
            internals.failed_conns.push(err);
            internals.num_conns -= 1;
        }
    }
    internals.cond.signal();
}

fn test_connection<C: Send, E: Send, M: PoolManager<C, E>>(inner: &InnerPool<C, E, M>, conn: C) {
    let is_valid = inner.manager.is_valid(&conn);
    let mut internals = inner.internals.lock();
    if is_valid {
        internals.conns.push(conn);
    } else {
        internals.num_conns -= 1;
    }
}

/// A smart pointer wrapping an underlying connection.
///
/// ## Note
///
/// Due to Rust bug [#15905](https://github.com/rust-lang/rust/issues/15905),
/// the connection cannot be automatically returned to its pool when the
/// `PooledConnection` drops out of scope. The `replace` method must be called,
/// or the `PooledConnection`'s destructor will `fail!()`.
pub struct PooledConnection<'a, C: 'a, E: 'a, M: 'a> {
    pool: &'a Pool<C, E, M>,
    conn: Option<C>,
}

impl<'a, C: Send, E: Send, M: PoolManager<C, E>> PooledConnection<'a, C, E, M> {
    /// Consumes the `PooledConnection`, returning the connection to its pool.
    ///
    /// This must be called before the `PooledConnection` drops out of scope or
    /// its destructor will `fail!()`.
    pub fn replace(mut self) {
        self.pool.put_back(self.conn.take().unwrap())
    }
}

#[unsafe_destructor]
impl<'a, C, E, M> Drop for PooledConnection<'a, C, E, M> {
    fn drop(&mut self) {
        if self.conn.is_some() {
            fail!("You must call conn.replace()");
        }
    }
}

impl<'a, C, E, M> Deref<C> for PooledConnection<'a, C, E, M> {
    fn deref(&self) -> &C {
        self.conn.as_ref().unwrap()
    }
}
<|endoftext|>


<commit_before>
//! A repeating-key XOR functions.
//!
//! This functions might be useful to play with
//! [the matasano crypto challenges](http://cryptopals.com).

#[cfg(test)]
#[macro_use(expect)]
extern crate expectest;

/// Returns result of a XOR operation applied to a `source` byte sequence.
///
/// `key` will be an infinitely repeating byte sequence.
pub fn xor(source: &[u8], key: &[u8]) -> Vec<u8> {
    match key.len() {
        0 => source.to_vec(),
        1 => xor_with_byte(source, key[0]),
        _ => {
            let key_iter = InfiniteByteIterator::new(key);
            source.iter().zip(key_iter).map(|(&a, b)| a ^ b).collect()
        },
    }
}

/// Returns result of a XOR operation applied to a `source` byte sequence.
///
/// `byte` will be an infinitely repeating byte sequence.
pub fn xor_with_byte(source: &[u8], byte: u8) -> Vec<u8> {
    source.iter().map(|&a| a ^ byte).collect()
}

struct InfiniteByteIterator<'a> {
    bytes: &'a [u8],
    index: usize
}

impl<'a> InfiniteByteIterator<'a> {
    pub fn new(bytes: &'a [u8]) -> InfiniteByteIterator<'a> {
        InfiniteByteIterator {
            bytes: bytes,
            index: 0
        }
    }
}

impl<'a> Iterator for InfiniteByteIterator<'a> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        let byte = self.bytes[self.index];
        self.index = next_index(self.index, self.bytes.len());
        Some(byte)
    }
}

fn next_index(index: usize, count: usize) -> usize {
    if index + 1 < count { index + 1 } else { 0 }
}

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

    #[test]
    fn xor_valid_result() {
        let source = &[0, 1, 2, 3];
        let key = &[34, 52];
        expect!(xor(source, key)).to(be_equal_to([34, 53, 32, 55]));
    }

    #[test]
    fn xor_valid_result_with_one_byte() {
        let source = &[0, 1, 2, 3];
        let key = &[47];
        expect!(xor(source, key)).to(be_equal_to([47, 46, 45, 44]));
    }

    #[test]
    fn xor_empty_key() {
        let source = &[0, 1, 2, 3];
        let key = &[];
        expect!(xor(source, key)).to(be_equal_to(source));
    }

    #[test]
    fn xor_empty_source() {
        let source = &[];
        let key = &[45, 32, 56];
        expect!(xor(source, key)).to(be_equal_to([]));
    }

    #[test]
    fn xor_with_byte_valid_result() {
        let source = &[0, 1, 2, 3];
        expect!(xor_with_byte(source, 23)).to(be_equal_to([23, 22, 21, 20]));
    }
}
<commit_msg>Clean up tests.<commit_after>
//! A repeating-key XOR functions.
//!
//! This functions might be useful to play with
//! [the matasano crypto challenges](http://cryptopals.com).

#[cfg(test)]
#[macro_use(expect)]
extern crate expectest;

/// Returns result of a XOR operation applied to a `source` byte sequence.
///
/// `key` will be an infinitely repeating byte sequence.
pub fn xor(source: &[u8], key: &[u8]) -> Vec<u8> {
    match key.len() {
        0 => source.to_vec(),
        1 => xor_with_byte(source, key[0]),
        _ => {
            let key_iter = InfiniteByteIterator::new(key);
            source.iter().zip(key_iter).map(|(&a, b)| a ^ b).collect()
        },
    }
}

/// Returns result of a XOR operation applied to a `source` byte sequence.
///
/// `byte` will be an infinitely repeating byte sequence.
pub fn xor_with_byte(source: &[u8], byte: u8) -> Vec<u8> {
    source.iter().map(|&a| a ^ byte).collect()
}

struct InfiniteByteIterator<'a> {
    bytes: &'a [u8],
    index: usize
}

impl<'a> InfiniteByteIterator<'a> {
    pub fn new(bytes: &'a [u8]) -> InfiniteByteIterator<'a> {
        InfiniteByteIterator {
            bytes: bytes,
            index: 0
        }
    }
}

impl<'a> Iterator for InfiniteByteIterator<'a> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        let byte = self.bytes[self.index];
        self.index = next_index(self.index, self.bytes.len());
        Some(byte)
    }
}

fn next_index(index: usize, count: usize) -> usize {
    if index + 1 < count { index + 1 } else { 0 }
}

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

    #[test]
    fn xor_valid_result() {
        let source = &[0, 1, 2, 3];
        let result = xor(source, &[34, 52]);
        expect!(result).to(be_equal_to([34, 53, 32, 55]));
    }

    #[test]
    fn xor_valid_result_with_one_byte() {
        let source = &[0, 1, 2, 3];
        let result = xor(source, &[47]);
        expect!(result).to(be_equal_to([47, 46, 45, 44]));
    }

    #[test]
    fn xor_empty_key() {
        let source = &[0, 1, 2, 3];
        let result = xor(source, &[]);
        expect!(result).to(be_equal_to(source));
    }

    #[test]
    fn xor_empty_source() {
        let source = &[];
        let result = xor(source, &[45, 32, 56]);
        expect!(result).to(be_empty());
    }

    #[test]
    fn xor_with_byte_valid_result() {
        let source = &[0, 1, 2, 3];
        let result = xor_with_byte(source, 23);
        expect!(result).to(be_equal_to([23, 22, 21, 20]));
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// 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.

//! The time oracle service for Exonum.

#![deny(missing_debug_implementations, missing_docs)]

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use iron::prelude::*;
use iron::Handler;
use router::Router;

use std::time::SystemTime;

use exonum::blockchain::{Blockchain, Service, ServiceContext, Schema, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::encoding::serialize::json::reexport::Value;
use exonum::storage::{Fork, Snapshot, MapIndex, Entry};
use exonum::crypto::PublicKey;
use exonum::encoding;
use exonum::helpers::fabric::{ServiceFactory, Context};
use exonum::api::Api;

/// Time service id.
const SERVICE_ID: u16 = 4;
/// `TxTime` transaction id.
const TX_TIME_ID: u16 = 1;
/// Time service name.
const SERVICE_NAME: &str = "exonum_time";

encoding_struct! {
    /// Time information.
    struct Time {
        const SIZE = 12;

        /// Field that stores `SystemTime`.
        field time:     SystemTime  [00 => 12]
    }
}

/// `Exonum-time` service database schema.
#[derive(Debug)]
pub struct TimeSchema<T> {
    view: T,
}

impl<T: AsRef<Snapshot>> TimeSchema<T> {
    /// Constructs schema for the given `snapshot`.
    pub fn new(view: T) -> Self {
        TimeSchema { view }
    }

    /// Returns the table that stores `Time` struct for every validator.
    pub fn validators_time(&self) -> MapIndex<&Snapshot, PublicKey, Time> {
        MapIndex::new(
            format!("{}.validators_time", SERVICE_NAME),
            self.view.as_ref(),
        )
    }

    /// Returns stored `Time`.
    pub fn time(&self) -> Entry<&Snapshot, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view.as_ref())
    }
}

impl<'a> TimeSchema<&'a mut Fork> {
    /// Mutable reference to the ['validators_time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.validators_time
    pub fn validators_time_mut(&mut self) -> MapIndex<&mut Fork, PublicKey, Time> {
        MapIndex::new(format!("{}.validators_time", SERVICE_NAME), self.view)
    }

    /// Mutable reference to the ['time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.time
    pub fn time_mut(&mut self) -> Entry<&mut Fork, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view)
    }
}

message! {
    /// Transaction that is sent by the validator after the commit of the block.
    struct TxTime {
        const TYPE = SERVICE_ID;
        const ID = TX_TIME_ID;
        const SIZE = 44;
        /// Validator's time.
        field time:     SystemTime  [00 => 12]
        /// Validator's public key.
        field pub_key:  &PublicKey  [12 => 44]
    }
}

impl Transaction for TxTime {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let validator_keys = Schema::new(&view).actual_configuration().validator_keys;

        // The transaction must be signed by the validator.
        let signed = validator_keys.iter().any(|&validator| {
            validator.service_key == *self.pub_key()
        });
        if !signed {
            return;
        }

        let mut schema = TimeSchema::new(view);
        match schema.validators_time().get(self.pub_key()) {
            // The validator time in the storage should be less than in the transaction.
            Some(ref storage_time) if storage_time.time() >= self.time() => {
                return;
            }
            // Write the time for the validator.
            _ => {
                schema.validators_time_mut().put(
                    self.pub_key(),
                    Time::new(self.time()),
                )
            }
        }

        // Find all known times for the validators.
        let mut validators_time: Vec<SystemTime>;
        {
            let idx = schema.validators_time();
            validators_time = idx.iter()
                .filter_map(|pair| {
                    validator_keys
                        .iter()
                        .find(|validator| validator.service_key == pair.0)
                        .map(|_| pair.1.time())
                })
                .collect();
        }

        // The largest number of Byzantine nodes.
        let max_byzantine_nodes = validator_keys.len() / 3;
        if validators_time.len() <= max_byzantine_nodes {
            return;
        }
        // Ordering time from highest to lowest.
        validators_time.sort_by(|a, b| b.cmp(a));

        match schema.time().get() {
            // Selected time should be longer than the time in the storage.
            Some(ref current_time)
                if current_time.time() >= validators_time[max_byzantine_nodes] => {
                return;
            }
            _ => {
                // Change the time in the storage.
                schema.time_mut().set(Time::new(
                    validators_time[max_byzantine_nodes],
                ));
            }
        }
    }
}

/// Implements the node API.
#[derive(Clone)]
struct TimeApi {
    blockchain: Blockchain,
}

/// Shortcut to get data from storage.
impl TimeApi {
    /// Endpoint for getting value of the time that is saved in storage.
    fn get_current_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let current_time = schema.time().get();
        self.ok_response(&serde_json::to_value(current_time).unwrap())
    }

    /// Endpoint for getting time values for all validators.
    fn get_validators_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let idx = schema.validators_time();
        let validators_time: Vec<Time> = idx.values().collect();
        if validators_time.is_empty() {
            self.not_found_response(&serde_json::to_value("Validators time database if empty")
                .unwrap())
        } else {
            self.ok_response(&serde_json::to_value(validators_time).unwrap())
        }
    }

    fn wire_private(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_validators_time = move |req: &mut Request| self_.get_validators_time(req);
        router.get(
            "/validators_time",
            get_validators_time,
            "get_validators_time",
        );
    }
}

impl Api for TimeApi {
    fn wire(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_current_time = move |req: &mut Request| self_.get_current_time(req);
        router.get("/current_time", get_current_time, "get_current_time");
    }
}

/// A helper trait that provides the node with a current time.
pub trait TimeProvider: Send + Sync + ::std::fmt::Debug {
    /// Returns the current time.
    fn current_time(&self) -> SystemTime;
}

#[derive(Debug)]
struct SystemTimeProvider;

impl TimeProvider for SystemTimeProvider {
    fn current_time(&self) -> SystemTime {
        SystemTime::now()
    }
}

/// Define the service.
#[derive(Debug)]
pub struct TimeService {
    /// Current time.
    time: Box<TimeProvider>,
}

impl Default for TimeService {
    fn default() -> TimeService {
        TimeService { time: Box::new(SystemTimeProvider) as Box<TimeProvider> }
    }
}

impl TimeService {
    /// Create a new `TimeService`.
    pub fn new() -> TimeService {
        TimeService::default()
    }

    /// Create a new `TimeService` with time provider `T`.
    pub fn with_provider<T: Into<Box<TimeProvider>>>(time_provider: T) -> TimeService {
        TimeService { time: time_provider.into() }
    }
}

impl Service for TimeService {
    fn service_name(&self) -> &'static str {
        SERVICE_NAME
    }

    fn service_id(&self) -> u16 {
        SERVICE_ID
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        match raw.message_type() {
            TX_TIME_ID => Ok(Box::new(TxTime::from_raw(raw)?)),
            _ => {
                let error =
                    encoding::Error::IncorrectMessageType { message_type: raw.message_type() };
                Err(error)
            }
        }
    }

    fn initialize(&self, _fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Creates transaction after commit of the block.
    fn handle_commit(&self, context: &ServiceContext) {
        // The transaction must be created by the validator.
        if context.validator_id().is_none() {
            return;
        }
        let (pub_key, sec_key) = (*context.public_key(), context.secret_key().clone());
        context
            .transaction_sender()
            .send(Box::new(
                TxTime::new(self.time.current_time(), &pub_key, &sec_key),
            ))
            .unwrap();
    }

    fn private_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire_private(&mut router);
        Some(Box::new(router))
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

/// A time service creator for the `NodeBuilder`.
#[derive(Debug)]
pub struct TimeServiceFactory;

impl ServiceFactory for TimeServiceFactory {
    fn make_service(&mut self, _: &Context) -> Box<Service> {
        Box::new(TimeService::new())
    }
}
<commit_msg>Returns 'HashMap' from private API.<commit_after>// Copyright 2017 The Exonum Team
//
// 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.

//! The time oracle service for Exonum.

#![deny(missing_debug_implementations, missing_docs)]

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use iron::prelude::*;
use iron::Handler;
use router::Router;

use std::time::SystemTime;
use std::collections::HashMap;

use exonum::blockchain::{Blockchain, Service, ServiceContext, Schema, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::encoding::serialize::json::reexport::Value;
use exonum::storage::{Fork, Snapshot, MapIndex, Entry};
use exonum::crypto::PublicKey;
use exonum::encoding;
use exonum::helpers::fabric::{ServiceFactory, Context};
use exonum::api::Api;

/// Time service id.
const SERVICE_ID: u16 = 4;
/// `TxTime` transaction id.
const TX_TIME_ID: u16 = 1;
/// Time service name.
const SERVICE_NAME: &str = "exonum_time";

encoding_struct! {
    /// Time information.
    struct Time {
        const SIZE = 12;

        /// Field that stores `SystemTime`.
        field time:     SystemTime  [00 => 12]
    }
}

/// `Exonum-time` service database schema.
#[derive(Debug)]
pub struct TimeSchema<T> {
    view: T,
}

impl<T: AsRef<Snapshot>> TimeSchema<T> {
    /// Constructs schema for the given `snapshot`.
    pub fn new(view: T) -> Self {
        TimeSchema { view }
    }

    /// Returns the table that stores `Time` struct for every validator.
    pub fn validators_time(&self) -> MapIndex<&Snapshot, PublicKey, Time> {
        MapIndex::new(
            format!("{}.validators_time", SERVICE_NAME),
            self.view.as_ref(),
        )
    }

    /// Returns stored `Time`.
    pub fn time(&self) -> Entry<&Snapshot, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view.as_ref())
    }
}

impl<'a> TimeSchema<&'a mut Fork> {
    /// Mutable reference to the ['validators_time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.validators_time
    pub fn validators_time_mut(&mut self) -> MapIndex<&mut Fork, PublicKey, Time> {
        MapIndex::new(format!("{}.validators_time", SERVICE_NAME), self.view)
    }

    /// Mutable reference to the ['time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.time
    pub fn time_mut(&mut self) -> Entry<&mut Fork, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view)
    }
}

message! {
    /// Transaction that is sent by the validator after the commit of the block.
    struct TxTime {
        const TYPE = SERVICE_ID;
        const ID = TX_TIME_ID;
        const SIZE = 44;
        /// Validator's time.
        field time:     SystemTime  [00 => 12]
        /// Validator's public key.
        field pub_key:  &PublicKey  [12 => 44]
    }
}

impl Transaction for TxTime {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let validator_keys = Schema::new(&view).actual_configuration().validator_keys;

        // The transaction must be signed by the validator.
        let signed = validator_keys.iter().any(|&validator| {
            validator.service_key == *self.pub_key()
        });
        if !signed {
            return;
        }

        let mut schema = TimeSchema::new(view);
        match schema.validators_time().get(self.pub_key()) {
            // The validator time in the storage should be less than in the transaction.
            Some(ref storage_time) if storage_time.time() >= self.time() => {
                return;
            }
            // Write the time for the validator.
            _ => {
                schema.validators_time_mut().put(
                    self.pub_key(),
                    Time::new(self.time()),
                )
            }
        }

        // Find all known times for the validators.
        let mut validators_time: Vec<SystemTime>;
        {
            let idx = schema.validators_time();
            validators_time = idx.iter()
                .filter_map(|pair| {
                    validator_keys
                        .iter()
                        .find(|validator| validator.service_key == pair.0)
                        .map(|_| pair.1.time())
                })
                .collect();
        }

        // The largest number of Byzantine nodes.
        let max_byzantine_nodes = validator_keys.len() / 3;
        if validators_time.len() <= max_byzantine_nodes {
            return;
        }
        // Ordering time from highest to lowest.
        validators_time.sort_by(|a, b| b.cmp(a));

        match schema.time().get() {
            // Selected time should be longer than the time in the storage.
            Some(ref current_time)
                if current_time.time() >= validators_time[max_byzantine_nodes] => {
                return;
            }
            _ => {
                // Change the time in the storage.
                schema.time_mut().set(Time::new(
                    validators_time[max_byzantine_nodes],
                ));
            }
        }
    }
}

/// Implements the node API.
#[derive(Clone)]
struct TimeApi {
    blockchain: Blockchain,
}

/// Shortcut to get data from storage.
impl TimeApi {
    /// Endpoint for getting value of the time that is saved in storage.
    fn get_current_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let current_time = schema.time().get();
        self.ok_response(&serde_json::to_value(current_time).unwrap())
    }

    /// Endpoint for getting time values for all validators.
    fn get_validators_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let idx = schema.validators_time();

        let validators_time: HashMap<_, _> = idx.iter().collect();

        if validators_time.is_empty() {
            self.not_found_response(&serde_json::to_value("Validators time database is empty")
                .unwrap())
        } else {
            self.ok_response(&serde_json::to_value(validators_time).unwrap())
        }
    }

    fn wire_private(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_validators_time = move |req: &mut Request| self_.get_validators_time(req);
        router.get(
            "/validators_time",
            get_validators_time,
            "get_validators_time",
        );
    }
}

impl Api for TimeApi {
    fn wire(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_current_time = move |req: &mut Request| self_.get_current_time(req);
        router.get("/current_time", get_current_time, "get_current_time");
    }
}

/// A helper trait that provides the node with a current time.
pub trait TimeProvider: Send + Sync + ::std::fmt::Debug {
    /// Returns the current time.
    fn current_time(&self) -> SystemTime;
}

#[derive(Debug)]
struct SystemTimeProvider;

impl TimeProvider for SystemTimeProvider {
    fn current_time(&self) -> SystemTime {
        SystemTime::now()
    }
}

/// Define the service.
#[derive(Debug)]
pub struct TimeService {
    /// Current time.
    time: Box<TimeProvider>,
}

impl Default for TimeService {
    fn default() -> TimeService {
        TimeService { time: Box::new(SystemTimeProvider) as Box<TimeProvider> }
    }
}

impl TimeService {
    /// Create a new `TimeService`.
    pub fn new() -> TimeService {
        TimeService::default()
    }

    /// Create a new `TimeService` with time provider `T`.
    pub fn with_provider<T: Into<Box<TimeProvider>>>(time_provider: T) -> TimeService {
        TimeService { time: time_provider.into() }
    }
}

impl Service for TimeService {
    fn service_name(&self) -> &'static str {
        SERVICE_NAME
    }

    fn service_id(&self) -> u16 {
        SERVICE_ID
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        match raw.message_type() {
            TX_TIME_ID => Ok(Box::new(TxTime::from_raw(raw)?)),
            _ => {
                let error =
                    encoding::Error::IncorrectMessageType { message_type: raw.message_type() };
                Err(error)
            }
        }
    }

    fn initialize(&self, _fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Creates transaction after commit of the block.
    fn handle_commit(&self, context: &ServiceContext) {
        // The transaction must be created by the validator.
        if context.validator_id().is_none() {
            return;
        }
        let (pub_key, sec_key) = (*context.public_key(), context.secret_key().clone());
        context
            .transaction_sender()
            .send(Box::new(
                TxTime::new(self.time.current_time(), &pub_key, &sec_key),
            ))
            .unwrap();
    }

    fn private_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire_private(&mut router);
        Some(Box::new(router))
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

/// A time service creator for the `NodeBuilder`.
#[derive(Debug)]
pub struct TimeServiceFactory;

impl ServiceFactory for TimeServiceFactory {
    fn make_service(&mut self, _: &Context) -> Box<Service> {
        Box::new(TimeService::new())
    }
}
<|endoftext|>


<commit_before>extern crate semver;
extern crate conduit;

use std::collections::HashMap;
use std::io::prelude::*;
use std::io::Cursor;
use std::net::{SocketAddr, Ipv4Addr, SocketAddrV4};

use semver::Version;
use conduit::{Method, Scheme, Host, Extensions, Headers, TypeMap};

pub struct MockRequest {
    path: String,
    method: Method,
    query_string: Option<String>,
    body: Option<Vec<u8>>,
    build_headers: HashMap<String, String>,
    headers: MockHeaders,
    extensions: TypeMap,
    reader: Option<Cursor<Vec<u8>>>
}

impl MockRequest {
    pub fn new(method: Method, path: &str) -> MockRequest {
        let headers = HashMap::new();

        MockRequest {
            path: path.to_string(),
            extensions: TypeMap::new(),
            query_string: None,
            body: None,
            build_headers: headers,
            headers: MockHeaders { headers: HashMap::new() },
            method: method,
            reader: None
        }
    }

    pub fn with_method(&mut self, method: Method) -> &mut MockRequest {
        self.method = method;
        self
    }

    pub fn with_path(&mut self, path: &str) -> &mut MockRequest {
        self.path = path.to_string();
        self
    }

    pub fn with_query(&mut self, string: &str) -> &mut MockRequest {
        self.query_string = Some(string.to_string());
        self
    }

    pub fn with_body(&mut self, bytes: &[u8]) -> &mut MockRequest {
        self.body = Some(bytes.to_vec());
        self.reader = None;
        self
    }

    pub fn header(&mut self, name: &str, value: &str) -> &mut MockRequest {
        self.build_headers.insert(name.to_string(), value.to_string());
        let headers = MockHeaders { headers: self.build_headers.clone() };
        self.headers = headers;

        self
    }
}

pub struct MockHeaders {
    headers: HashMap<String, String>
}

impl Headers for MockHeaders {
    fn find(&self, key: &str) -> Option<Vec<&str>> {
        self.headers.get(key).map(|v| vec![&v[..]])
    }

    fn has(&self, key: &str) -> bool {
        self.headers.contains_key(key)
    }

    fn all(&self) -> Vec<(&str, Vec<&str>)> {
        self.headers.iter().map(|(k,v)| (&k[..], vec![&v[..]]))
                    .collect()
    }
}

impl conduit::Request for MockRequest {
    fn http_version(&self) -> Version {
        Version::parse("1.1.0").unwrap()
    }

    fn conduit_version(&self) -> Version {
        Version::parse("0.1.0").unwrap()
    }

    fn method(&self) -> Method { self.method.clone() }
    fn scheme(&self) -> Scheme { Scheme::Http }
    fn host(&self) -> Host { Host::Name("example.com") }
    fn virtual_root(&self) -> Option<&str> { None }

    fn path(&self) -> &str {
        &self.path
    }

    fn query_string(&self) -> Option<&str> {
        self.query_string.as_ref().map(|s| &s[..])
    }

    fn remote_addr(&self) -> SocketAddr {
        SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 80))
    }

    fn content_length(&self) -> Option<u64> {
        self.body.as_ref().map(|b| b.len() as u64)
    }

    fn headers(&self) -> &Headers {
        &self.headers as &Headers
    }

    fn body(&mut self) -> &mut Read {
        if self.reader.is_none() {
            let body = self.body.clone().unwrap_or(Vec::new());
            self.reader = Some(Cursor::new(body));
        }
        self.reader.as_mut().unwrap()
    }

    fn extensions(&self) -> &Extensions {
        &self.extensions
    }
    fn mut_extensions(&mut self) -> &mut Extensions {
        &mut self.extensions
    }
}

#[cfg(test)]
mod tests {
    use super::MockRequest;
    use semver::Version;

    use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};

    use conduit::{Request, Method, Host, Scheme};

    #[test]
    fn simple_request_test() {
        let mut req = MockRequest::new(Method::Get, "/");

        assert_eq!(req.http_version(), Version::parse("1.1.0").unwrap());
        assert_eq!(req.conduit_version(), Version::parse("0.1.0").unwrap());
        assert_eq!(req.method(), Method::Get);
        assert_eq!(req.scheme(), Scheme::Http);
        assert_eq!(req.host(), Host::Name("example.com"));
        assert_eq!(req.virtual_root(), None);
        assert_eq!(req.path(), "/");
        assert_eq!(req.query_string(), None);
        assert_eq!(req.remote_addr(),
                   SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1),
                                                    80)));
        assert_eq!(req.content_length(), None);
        assert_eq!(req.headers().all().len(), 0);
        let mut s = String::new();
        req.body().read_to_string(&mut s).ok().expect("No body");
        assert_eq!(s, "".to_string());
    }

    #[test]
    fn request_body_test() {
        let mut req = MockRequest::new(Method::Post, "/articles");
        req.with_body(b"Hello world");

        assert_eq!(req.method(), Method::Post);
        assert_eq!(req.path(), "/articles");
        let mut s = String::new();
        req.body().read_to_string(&mut s).ok().expect("No body");
        assert_eq!(s, "Hello world".to_string());
        assert_eq!(req.content_length(), Some(11));
    }

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

        assert_eq!(req.query_string().expect("No query string"), "foo=bar");
    }

    #[test]
    fn request_headers() {
        let mut req = MockRequest::new(Method::Post, "/articles");
        req.header("User-Agent", "lulz");
        req.header("DNT", "1");

        assert_eq!(req.headers().all().len(), 2);
        assert_eq!(req.headers().find("User-Agent").unwrap(), vec!("lulz"));
        assert_eq!(req.headers().find("DNT").unwrap(), vec!("1"));
    }
}
<commit_msg>Add dyn keyword to address warnings<commit_after>extern crate semver;
extern crate conduit;

use std::collections::HashMap;
use std::io::prelude::*;
use std::io::Cursor;
use std::net::{SocketAddr, Ipv4Addr, SocketAddrV4};

use semver::Version;
use conduit::{Method, Scheme, Host, Extensions, Headers, TypeMap};

pub struct MockRequest {
    path: String,
    method: Method,
    query_string: Option<String>,
    body: Option<Vec<u8>>,
    build_headers: HashMap<String, String>,
    headers: MockHeaders,
    extensions: TypeMap,
    reader: Option<Cursor<Vec<u8>>>
}

impl MockRequest {
    pub fn new(method: Method, path: &str) -> MockRequest {
        let headers = HashMap::new();

        MockRequest {
            path: path.to_string(),
            extensions: TypeMap::new(),
            query_string: None,
            body: None,
            build_headers: headers,
            headers: MockHeaders { headers: HashMap::new() },
            method: method,
            reader: None
        }
    }

    pub fn with_method(&mut self, method: Method) -> &mut MockRequest {
        self.method = method;
        self
    }

    pub fn with_path(&mut self, path: &str) -> &mut MockRequest {
        self.path = path.to_string();
        self
    }

    pub fn with_query(&mut self, string: &str) -> &mut MockRequest {
        self.query_string = Some(string.to_string());
        self
    }

    pub fn with_body(&mut self, bytes: &[u8]) -> &mut MockRequest {
        self.body = Some(bytes.to_vec());
        self.reader = None;
        self
    }

    pub fn header(&mut self, name: &str, value: &str) -> &mut MockRequest {
        self.build_headers.insert(name.to_string(), value.to_string());
        let headers = MockHeaders { headers: self.build_headers.clone() };
        self.headers = headers;

        self
    }
}

pub struct MockHeaders {
    headers: HashMap<String, String>
}

impl Headers for MockHeaders {
    fn find(&self, key: &str) -> Option<Vec<&str>> {
        self.headers.get(key).map(|v| vec![&v[..]])
    }

    fn has(&self, key: &str) -> bool {
        self.headers.contains_key(key)
    }

    fn all(&self) -> Vec<(&str, Vec<&str>)> {
        self.headers.iter().map(|(k,v)| (&k[..], vec![&v[..]]))
                    .collect()
    }
}

impl conduit::Request for MockRequest {
    fn http_version(&self) -> Version {
        Version::parse("1.1.0").unwrap()
    }

    fn conduit_version(&self) -> Version {
        Version::parse("0.1.0").unwrap()
    }

    fn method(&self) -> Method { self.method.clone() }
    fn scheme(&self) -> Scheme { Scheme::Http }
    fn host(&self) -> Host { Host::Name("example.com") }
    fn virtual_root(&self) -> Option<&str> { None }

    fn path(&self) -> &str {
        &self.path
    }

    fn query_string(&self) -> Option<&str> {
        self.query_string.as_ref().map(|s| &s[..])
    }

    fn remote_addr(&self) -> SocketAddr {
        SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 80))
    }

    fn content_length(&self) -> Option<u64> {
        self.body.as_ref().map(|b| b.len() as u64)
    }

    fn headers(&self) -> &dyn Headers {
        &self.headers as &dyn Headers
    }

    fn body(&mut self) -> &mut dyn Read {
        if self.reader.is_none() {
            let body = self.body.clone().unwrap_or(Vec::new());
            self.reader = Some(Cursor::new(body));
        }
        self.reader.as_mut().unwrap()
    }

    fn extensions(&self) -> &Extensions {
        &self.extensions
    }
    fn mut_extensions(&mut self) -> &mut Extensions {
        &mut self.extensions
    }
}

#[cfg(test)]
mod tests {
    use super::MockRequest;
    use semver::Version;

    use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};

    use conduit::{Request, Method, Host, Scheme};

    #[test]
    fn simple_request_test() {
        let mut req = MockRequest::new(Method::Get, "/");

        assert_eq!(req.http_version(), Version::parse("1.1.0").unwrap());
        assert_eq!(req.conduit_version(), Version::parse("0.1.0").unwrap());
        assert_eq!(req.method(), Method::Get);
        assert_eq!(req.scheme(), Scheme::Http);
        assert_eq!(req.host(), Host::Name("example.com"));
        assert_eq!(req.virtual_root(), None);
        assert_eq!(req.path(), "/");
        assert_eq!(req.query_string(), None);
        assert_eq!(req.remote_addr(),
                   SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1),
                                                    80)));
        assert_eq!(req.content_length(), None);
        assert_eq!(req.headers().all().len(), 0);
        let mut s = String::new();
        req.body().read_to_string(&mut s).ok().expect("No body");
        assert_eq!(s, "".to_string());
    }

    #[test]
    fn request_body_test() {
        let mut req = MockRequest::new(Method::Post, "/articles");
        req.with_body(b"Hello world");

        assert_eq!(req.method(), Method::Post);
        assert_eq!(req.path(), "/articles");
        let mut s = String::new();
        req.body().read_to_string(&mut s).ok().expect("No body");
        assert_eq!(s, "Hello world".to_string());
        assert_eq!(req.content_length(), Some(11));
    }

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

        assert_eq!(req.query_string().expect("No query string"), "foo=bar");
    }

    #[test]
    fn request_headers() {
        let mut req = MockRequest::new(Method::Post, "/articles");
        req.header("User-Agent", "lulz");
        req.header("DNT", "1");

        assert_eq!(req.headers().all().len(), 2);
        assert_eq!(req.headers().find("User-Agent").unwrap(), vec!("lulz"));
        assert_eq!(req.headers().find("DNT").unwrap(), vec!("1"));
    }
}
<|endoftext|>