<commit_before>use libc::{uint64_t, int64_t, c_void, c_char, c_double};
use std::ffi::CString;
use std::ptr;
use energymon_sys::energymon::EnergyMon;

#[link(name = "hbt-acc-pow")]
extern {
    fn heartbeat_acc_pow_init(parent: *mut c_void,
                              window_size: uint64_t,
                              buffer_depth: uint64_t,
                              log_name: *const c_char,
                              num_energy_impls: uint64_t,
                              energy_impls: *mut EnergyMon) -> *mut c_void;

    fn heartbeat_acc(hb: *mut c_void,
                     user_tag: uint64_t,
                     work: uint64_t,
                     accuracy: c_double,
                     hb_prev: *mut c_void) -> int64_t;

    fn heartbeat_finish(hb: *mut c_void);

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

    fn hb_get_window_rate(hb: *const c_void) -> c_double;

    fn hb_get_window_power(hb: *const c_void) -> c_double;
}

/// A `Heartbeat` is used for tracking performance/accuracy/power of recurring jobs.
pub struct Heartbeat {
    /// The underlying C struct `heartbeat_t`.
    pub hb: *mut c_void,
}

impl Heartbeat {
    /// Allocate and initialize a new `Heartbeat` with its underlying C struct.
    pub fn new(parent: Option<&mut Heartbeat>,
               window_size: u64,
               buffer_depth: u64,
               log_name: Option<&CString>,
               energy_impl: Option<&mut EnergyMon>) -> Result<Heartbeat, &'static str> {
        let parent = match parent {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        let log_ptr = match log_name {
          Some(n) => n.as_ptr(),
          None => ptr::null(),
        };
        let num_energy_impls: u64;
        let mut em: *mut EnergyMon;
        if energy_impl.is_some() {
            num_energy_impls = 1;
            em = energy_impl.unwrap();
        } else {
            num_energy_impls = 0;
            em = ptr::null_mut();
        }
        let heart = unsafe {
            heartbeat_acc_pow_init(parent, window_size, buffer_depth, log_ptr,
                                   num_energy_impls, em)
        };
        if heart.is_null() {
            return Err("Failed to initialize heartbeat");
        }
        Ok(Heartbeat { hb: heart, })
    }

    /// Issue a heartbeat.
    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     accuracy: f64,
                     hb_prev: Option<&Heartbeat>) -> i64 {
        let hb_prev = match hb_prev {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        unsafe {
            heartbeat_acc(self.hb, tag, work, accuracy, hb_prev)
        }
    }

    /// Utility function to get the most recent user-specified tag
    pub fn get_tag(&mut self) -> u64 {
        unsafe {
            hb_get_user_tag(self.hb)
        }
    }

    /// Utility function to get the current window performance.
    pub fn get_window_perf(&mut self) -> f64 {
        unsafe {
            hb_get_window_rate(self.hb)
        }
    }

    /// Utility function to get the current window power.
    pub fn get_window_pwr(&mut self) -> f64 {
        unsafe {
            hb_get_window_power(self.hb)
        }
    }
}

impl Drop for Heartbeat {
    /// Cleans up and deallocates the underlying C struct.
    fn drop(&mut self) {
        unsafe {
            heartbeat_finish(self.hb);
        }
    }
}

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

    #[test]
    fn test_no_energymon() {
        let mut hb = Heartbeat::new(None, 20, 20, None, None).unwrap();
        hb.heartbeat(0, 1, 0.0, None);
    }
}
<commit_msg>A little cleaner. Declare all variable types<commit_after>use libc::{uint64_t, int64_t, c_void, c_char, c_double};
use std::ffi::CString;
use std::ptr;
use energymon_sys::energymon::EnergyMon;

#[link(name = "hbt-acc-pow")]
extern {
    fn heartbeat_acc_pow_init(parent: *mut c_void,
                              window_size: uint64_t,
                              buffer_depth: uint64_t,
                              log_name: *const c_char,
                              num_energy_impls: uint64_t,
                              energy_impls: *mut EnergyMon) -> *mut c_void;

    fn heartbeat_acc(hb: *mut c_void,
                     user_tag: uint64_t,
                     work: uint64_t,
                     accuracy: c_double,
                     hb_prev: *mut c_void) -> int64_t;

    fn heartbeat_finish(hb: *mut c_void);

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

    fn hb_get_window_rate(hb: *const c_void) -> c_double;

    fn hb_get_window_power(hb: *const c_void) -> c_double;
}

/// A `Heartbeat` is used for tracking performance/accuracy/power of recurring jobs.
pub struct Heartbeat {
    /// The underlying C struct `heartbeat_t`.
    pub hb: *mut c_void,
}

impl Heartbeat {
    /// Allocate and initialize a new `Heartbeat` with its underlying C struct.
    pub fn new(parent: Option<&mut Heartbeat>,
               window_size: u64,
               buffer_depth: u64,
               log_name: Option<&CString>,
               energy_impl: Option<&mut EnergyMon>) -> Result<Heartbeat, &'static str> {
        let parent_ptr: *mut c_void = match parent {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        let log_ptr: *const c_char = match log_name {
          Some(n) => n.as_ptr(),
          None => ptr::null(),
        };
        let (num_em, em_ptr): (u64, *mut EnergyMon) = match energy_impl {
          Some(e) => (1, e),
          None => (0, ptr::null_mut()),
        };
        let heart: *mut c_void = unsafe {
            heartbeat_acc_pow_init(parent_ptr, window_size, buffer_depth, log_ptr, num_em, em_ptr)
        };
        if heart.is_null() {
            return Err("Failed to initialize heartbeat");
        }
        Ok(Heartbeat { hb: heart, })
    }

    /// Issue a heartbeat.
    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     accuracy: f64,
                     hb_prev: Option<&Heartbeat>) -> i64 {
        let hb_prev: *mut c_void = match hb_prev {
            Some(p) => p.hb,
            None => ptr::null_mut(),
        };
        unsafe {
            heartbeat_acc(self.hb, tag, work, accuracy, hb_prev)
        }
    }

    /// Utility function to get the most recent user-specified tag
    pub fn get_tag(&mut self) -> u64 {
        unsafe {
            hb_get_user_tag(self.hb)
        }
    }

    /// Utility function to get the current window performance.
    pub fn get_window_perf(&mut self) -> f64 {
        unsafe {
            hb_get_window_rate(self.hb)
        }
    }

    /// Utility function to get the current window power.
    pub fn get_window_pwr(&mut self) -> f64 {
        unsafe {
            hb_get_window_power(self.hb)
        }
    }
}

impl Drop for Heartbeat {
    /// Cleans up and deallocates the underlying C struct.
    fn drop(&mut self) {
        unsafe {
            heartbeat_finish(self.hb);
        }
    }
}

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

    #[test]
    fn test_no_energymon() {
        let mut hb = Heartbeat::new(None, 20, 20, None, None).unwrap();
        hb.heartbeat(1, 1, 1.0, None);
        assert!(hb.get_tag() == 1);
        // can't really test performance and power accurately
    }
}
<|endoftext|>


<commit_before>use std::io::{BufReader,IoResult,Reader};

pub enum Body<'a> {
    FixedBody(BufReader<'a>, uint),
    ChunkedBody(&'a mut Reader)
}

impl<'a> Body<'a> {
    pub fn get_size(&self) -> Option<uint> {
        match self {
            &FixedBody(_, len) => Some(len),
            _ => None
        }
    }

    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        match self {
            &FixedBody(ref mut r,_) => r.read(buf),
            &ChunkedBody(ref mut r) => r.read(buf)
        }
    }
}

pub trait ToBody<'a> {
    fn to_body(self) -> Body<'a>;
}

impl<'a> ToBody<'a> for &'a str {
    fn to_body(self) -> Body<'a> {
        self.as_bytes().to_body()
    }
}

impl<'a> ToBody<'a> for &'a [u8] {
    fn to_body(self) -> Body<'a> {
        FixedBody(BufReader::new(self), self.len())
    }
}

impl<'a> ToBody<'a> for &'a String {
    fn to_body(self) -> Body<'a> {
        self.as_slice().to_body()
    }
}

// TODO: https://github.com/rust-lang/rust/issues/14901
impl<'a> ToBody<'a> for &'a mut Reader {
    fn to_body(self) -> Body<'a> {
        ChunkedBody(self)
    }
}
<commit_msg>Update to Rust master<commit_after>use std::io::{BufReader,IoResult,Reader};

pub enum Body<'a> {
    FixedBody(BufReader<'a>, uint),
    ChunkedBody(&'a mut Reader + Send)
}

impl<'a> Body<'a> {
    pub fn get_size(&self) -> Option<uint> {
        match self {
            &FixedBody(_, len) => Some(len),
            _ => None
        }
    }

    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        match self {
            &FixedBody(ref mut r,_) => r.read(buf),
            &ChunkedBody(ref mut r) => r.read(buf)
        }
    }
}

pub trait ToBody<'a> {
    fn to_body(self) -> Body<'a>;
}

impl<'a> ToBody<'a> for &'a str {
    fn to_body(self) -> Body<'a> {
        self.as_bytes().to_body()
    }
}

impl<'a> ToBody<'a> for &'a [u8] {
    fn to_body(self) -> Body<'a> {
        FixedBody(BufReader::new(self), self.len())
    }
}

impl<'a> ToBody<'a> for &'a String {
    fn to_body(self) -> Body<'a> {
        self.as_slice().to_body()
    }
}

// TODO: https://github.com/rust-lang/rust/issues/14901
impl<'a> ToBody<'a> for &'a mut Reader + Send {
    fn to_body(self) -> Body<'a> {
        ChunkedBody(self)
    }
}
<|endoftext|>


<commit_before>extern crate itertools;
extern crate rand;
extern crate rayon;

use self::itertools::Itertools;

use self::rand::Rng;

use super::train;
use super::train::Train;
use super::error::Error;
use super::common::{Node, Value};
use super::mutator::{Arc, Mutator};
use super::network::NetworkBuf;
use super::id_generator::IdGenerator;

pub struct Conf<'r, RngT: 'r + Rng> {
    pub train_conf: &'r train::Conf<'r>,
    pub rng: &'r mut RngT,
    pub node_id: &'r mut IdGenerator,
    pub population_size: usize,
    pub error: Value,
    pub iterations_count: usize,
}

pub trait Evolve {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self;
}

impl Evolve for NetworkBuf {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Mutator::from_network(&self.as_network()).evolve(conf).as_network_buf()
    }
}

impl Evolve for Mutator {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Evolution::new(conf, self).perform()
    }
}

trait MutatorRandom {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node;
    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc;
}

impl MutatorRandom for Mutator {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node {
        let nth = rng.gen_range(0, self.nodes().len());
        *self.nodes().nth(nth).unwrap()
    }

    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc {
        let nth = rng.gen_range(0, self.arcs().len());
        self.arcs().nth(nth).unwrap().clone()
    }
}

struct Evolution<'c, 'f, RngT: 'c + Rng> {
    conf: &'c mut Conf<'c, RngT>,
    mutator: &'f Mutator,
    iterations_count: usize,
}

impl<'c, 'f, RngT: 'c + Rng> Evolution<'c, 'f, RngT> {
    pub fn new(conf: &'c mut Conf<'c, RngT>, mutator: &'f Mutator) -> Self {
        assert!(conf.population_size > 1);
        assert!(conf.population_size % 2 == 0);
        Evolution {conf: conf, mutator: mutator, iterations_count: 0}
    }

    pub fn perform(&mut self) -> Mutator {
        if !self.begin() {
            return self.mutator.clone();
        }
        let population = (0..self.conf.population_size)
            .map(|_| self.mutator.clone()).collect::<Vec<_>>();
        let evolved = self.evolve(population);
        self.select_one(evolved)
    }

    fn evolve(&mut self, mut population: Vec<Mutator>) -> Vec<Mutator> {
        loop {
            let mutated = self.mutate(population);
            self.iterations_count += 1;
            if self.terminate(&mutated[..]) {
                return mutated;
            }
            let propagated = self.propagate(mutated);
            population = self.select(propagated);
        }
    }

    fn mutate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        use self::rayon::prelude::{IntoParallelIterator, ParallelIterator, ExactParallelIterator};
        let ref mut node_id = self.conf.node_id;
        let ref mut rng = self.conf.rng;
        let ref train_conf = self.conf.train_conf;
        let mut result = Vec::new();
        population.into_iter()
            .map(|mut x| {
                for _ in 0..3 {
                    match rng.gen_range(0, 3) {
                        0 => {
                            let arc = x.random_arc(rng);
                            x.split(node_id, &arc);
                        },
                        1 => loop {
                            let src = x.random_node(rng);
                            let dst = x.random_node(rng);
                            if !x.graph().arcs().contains_key(&Arc(src, dst)) {
                                x.add_arc(src, dst, 1e-3);
                                break;
                            }
                        },
                        2 => {
                            let arc = x.random_arc(rng);
                            x.rm_arc(&arc);
                            x.rm_useless();
                        },
                        _ => (),
                    }
                }
                x
            })
            .collect::<Vec<_>>()
            .into_par_iter()
            .map(|x| {
                let mut network_buf = x.as_network_buf();
                network_buf.as_network_mut().train(train_conf);
                Mutator::from_network(&network_buf.as_network())
            })
            .collect_into(&mut result);
        result
    }

    fn begin(&self) -> bool {
        self.iterations_count < self.conf.iterations_count
        && self.mutator.as_network_buf().as_network().error(self.conf.train_conf.error_conf)
           > self.conf.error
    }

    fn terminate(&self, population: &[Mutator]) -> bool {
        use std::io::{Write, stderr};
        write!(&mut stderr(), "Evolve {}/{} iterations done\n",
               self.iterations_count, self.conf.iterations_count).unwrap();
        self.iterations_count >= self.conf.iterations_count
        || population.iter()
            .map(|x| x.as_network_buf().as_network().error(self.conf.train_conf.error_conf))
            .filter(|&x| x <= self.conf.error)
            .count() > 0
    }

    fn propagate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let mut new = {
            let mut a = population.iter().collect::<Vec<_>>();
            let mut b = population.iter().collect::<Vec<_>>();
            self.conf.rng.shuffle(&mut a[..]);
            self.conf.rng.shuffle(&mut b[..]);
            a.iter().zip(b.iter()).map(|(l, r)| l.union(r)).collect::<Vec<_>>()
        };
        new.extend(population.into_iter());
        new
    }

    fn select(&self, population: Vec<Mutator>) -> Vec<Mutator> {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .take(self.conf.population_size)
            .map(|x| x.1)
            .collect()
    }

    fn select_one(&self, population: Vec<Mutator>) -> Mutator {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .nth(0)
            .unwrap().1
    }
}

#[test]
fn test_evolve_should_succeed() {
    extern crate rand;
    use std::collections::{BTreeSet, HashMap, HashSet};
    use self::rand::{XorShiftRng, SeedableRng};
    use neural_network::apply::{Conf as ApplyConf};
    use neural_network::error::{Conf as ErrorConf, Sample};
    use neural_network::train::{Conf as TrainConf};
    use neural_network::matrix::Matrix;
    use neural_network::network::Network;
    let mut weights_values = [
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0, 0.0,
    ];
    let inputs = [0, 1, 2].iter().cloned().collect::<BTreeSet<usize>>();
    let outputs = [3, 4].iter().cloned().collect::<HashSet<usize>>();
    let weights = Matrix::new(5, &mut weights_values);
    let nodes = (0..5).map(|x| (x, Node(x))).collect::<HashMap<usize, Node>>();
    let network = Network {
        inputs: &inputs,
        outputs: &outputs,
        weights: weights,
        nodes: &nodes
    };
    let mutator = Mutator::from_network(&network);
    let apply_conf = ApplyConf {
        group_size: 1000,
        threshold: 1e-4,
    };
    let samples = [
        Sample {input: &[0.6, 0.7, 0.8], output: &[0.5, 0.4]},
        Sample {input: &[0.3, 0.4, 0.5], output: &[0.3, 0.4]},
    ];
    let error_conf = ErrorConf {
        apply_conf: &apply_conf,
        samples: &samples,
    };
    let train_conf = TrainConf {
        error_conf: &error_conf,
        max_function_calls_count: 111,
    };
    let mut rng = XorShiftRng::new_unseeded();
    rng.reseed([1, 1, 1, 1]);
    let mut node_id = IdGenerator::new(0);
    let mut conf = Conf {
        train_conf: &train_conf,
        rng: &mut rng,
        node_id: &mut node_id,
        population_size: 2,
        error: 1e-3,
        iterations_count: 2,
    };
    let evolved = mutator.evolve(&mut conf);
    let evolved_network_buf = evolved.as_network_buf();
    let evolved_network = evolved_network_buf.as_network();
    let result: &[f64] = evolved_network.weights.values();
    assert_eq!(result, &[
        0.0, 0.0, 0.0, 0.2683965623209851  , 0.17777079087862993   , 0.3539603853353258, 0.0,
        0.0, 0.0, 0.0, 0.0                 , 0.6691012007499241    , 0.0               , 0.5829220793286896,
        0.0, 0.0, 0.0, 0.47249060773832235 , 0.3731956371044444    , 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.010525576601664234, 0.00012966522945039157, 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.0                 , 0.02282920151502366   , 0.0               , 0.027966325746754388,
        0.0, 0.0, 0.0, 0.0                 , 0.3304639663408785    , 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.5829220793286896  , 0.0                   , 0.0               , 0.0,
    ] as &[f64]);
}
<commit_msg>More tests<commit_after>extern crate itertools;
extern crate rand;
extern crate rayon;

use self::itertools::Itertools;

use self::rand::Rng;

use super::train;
use super::train::Train;
use super::error::Error;
use super::common::{Node, Value};
use super::mutator::{Arc, Mutator};
use super::network::NetworkBuf;
use super::id_generator::IdGenerator;

pub struct Conf<'r, RngT: 'r + Rng> {
    pub train_conf: &'r train::Conf<'r>,
    pub rng: &'r mut RngT,
    pub node_id: &'r mut IdGenerator,
    pub population_size: usize,
    pub error: Value,
    pub iterations_count: usize,
}

pub trait Evolve {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self;
}

impl Evolve for NetworkBuf {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Mutator::from_network(&self.as_network()).evolve(conf).as_network_buf()
    }
}

impl Evolve for Mutator {
    fn evolve<'r, RngT: 'r + Rng>(&self, conf: &'r mut Conf<'r, RngT>) -> Self {
        Evolution::new(conf, self).perform()
    }
}

trait MutatorRandom {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node;
    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc;
}

impl MutatorRandom for Mutator {
    fn random_node<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Node {
        let nth = rng.gen_range(0, self.nodes().len());
        *self.nodes().nth(nth).unwrap()
    }

    fn random_arc<'r, RngT: 'r + Rng>(&self, rng: &mut RngT) -> Arc {
        let nth = rng.gen_range(0, self.arcs().len());
        self.arcs().nth(nth).unwrap().clone()
    }
}

struct Evolution<'c, 'f, RngT: 'c + Rng> {
    conf: &'c mut Conf<'c, RngT>,
    mutator: &'f Mutator,
    iterations_count: usize,
}

impl<'c, 'f, RngT: 'c + Rng> Evolution<'c, 'f, RngT> {
    pub fn new(conf: &'c mut Conf<'c, RngT>, mutator: &'f Mutator) -> Self {
        assert!(conf.population_size > 1);
        assert!(conf.population_size % 2 == 0);
        Evolution {conf: conf, mutator: mutator, iterations_count: 0}
    }

    pub fn perform(&mut self) -> Mutator {
        if !self.begin() {
            return self.mutator.clone();
        }
        let population = (0..self.conf.population_size)
            .map(|_| self.mutator.clone()).collect::<Vec<_>>();
        let evolved = self.evolve(population);
        self.select_one(evolved)
    }

    fn evolve(&mut self, mut population: Vec<Mutator>) -> Vec<Mutator> {
        loop {
            let mutated = self.mutate(population);
            self.iterations_count += 1;
            if self.terminate(&mutated[..]) {
                return mutated;
            }
            let propagated = self.propagate(mutated);
            population = self.select(propagated);
        }
    }

    fn mutate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        use self::rayon::prelude::{IntoParallelIterator, ParallelIterator, ExactParallelIterator};
        let ref mut node_id = self.conf.node_id;
        let ref mut rng = self.conf.rng;
        let ref train_conf = self.conf.train_conf;
        let mut result = Vec::new();
        population.into_iter()
            .map(|mut x| {
                for _ in 0..3 {
                    match rng.gen_range(0, 3) {
                        0 => {
                            let arc = x.random_arc(rng);
                            x.split(node_id, &arc);
                        },
                        1 => loop {
                            let src = x.random_node(rng);
                            let dst = x.random_node(rng);
                            if !x.graph().arcs().contains_key(&Arc(src, dst)) {
                                x.add_arc(src, dst, 1e-3);
                                break;
                            }
                        },
                        2 => {
                            let arc = x.random_arc(rng);
                            x.rm_arc(&arc);
                            x.rm_useless();
                        },
                        _ => (),
                    }
                }
                x
            })
            .collect::<Vec<_>>()
            .into_par_iter()
            .map(|x| {
                let mut network_buf = x.as_network_buf();
                network_buf.as_network_mut().train(train_conf);
                Mutator::from_network(&network_buf.as_network())
            })
            .collect_into(&mut result);
        result
    }

    fn begin(&self) -> bool {
        self.iterations_count < self.conf.iterations_count
        && self.mutator.as_network_buf().as_network().error(self.conf.train_conf.error_conf)
           > self.conf.error
    }

    fn terminate(&self, population: &[Mutator]) -> bool {
        use std::io::{Write, stderr};
        write!(&mut stderr(), "Evolve {}/{} iterations done\n",
               self.iterations_count, self.conf.iterations_count).unwrap();
        self.iterations_count >= self.conf.iterations_count
        || population.iter()
            .map(|x| x.as_network_buf().as_network().error(self.conf.train_conf.error_conf))
            .filter(|&x| x <= self.conf.error)
            .count() > 0
    }

    fn propagate(&mut self, population: Vec<Mutator>) -> Vec<Mutator> {
        let mut new = {
            let mut a = population.iter().collect::<Vec<_>>();
            let mut b = population.iter().collect::<Vec<_>>();
            self.conf.rng.shuffle(&mut a[..]);
            self.conf.rng.shuffle(&mut b[..]);
            a.iter().zip(b.iter()).map(|(l, r)| l.union(r)).collect::<Vec<_>>()
        };
        new.extend(population.into_iter());
        new
    }

    fn select(&self, population: Vec<Mutator>) -> Vec<Mutator> {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .take(self.conf.population_size)
            .map(|x| x.1)
            .collect()
    }

    fn select_one(&self, population: Vec<Mutator>) -> Mutator {
        population.into_iter()
            .map(|x| (x.as_network_buf().as_network().error(self.conf.train_conf.error_conf), x))
            .sorted_by(|l, r| l.0.partial_cmp(&r.0).unwrap())
            .into_iter()
            .nth(0)
            .unwrap().1
    }
}

#[test]
fn test_evolve_should_succeed() {
    extern crate rand;
    use std::collections::{BTreeSet, HashMap, HashSet};
    use self::rand::{XorShiftRng, SeedableRng};
    use neural_network::apply::{Conf as ApplyConf};
    use neural_network::error::{Conf as ErrorConf, Sample};
    use neural_network::train::{Conf as TrainConf};
    use neural_network::matrix::Matrix;
    use neural_network::network::Network;
    let mut weights_values = [
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0, 0.0,
    ];
    let inputs = [0, 1, 2].iter().cloned().collect::<BTreeSet<usize>>();
    let outputs = [3, 4].iter().cloned().collect::<HashSet<usize>>();
    let weights = Matrix::new(5, &mut weights_values);
    let nodes = (0..5).map(|x| (x, Node(x))).collect::<HashMap<usize, Node>>();
    let network = Network {
        inputs: &inputs,
        outputs: &outputs,
        weights: weights,
        nodes: &nodes
    };
    let mutator = Mutator::from_network(&network);
    let apply_conf = ApplyConf {
        group_size: 1000,
        threshold: 1e-4,
    };
    let samples = [
        Sample {input: &[0.6, 0.7, 0.8], output: &[0.5, 0.4]},
        Sample {input: &[0.3, 0.4, 0.5], output: &[0.3, 0.4]},
    ];
    let error_conf = ErrorConf {
        apply_conf: &apply_conf,
        samples: &samples,
    };
    let train_conf = TrainConf {
        error_conf: &error_conf,
        max_function_calls_count: 111,
    };
    let mut rng = XorShiftRng::new_unseeded();
    rng.reseed([1, 1, 1, 1]);
    let mut node_id = IdGenerator::new(0);
    let mut conf = Conf {
        train_conf: &train_conf,
        rng: &mut rng,
        node_id: &mut node_id,
        population_size: 2,
        error: 1e-3,
        iterations_count: 2,
    };
    let evolved = mutator.evolve(&mut conf);
    let evolved_network_buf = evolved.as_network_buf();
    let evolved_network = evolved_network_buf.as_network();
    let result: &[f64] = evolved_network.weights.values();
    assert_eq!(result, &[
        0.0, 0.0, 0.0, 0.2683965623209851  , 0.17777079087862993   , 0.3539603853353258, 0.0,
        0.0, 0.0, 0.0, 0.0                 , 0.6691012007499241    , 0.0               , 0.5829220793286896,
        0.0, 0.0, 0.0, 0.47249060773832235 , 0.3731956371044444    , 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.010525576601664234, 0.00012966522945039157, 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.0                 , 0.02282920151502366   , 0.0               , 0.027966325746754388,
        0.0, 0.0, 0.0, 0.0                 , 0.3304639663408785    , 0.0               , 0.0,
        0.0, 0.0, 0.0, 0.5829220793286896  , 0.0                   , 0.0               , 0.0,
    ] as &[f64]);
}

#[test]
fn test_evolve_zero_iterations_should_do_nothing() {
    extern crate rand;
    use std::collections::{BTreeSet, HashMap, HashSet};
    use self::rand::{XorShiftRng, SeedableRng};
    use neural_network::apply::{Conf as ApplyConf};
    use neural_network::error::{Conf as ErrorConf, Sample};
    use neural_network::train::{Conf as TrainConf};
    use neural_network::matrix::Matrix;
    use neural_network::network::Network;
    let mut weights_values = [
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0, 0.0,
    ];
    let inputs = [0, 1, 2].iter().cloned().collect::<BTreeSet<usize>>();
    let outputs = [3, 4].iter().cloned().collect::<HashSet<usize>>();
    let weights = Matrix::new(5, &mut weights_values);
    let nodes = (0..5).map(|x| (x, Node(x))).collect::<HashMap<usize, Node>>();
    let network = Network {
        inputs: &inputs,
        outputs: &outputs,
        weights: weights,
        nodes: &nodes
    };
    let mutator = Mutator::from_network(&network);
    let apply_conf = ApplyConf {
        group_size: 1000,
        threshold: 1e-4,
    };
    let samples = [
        Sample {input: &[0.6, 0.7, 0.8], output: &[0.5, 0.4]},
        Sample {input: &[0.3, 0.4, 0.5], output: &[0.3, 0.4]},
    ];
    let error_conf = ErrorConf {
        apply_conf: &apply_conf,
        samples: &samples,
    };
    let train_conf = TrainConf {
        error_conf: &error_conf,
        max_function_calls_count: 111,
    };
    let mut rng = XorShiftRng::new_unseeded();
    rng.reseed([1, 1, 1, 1]);
    let mut node_id = IdGenerator::new(0);
    let mut conf = Conf {
        train_conf: &train_conf,
        rng: &mut rng,
        node_id: &mut node_id,
        population_size: 2,
        error: 1e-3,
        iterations_count: 0,
    };
    let evolved = mutator.evolve(&mut conf);
    let evolved_network_buf = evolved.as_network_buf();
    let evolved_network = evolved_network_buf.as_network();
    let result: &[f64] = evolved_network.weights.values();
    assert_eq!(result, &[
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.1, 0.1,
        0.0, 0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0, 0.0,
    ] as &[f64]);
}
<|endoftext|>


<commit_before>use errors::{Result, ResultExt};

use case::CaseExt;
use difference;

use super::defaults;
use difference::{Changeset, Difference};
use handlebars::{Handlebars, Helper, RenderContext, RenderError};
use std::collections::BTreeMap;
use std::env;
use std::fs::{self, File, OpenOptions, create_dir_all};
use std::io::{self, Read, Write};
use std::path::{MAIN_SEPARATOR, Path, PathBuf};
use walkdir::WalkDir;
extern crate term;

/// file to clone template to
// const TMP_PREFIX: &'static str = "porteurbars";
/// subdirectory containing template source
const TEMPLATE_DIR: &'static str = "template";

/// name of file containing key/value pairs representing template defaults
const DEFAULTS: &'static str = "default.env";

/// A template holds a path to template source and a
/// file describing the default values associated with
/// names used in the template
#[derive(Debug)]
pub struct Template {
    /// path to template source
    pub path: PathBuf,
}

impl Template {
    pub fn new<P>(path: P) -> Template
    where
        P: AsRef<Path>,
    {
        Template { path: path.as_ref().to_path_buf() }
    }

    /// resolve context
    fn context<R>(
        &self,
        root: &Option<R>,
        yes: bool,
    ) -> Result<BTreeMap<String, String>>
    where
        R: AsRef<Path>,
    {
        let path = &self.path;
        let defaults_file = root.as_ref()
            .map(|r| path.join(r))
            .unwrap_or(path.to_path_buf())
            .join(DEFAULTS);
        let defaults = defaults::from_file(defaults_file.clone()).chain_err(
            move || {
                format!(
                    "failed to parse defaults from file {}",
                    defaults_file.to_string_lossy()
                )
            },
        )?;
        let resolved = if yes {
            defaults.iter().fold(BTreeMap::new(), |mut a, e| {
                let &(ref k, ref v) = e;
                a.insert(k.clone(), v.clone());
                a
            })
        } else {
            interact(&defaults).chain_err(|| "failed to parse defaults")?
        };
        Ok(resolved)
    }

    /// Apply template
    pub fn apply<P, R>(
        &self,
        target: P,
        root: Option<R>,
        yes: bool,
        keep: bool,
    ) -> Result<()>
    where
        P: AsRef<Path>,
        R: AsRef<Path>,
    {
        let ctx = self.context(&root, yes)?;
        let adjusted_path = root.as_ref()
            .map(|r| self.path.join(r))
            .unwrap_or(self.path.to_path_buf());

        // apply handlebars processing
        let apply = |path: &Path, hbs: &mut Handlebars| -> Result<()> {

            // /tmp/download_dir/templates
            let scratchpath =
                &format!(
                    "{}{}",
                    adjusted_path.join(TEMPLATE_DIR).to_str().unwrap(),
                    MAIN_SEPARATOR
                )
                    [..];

            // path relatived based on scratch dir
            let localpath =
                path.to_str().unwrap().trim_left_matches(scratchpath);

            // eval path as template
            let evalpath =
                hbs.template_render(&localpath, &ctx).chain_err(|| {
                    format!("failed to render template {}", localpath)
                })?;

            // rewritten path, based on target dir and eval path
            let targetpath = target.as_ref().join(evalpath);

            if path.is_dir() {
                fs::create_dir_all(targetpath).chain_err(|| {
                    format!(
                        "failed to create directory {}",
                        path.to_string_lossy()
                    )
                })?
            } else {
                let mut file = File::open(path)?;
                let mut s = String::new();
                file.read_to_string(&mut s)?;
                if targetpath.exists() {
                    // open file for reading and writing
                    let mut file = OpenOptions::new()
                        .write(true)
                        .read(true)
                        .open(&targetpath)?;

                    // get the current content
                    let mut current_content = String::new();
                    file.read_to_string(&mut current_content)?;

                    // get the target content
                    let template_eval = hbs.template_render(&s, &ctx)?;

                    // if there's a diff prompt for change
                    if template_eval != current_content {
                        let kept = keep ||
                            keep_current_content(
                                current_content.as_ref(),
                                template_eval.as_ref(),
                                &targetpath,
                            )?;
                        if !kept {
                            // force truncation of current content
                            let mut file = OpenOptions::new()
                                .write(true)
                                .truncate(true)
                                .open(targetpath)?;
                            file.write_all(template_eval.as_bytes())?;
                        }
                    }
                } else {
                    let mut file = File::create(targetpath)?;
                    hbs.template_renderw(&s, &ctx, &mut file)?;
                }
            }
            Ok(())
        };

        create_dir_all(target.as_ref())?;
        let mut hbs = bars();
        for entry in WalkDir::new(&adjusted_path.join(TEMPLATE_DIR))
            .into_iter()
            .skip(1)
            .filter_map(|e| e.ok())
        {
            debug!("applying {:?}", entry.path().display());
            apply(entry.path(), &mut hbs)?
        }
        Ok(())
    }
}

pub fn bars() -> Handlebars {
    let mut hbs = Handlebars::new();
    fn transform<F>(bars: &mut Handlebars, name: &str, f: F)
    where
        F: 'static + Fn(&str) -> String + Sync + Send,
    {
        bars.register_helper(
            name,
            Box::new(move |h: &Helper,
                  _: &Handlebars,
                  rc: &mut RenderContext|
                  -> ::std::result::Result<(), RenderError> {
                let value = h.params().get(0).unwrap().value();
                rc.writer.write(f(value.as_str().unwrap()).as_bytes())?;
                Ok(())
            }),
        );
    }

    transform(&mut hbs, "upper", str::to_uppercase);
    transform(&mut hbs, "lower", str::to_lowercase);
    transform(&mut hbs, "capitalize", CaseExt::to_capitalized);
    transform(&mut hbs, "camel", CaseExt::to_camel);
    transform(&mut hbs, "snake", CaseExt::to_snake);
    transform(&mut hbs, "dashed", CaseExt::to_dashed);

    hbs
}

fn keep_current_content<P>(
    current: &str,
    new: &str,
    file: P,
) -> io::Result<bool>
where
    P: AsRef<Path>,
{
    let mut answer = String::new();
    println!(
        "\n⚠ Warning: Conflicts exist with the previous version of {}\n",
        file.as_ref().display()
    );
    diff(difference::Changeset::new(current, new, "\n"))?;
    print!("Type `r` to replace it: ");
    io::stdout().flush()?;
    io::stdin().read_line(&mut answer)?;
    let trimmed = answer.trim().to_lowercase();
    Ok(trimmed.is_empty() || trimmed != String::from("r"))
}

fn diff(changes: difference::Changeset) -> io::Result<()> {
    let Changeset { diffs, .. } = changes;
    let mut t = term::stdout().unwrap();

    for i in 0..diffs.len() {
        match diffs[i] {
            Difference::Same(ref x) => {
                t.reset()?;
                writeln!(t, " {}", x)?;
            }
            Difference::Add(ref x) => {
                match diffs[i - 1] {
                    Difference::Rem(ref y) => {
                        t.fg(term::color::GREEN)?;
                        write!(t, "+")?;
                        let Changeset { diffs, .. } = Changeset::new(y, x, "");
                        for c in diffs {
                            match c {
                                Difference::Same(ref z) => {
                                    t.fg(term::color::GREEN)?;
                                    write!(t, "{}", z)?;
                                    write!(t, "")?;
                                }
                                Difference::Add(ref z) => {
                                    t.fg(term::color::WHITE)?;
                                    t.bg(term::color::GREEN)?;
                                    write!(t, "{}", z)?;
                                    t.reset()?;
                                    write!(t, "")?;
                                }
                                _ => (),
                            }
                        }
                        writeln!(t, "")?;
                    }
                    _ => {
                        t.fg(term::color::BRIGHT_GREEN)?;
                        writeln!(t, "+{}", x)?;
                    }
                };
            }
            Difference::Rem(ref x) => {
                t.fg(term::color::RED)?;
                writeln!(t, "-{}", x)?;
            }
        }
    }
    t.reset()?;
    t.flush()?;
    Ok(())
}

/// prompt for a value defaulting to a given string when an answer is not available
fn prompt(name: &str, default: &str) -> io::Result<String> {
    let mut answer = String::new();
    print!("{} [{}]: ", name, default);
    io::stdout().flush()?;
    io::stdin().read_line(&mut answer)?;
    let trimmed = answer.trim();
    if trimmed.trim().is_empty() {
        Ok(default.to_owned())
    } else {
        Ok(trimmed.to_owned())
    }
}

/// given a set of defaults, attempt to interact with a user
/// to resolve the parameters that can not be inferred from env
fn interact(defaults: &defaults::Defaults) -> Result<BTreeMap<String, String>> {
    let mut resolved = BTreeMap::new();
    for pair in defaults.iter() {
        let &(ref k, ref v) = pair;
        let answer = match env::var(k) {
            Ok(v) => v,
            _ => prompt(k.as_ref(), v.as_ref())?,
        };
        resolved.insert(k.clone(), answer);
    }
    Ok(resolved)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::BTreeMap;

    #[test]
    fn test_bars_respects_escapes_tags() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurbars".to_owned());
        assert_eq!(
            "Hello, {{upper name}}",
            bars()
                .template_render(r"Hello, \\{{upper name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn test_bars_upper() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurbars".to_owned());
        assert_eq!(
            "Hello, PORTEURBARS",
            bars()
                .template_render("Hello, {{upper name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn test_bars_lower() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "PORTEURBARS".to_owned());
        assert_eq!(
            "Hello, porteurbars",
            bars()
                .template_render("Hello, {{lower name}}", &map)
                .unwrap()
        );
    }
}
<commit_msg>test cov<commit_after>use errors::{Result, ResultExt};

use case::CaseExt;
use difference;

use super::defaults;
use difference::{Changeset, Difference};
use handlebars::{Handlebars, Helper, RenderContext, RenderError};
use std::collections::BTreeMap;
use std::env;
use std::fs::{self, File, OpenOptions, create_dir_all};
use std::io::{self, Read, Write};
use std::path::{MAIN_SEPARATOR, Path, PathBuf};
use walkdir::WalkDir;
extern crate term;

/// file to clone template to
// const TMP_PREFIX: &'static str = "porteurbars";
/// subdirectory containing template source
const TEMPLATE_DIR: &'static str = "template";

/// name of file containing key/value pairs representing template defaults
const DEFAULTS: &'static str = "default.env";

/// A template holds a path to template source and a
/// file describing the default values associated with
/// names used in the template
#[derive(Debug)]
pub struct Template {
    /// path to template source
    pub path: PathBuf,
}

impl Template {
    pub fn new<P>(path: P) -> Template
    where
        P: AsRef<Path>,
    {
        Template { path: path.as_ref().to_path_buf() }
    }

    /// resolve context
    fn context<R>(
        &self,
        root: &Option<R>,
        yes: bool,
    ) -> Result<BTreeMap<String, String>>
    where
        R: AsRef<Path>,
    {
        let path = &self.path;
        let defaults_file = root.as_ref()
            .map(|r| path.join(r))
            .unwrap_or(path.to_path_buf())
            .join(DEFAULTS);
        let defaults = defaults::from_file(defaults_file.clone()).chain_err(
            move || {
                format!(
                    "failed to parse defaults from file {}",
                    defaults_file.to_string_lossy()
                )
            },
        )?;
        let resolved = if yes {
            defaults.iter().fold(BTreeMap::new(), |mut a, e| {
                let &(ref k, ref v) = e;
                a.insert(k.clone(), v.clone());
                a
            })
        } else {
            interact(&defaults).chain_err(|| "failed to parse defaults")?
        };
        Ok(resolved)
    }

    /// Apply template
    pub fn apply<P, R>(
        &self,
        target: P,
        root: Option<R>,
        yes: bool,
        keep: bool,
    ) -> Result<()>
    where
        P: AsRef<Path>,
        R: AsRef<Path>,
    {
        let ctx = self.context(&root, yes)?;
        let adjusted_path = root.as_ref()
            .map(|r| self.path.join(r))
            .unwrap_or(self.path.to_path_buf());

        // apply handlebars processing
        let apply = |path: &Path, hbs: &mut Handlebars| -> Result<()> {

            // /tmp/download_dir/templates
            let scratchpath =
                &format!(
                    "{}{}",
                    adjusted_path.join(TEMPLATE_DIR).to_str().unwrap(),
                    MAIN_SEPARATOR
                )
                    [..];

            // path relatived based on scratch dir
            let localpath =
                path.to_str().unwrap().trim_left_matches(scratchpath);

            // eval path as template
            let evalpath =
                hbs.template_render(&localpath, &ctx).chain_err(|| {
                    format!("failed to render template {}", localpath)
                })?;

            // rewritten path, based on target dir and eval path
            let targetpath = target.as_ref().join(evalpath);

            if path.is_dir() {
                fs::create_dir_all(targetpath).chain_err(|| {
                    format!(
                        "failed to create directory {}",
                        path.to_string_lossy()
                    )
                })?
            } else {
                let mut file = File::open(path)?;
                let mut s = String::new();
                file.read_to_string(&mut s)?;
                if targetpath.exists() {
                    // open file for reading and writing
                    let mut file = OpenOptions::new()
                        .write(true)
                        .read(true)
                        .open(&targetpath)?;

                    // get the current content
                    let mut current_content = String::new();
                    file.read_to_string(&mut current_content)?;

                    // get the target content
                    let template_eval = hbs.template_render(&s, &ctx)?;

                    // if there's a diff prompt for change
                    if template_eval != current_content {
                        let kept = keep ||
                            keep_current_content(
                                current_content.as_ref(),
                                template_eval.as_ref(),
                                &targetpath,
                            )?;
                        if !kept {
                            // force truncation of current content
                            let mut file = OpenOptions::new()
                                .write(true)
                                .truncate(true)
                                .open(targetpath)?;
                            file.write_all(template_eval.as_bytes())?;
                        }
                    }
                } else {
                    let mut file = File::create(targetpath)?;
                    hbs.template_renderw(&s, &ctx, &mut file)?;
                }
            }
            Ok(())
        };

        create_dir_all(target.as_ref())?;
        let mut hbs = bars();
        for entry in WalkDir::new(&adjusted_path.join(TEMPLATE_DIR))
            .into_iter()
            .skip(1)
            .filter_map(|e| e.ok())
        {
            debug!("applying {:?}", entry.path().display());
            apply(entry.path(), &mut hbs)?
        }
        Ok(())
    }
}

pub fn bars() -> Handlebars {
    let mut hbs = Handlebars::new();
    fn transform<F>(bars: &mut Handlebars, name: &str, f: F)
    where
        F: 'static + Fn(&str) -> String + Sync + Send,
    {
        bars.register_helper(
            name,
            Box::new(move |h: &Helper,
                  _: &Handlebars,
                  rc: &mut RenderContext|
                  -> ::std::result::Result<(), RenderError> {
                let value = h.params().get(0).unwrap().value();
                rc.writer.write(f(value.as_str().unwrap()).as_bytes())?;
                Ok(())
            }),
        );
    }

    transform(&mut hbs, "upper", str::to_uppercase);
    transform(&mut hbs, "lower", str::to_lowercase);
    transform(&mut hbs, "capitalize", CaseExt::to_capitalized);
    transform(&mut hbs, "camel", CaseExt::to_camel);
    transform(&mut hbs, "snake", CaseExt::to_snake);
    transform(&mut hbs, "dashed", CaseExt::to_dashed);

    hbs
}

fn keep_current_content<P>(
    current: &str,
    new: &str,
    file: P,
) -> io::Result<bool>
where
    P: AsRef<Path>,
{
    let mut answer = String::new();
    println!(
        "\n⚠ Warning: Conflicts exist with the previous version of {}\n",
        file.as_ref().display()
    );
    diff(difference::Changeset::new(current, new, "\n"))?;
    print!("Type `r` to replace it: ");
    io::stdout().flush()?;
    io::stdin().read_line(&mut answer)?;
    let trimmed = answer.trim().to_lowercase();
    Ok(trimmed.is_empty() || trimmed != String::from("r"))
}

fn diff(changes: difference::Changeset) -> io::Result<()> {
    let Changeset { diffs, .. } = changes;
    let mut t = term::stdout().unwrap();

    for i in 0..diffs.len() {
        match diffs[i] {
            Difference::Same(ref x) => {
                t.reset()?;
                writeln!(t, " {}", x)?;
            }
            Difference::Add(ref x) => {
                match diffs[i - 1] {
                    Difference::Rem(ref y) => {
                        t.fg(term::color::GREEN)?;
                        write!(t, "+")?;
                        let Changeset { diffs, .. } = Changeset::new(y, x, "");
                        for c in diffs {
                            match c {
                                Difference::Same(ref z) => {
                                    t.fg(term::color::GREEN)?;
                                    write!(t, "{}", z)?;
                                    write!(t, "")?;
                                }
                                Difference::Add(ref z) => {
                                    t.fg(term::color::WHITE)?;
                                    t.bg(term::color::GREEN)?;
                                    write!(t, "{}", z)?;
                                    t.reset()?;
                                    write!(t, "")?;
                                }
                                _ => (),
                            }
                        }
                        writeln!(t, "")?;
                    }
                    _ => {
                        t.fg(term::color::BRIGHT_GREEN)?;
                        writeln!(t, "+{}", x)?;
                    }
                };
            }
            Difference::Rem(ref x) => {
                t.fg(term::color::RED)?;
                writeln!(t, "-{}", x)?;
            }
        }
    }
    t.reset()?;
    t.flush()?;
    Ok(())
}

/// prompt for a value defaulting to a given string when an answer is not available
fn prompt(name: &str, default: &str) -> io::Result<String> {
    let mut answer = String::new();
    print!("{} [{}]: ", name, default);
    io::stdout().flush()?;
    io::stdin().read_line(&mut answer)?;
    let trimmed = answer.trim();
    if trimmed.trim().is_empty() {
        Ok(default.to_owned())
    } else {
        Ok(trimmed.to_owned())
    }
}

/// given a set of defaults, attempt to interact with a user
/// to resolve the parameters that can not be inferred from env
fn interact(defaults: &defaults::Defaults) -> Result<BTreeMap<String, String>> {
    let mut resolved = BTreeMap::new();
    for pair in defaults.iter() {
        let &(ref k, ref v) = pair;
        let answer = match env::var(k) {
            Ok(v) => v,
            _ => prompt(k.as_ref(), v.as_ref())?,
        };
        resolved.insert(k.clone(), answer);
    }
    Ok(resolved)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::BTreeMap;

    #[test]
    fn bars_respects_escapes_tags() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurbars".to_owned());
        assert_eq!(
            "Hello, {{upper name}}",
            bars()
                .template_render(r"Hello, \\{{upper name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_upper() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurbars".to_owned());
        assert_eq!(
            "Hello, PORTEURBARS",
            bars()
                .template_render("Hello, {{upper name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_capitalize() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurbars".to_owned());
        assert_eq!(
            "Hello, Porteurbars",
            bars()
                .template_render("Hello, {{capitalize name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_camel() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteur_bars".to_owned());
        assert_eq!(
            "Hello, PorteurBars",
            bars()
                .template_render("Hello, {{camel name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_dashed() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteur_bars".to_owned());
        assert_eq!(
            "Hello, porteur-bars",
            bars()
                .template_render("Hello, {{dashed name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_snake() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "porteurBars".to_owned());
        assert_eq!(
            "Hello, porteur_bars",
            bars()
                .template_render("Hello, {{snake name}}", &map)
                .unwrap()
        );
    }

    #[test]
    fn bars_lower() {
        let mut map = BTreeMap::new();
        map.insert("name".to_owned(), "PORTEURBARS".to_owned());
        assert_eq!(
            "Hello, porteurbars",
            bars()
                .template_render("Hello, {{lower name}}", &map)
                .unwrap()
        );
    }
}
<|endoftext|>


<commit_before>use std::str::CharEq;

pub fn tokenize(text: &str) -> Vec<&str> {
  text.split(Splitter::is_match).filter(|s| s.len() > 0).collect()
}

struct Splitter;

impl Splitter {
    fn is_match(c: char) -> bool {
        match c {
            ' ' | ',' | '.' | '!' | '?' | ';' | '\'' |  '"'
            | ':' | '\t' | '\n' | '(' | ')' | '-' => true,
            _ => false
        }
    }
}
<commit_msg>Removed CharEq import<commit_after>
pub fn tokenize(text: &str) -> Vec<&str> {
  text.split(Splitter::is_match)
      .filter(|s| s.len() > 0)
      .collect()
}

struct Splitter;

impl Splitter {
    fn is_match(c: char) -> bool {
        match c {
            ' ' | ',' | '.' | '!' | '?' | ';' | '\'' |  '"'
            | ':' | '\t' | '\n' | '(' | ')' | '-' => true,
            _ => false
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub, Mul};
use libc::{c_char, c_int, c_ulong, c_long, c_double, c_void};
use std::ffi::*;
use std::cmp::{Ordering};
use std::slice;
use std::sync::{Once, ONCE_INIT};

static EXACTINIT: Once = ONCE_INIT;

#[repr(C)]
#[derive(Debug, Clone, PartialEq)]
pub struct Point2D {
    x: c_double,
    y: c_double,
}

#[repr(C)]
#[derive(Debug, Clone, PartialEq)]
pub struct Point3D {
    x: c_double,
    y: c_double,
    z: c_double,
}

#[link(name = "predicates")]
extern "C" {
    fn exactinit() -> c_void;
    fn insphere(pa: *const Point3D, pb: *const Point3D, pc: *const Point3D, pd: *const Point3D, pe: *const Point3D) -> c_double;
    fn incircle(pa: *const Point2D, pb: *const Point2D, pc: *const Point2D, pd: *const Point2D) -> c_double;
}

fn init_predicates() {
    EXACTINIT.call_once(|| {
        unsafe { exactinit() };
    });
}

#[derive(Debug, Eq, PartialEq)]
pub enum InCircleLocation {
    Inside,
    Outside,
    On
}

pub trait InCircle<P> {
    fn in_circle_test(&self, point: &P) -> Option<InCircleLocation>;
}

pub struct Triangle<P> {
    p1: P,
    p2: P,
    p3: P,
}

impl InCircle<Point2D> for Triangle<Point2D> {
    fn in_circle_test(&self, point: &Point2D) -> Option<InCircleLocation> {
        init_predicates();

        let incircle_det = unsafe { incircle(&self.p1, &self.p2, &self.p3, point) };

        match 0.0.partial_cmp(&incircle_det) {
            Some(Ordering::Greater) => { Some(InCircleLocation::Inside) }
            Some(Ordering::Less) => { Some(InCircleLocation::Outside) }
            Some(Ordering::Equal) => { Some(InCircleLocation::On) }
            None => { None }
        }
    }
}

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

    #[test]
    fn mat3_det_mpfr() {
        let p1 = Point2D { x: 0.0, y: 0.0 };
        let p2 = Point2D { x: 0.0, y: 1.0 };
        let p3 = Point2D { x: 1.0, y: 1.0 };
        let d_inside  = Point2D { x: 0.5, y: 0.5 };
        let d_outside  = Point2D { x: 2.0, y: 0.0 };
        let d_on  = Point2D { x: 1.0, y: 1.0 };

        let t = Triangle { p1: p1, p2: p2, p3: p3 };

        assert_eq!(t.in_circle_test(&d_inside), Some(InCircleLocation::Inside));
        assert_eq!(t.in_circle_test(&d_outside), Some(InCircleLocation::Outside));
        assert_eq!(t.in_circle_test(&d_on), Some(InCircleLocation::On));
    }
}
<commit_msg>Renamed test<commit_after>use std::ops::{Add, Sub, Mul};
use libc::{c_char, c_int, c_ulong, c_long, c_double, c_void};
use std::ffi::*;
use std::cmp::{Ordering};
use std::slice;
use std::sync::{Once, ONCE_INIT};

static EXACTINIT: Once = ONCE_INIT;

#[repr(C)]
#[derive(Debug, Clone, PartialEq)]
pub struct Point2D {
    x: c_double,
    y: c_double,
}

#[repr(C)]
#[derive(Debug, Clone, PartialEq)]
pub struct Point3D {
    x: c_double,
    y: c_double,
    z: c_double,
}

#[link(name = "predicates")]
extern "C" {
    fn exactinit() -> c_void;
    fn insphere(pa: *const Point3D, pb: *const Point3D, pc: *const Point3D, pd: *const Point3D, pe: *const Point3D) -> c_double;
    fn incircle(pa: *const Point2D, pb: *const Point2D, pc: *const Point2D, pd: *const Point2D) -> c_double;
}

fn init_predicates() {
    EXACTINIT.call_once(|| {
        unsafe { exactinit() };
    });
}

#[derive(Debug, Eq, PartialEq)]
pub enum InCircleLocation {
    Inside,
    Outside,
    On
}

pub trait InCircle<P> {
    fn in_circle_test(&self, point: &P) -> Option<InCircleLocation>;
}

pub struct Triangle<P> {
    p1: P,
    p2: P,
    p3: P,
}

impl InCircle<Point2D> for Triangle<Point2D> {
    fn in_circle_test(&self, point: &Point2D) -> Option<InCircleLocation> {
        init_predicates();

        let incircle_det = unsafe { incircle(&self.p1, &self.p2, &self.p3, point) };

        match 0.0.partial_cmp(&incircle_det) {
            Some(Ordering::Greater) => { Some(InCircleLocation::Inside) }
            Some(Ordering::Less) => { Some(InCircleLocation::Outside) }
            Some(Ordering::Equal) => { Some(InCircleLocation::On) }
            None => { None }
        }
    }
}

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

    #[test]
    fn in_circle_2d() {
        let p1 = Point2D { x: 0.0, y: 0.0 };
        let p2 = Point2D { x: 0.0, y: 1.0 };
        let p3 = Point2D { x: 1.0, y: 1.0 };
        let d_inside  = Point2D { x: 0.5, y: 0.5 };
        let d_outside  = Point2D { x: 2.0, y: 0.0 };
        let d_on  = Point2D { x: 1.0, y: 1.0 };

        let t = Triangle { p1: p1, p2: p2, p3: p3 };

        assert_eq!(t.in_circle_test(&d_inside), Some(InCircleLocation::Inside));
        assert_eq!(t.in_circle_test(&d_outside), Some(InCircleLocation::Outside));
        assert_eq!(t.in_circle_test(&d_on), Some(InCircleLocation::On));
    }
}
<|endoftext|>


<commit_before>use voodoo::color::ColorValue;
use voodoo::window::{FormattedString, Point, Window};

use program::{Ability, Program, Team};

pub struct InfoView {
    window: Window,
    ability_list: Vec<(String, Ability)>,
    selected_ability: Option<(usize, Ability)>,
    team: Team,
    pub primary_action: String,
}

impl InfoView {
    pub fn new(window: Window) -> InfoView {
        let info = InfoView {
            window: window,
            ability_list: Vec::new(),
            selected_ability: None,
            team: Team::Player,
            primary_action: "     End Turn     ".to_owned(),
        };

        info
    }

    pub fn from_global_frame(&self, p: Point) -> Option<Point> {
        self.window.position.from_global_frame(p)
    }

    pub fn refresh(&mut self, stdout: &mut ::std::io::Stdout) {
        self.window.refresh(stdout);
    }

    pub fn display_end_turn(&mut self) {
        let mut f: FormattedString = (&self.primary_action).into();
        f.bg = Some(ColorValue::Magenta);
        self.window.print_at(Point::new(2, 23), f);
    }

    pub fn set_team(&mut self, team: Team) {
        self.team = team;
    }

    pub fn clear(&mut self) {
        self.ability_list.clear();
        self.selected_ability = None;
        self.window.clear();
        self.window.border();
        self.window.print_at(Point::new(2, 1), match self.team {
            Team::Player => "PLAYER TURN",
            Team::Enemy => "AI TURN",
        });
        if let Team::Player = self.team {
            self.display_end_turn();
        }
    }

    pub fn display_abilities(&mut self) {
        let mut y = 6;
        for (ability_number, &(ref name, _)) in self.ability_list.iter().enumerate() {
            let mut f: FormattedString = name.into();
            f.bg = if let Some((offset, _)) = self.selected_ability {
                if offset == ability_number {
                    Some(ColorValue::Red)
                }
                else {
                    Some(ColorValue::Magenta)
                }
            } else { Some(ColorValue::Magenta) };
            self.window.print_at(Point::new(2, y), f);
            y += 1;
        }
    }

    // TODO: take a ProgramRef and store it (maybe a weak reference)
    pub fn display_program(&mut self, program: &Program) {
        self.window.print_at(Point::new(2, 2), &program.name);
        self.update_program(program);

        self.ability_list.clear();
        if program.turn_state.ability_used {
            self.window.print_at(Point::new(2, 4), "Ability used");
        }
        else {
            self.window.print_at(Point::new(2, 4), "Abilities:");
            self.ability_list.extend(program.abilities.iter().cloned());

            self.display_abilities();
        }
    }

    pub fn update_program(&mut self, program: &Program) {
        self.window.print_at(
            Point::new(2, 3),
            &format!("Moves: {}/{}", program.max_moves - program.turn_state.moves_made, program.max_moves));
    }

    // TODO: return the ability range or something? Ability descriptor
    pub fn translate_click(&mut self, click: Point) -> Option<Ability> {
        for (offset, &(_, ability)) in self.ability_list.iter().enumerate() {
            if click.y == 6 + offset as u16 {
                self.selected_ability = Some((offset, ability));
                break;
            }
        }
        self.display_abilities();

        self.selected_ability.map(|(_, ability)| ability)
    }

    pub fn clear_ability(&mut self) {
        self.selected_ability = None;
        self.display_abilities();
    }
}
<commit_msg>refactor: move list UI handling code to separate struct<commit_after>use voodoo::color::ColorValue;
use voodoo::window::{FormattedString, Point, Window};

use program::{Ability, Program, Team};

pub struct ChoiceList<T> {
    y: u16,
    list: Vec<(String, T)>,
    selected: Option<(u16, T)>,
}

impl<T: Copy> ChoiceList<T> {
    pub fn new(y: u16) -> ChoiceList<T> {
        ChoiceList {
            y: y,
            list: vec![],
            selected: None,
        }
    }

    pub fn choices(&mut self) -> &mut Vec<(String, T)> {
        &mut self.list
    }

    pub fn handle_click(&mut self, point: Point) -> Option<T> {
        if point.y < self.y || point.y >= self.y + self.list.len() as u16 {
            self.selected = None;
        }
        else if let Some((offset, _)) = self.selected {
            if offset == point.y {
                self.selected = None;
            }
            else {
                self.selected = Some((point.y, self.list[(point.y - self.y) as usize].1));
            }
        }
        else {
            self.selected = Some((point.y, self.list[(point.y - self.y) as usize].1));
        }

        self.selected.map(|x| x.1)
    }

    pub fn clear_selection(&mut self) {
        self.selected = None;
    }

    pub fn clear(&mut self) {
        self.list.clear();
        self.selected = None;
    }

    pub fn display(&self, window: &mut Window) {
        let mut y = self.y;
        for (number, &(ref label, _)) in self.list.iter().enumerate() {
            let number = number as u16 + self.y;
            let mut f: FormattedString = label.into();
            f.bg = if let Some((offset, _)) = self.selected {
                if offset == number {
                    Some(ColorValue::Red)
                }
                else {
                    Some(ColorValue::Magenta)
                }
            } else { Some(ColorValue::Magenta) };
            window.print_at(Point::new(2, y), f);
            y += 1;
        }
    }
}

pub struct InfoView {
    window: Window,
    ability_list: ChoiceList<Ability>,
    team: Team,
    pub primary_action: String,
}

impl InfoView {
    pub fn new(window: Window) -> InfoView {
        let info = InfoView {
            window: window,
            ability_list: ChoiceList::new(6),
            team: Team::Player,
            primary_action: "     End Turn     ".to_owned(),
        };

        info
    }

    pub fn from_global_frame(&self, p: Point) -> Option<Point> {
        self.window.position.from_global_frame(p)
    }

    pub fn refresh(&mut self, stdout: &mut ::std::io::Stdout) {
        self.window.refresh(stdout);
    }

    pub fn display_end_turn(&mut self) {
        let mut f: FormattedString = (&self.primary_action).into();
        f.bg = Some(ColorValue::Magenta);
        self.window.print_at(Point::new(2, 23), f);
    }

    pub fn set_team(&mut self, team: Team) {
        self.team = team;
    }

    pub fn clear(&mut self) {
        self.ability_list.clear();
        self.window.clear();
        self.window.border();
        self.window.print_at(Point::new(2, 1), match self.team {
            Team::Player => "PLAYER TURN",
            Team::Enemy => "AI TURN",
        });
        if let Team::Player = self.team {
            self.display_end_turn();
        }
    }

    pub fn display_abilities(&mut self) {
        self.ability_list.display(&mut self.window);
    }

    // TODO: take a ProgramRef and store it (maybe a weak reference)
    pub fn display_program(&mut self, program: &Program) {
        self.window.print_at(Point::new(2, 2), &program.name);
        self.update_program(program);

        self.ability_list.clear();
        if program.turn_state.ability_used {
            self.window.print_at(Point::new(2, 4), "Ability used");
        }
        else {
            self.window.print_at(Point::new(2, 4), "Abilities:");
            self.ability_list.choices().extend(program.abilities.iter().cloned());

            self.display_abilities();
        }
    }

    pub fn update_program(&mut self, program: &Program) {
        self.window.print_at(
            Point::new(2, 3),
            &format!("Moves: {}/{}", program.max_moves - program.turn_state.moves_made, program.max_moves));
    }

    // TODO: return the ability range or something? Ability descriptor
    pub fn translate_click(&mut self, click: Point) -> Option<Ability> {
        let result = self.ability_list.handle_click(click);
        self.display_abilities();

        result
    }

    pub fn clear_ability(&mut self) {
        self.ability_list.clear_selection();
        self.display_abilities();
    }
}
<|endoftext|>


<commit_before>//! This module implements simple request and response objects.

use std::fmt;
use std::collections::HashMap;
use std::net::SocketAddr;
use std::io;
use std::io::{Read, Write};

use hyper;
use hyper::uri::RequestUri::{AbsolutePath, AbsoluteUri, Authority, Star};
use hyper::header::{Headers, ContentLength, ContentType, Cookie};
use hyper::mime::Mime;
use hyper::method::Method;
use url::UrlParser;
use url::form_urlencoded;
use formdata::uploaded_file::UploadedFile;

use app::Pencil;
use datastructures::MultiDict;
use httputils::{get_name_by_http_code, get_content_type, get_host_value};
use httputils::get_status_from_code;
use routing::Rule;
use types::ViewArgs;
use http_errors::{HTTPError, NotFound};
use formparser::FormDataParser;

/// Request type.
pub struct Request<'r, 'a, 'b: 'a> {
    pub app: &'r Pencil,
    /// The original hyper request object.
    pub request: hyper::server::request::Request<'a, 'b>,
    /// The URL rule that matched the request.  This is
    /// going to be `None` if nothing matched.
    pub url_rule: Option<Rule>,
    /// A dict of view arguments that matched the request.
    pub view_args: ViewArgs,
    /// If matching the URL failed, this will be the error.
    pub routing_error: Option<HTTPError>,
    args: Option<MultiDict<String>>,
    form: Option<MultiDict<String>>,
    files: Option<MultiDict<UploadedFile>>,
}

impl<'r, 'a, 'b: 'a> Request<'r, 'a, 'b> {
    /// Create a `Request`.
    pub fn new(app: &'r Pencil, request: hyper::server::request::Request<'a, 'b>) -> Request<'r, 'a, 'b> {
        Request {
            app: app,
            request: request,
            url_rule: None,
            view_args: HashMap::new(),
            routing_error: None,
            args: None,
            form: None,
            files: None,
        }
    }

    /// Match the request, set the `url_rule` and `view_args` field.
    pub fn match_request(&mut self) {
        match self.path() {
            Some(path) => {
                let url_adapter = self.app.url_map.bind(path, self.method());
                match url_adapter.matched() {
                    Ok(caps) => {
                        let (rule, view_args) = caps;
                        self.url_rule = Some(rule);
                        self.view_args = view_args;
                    },
                    Err(e) => {
                        self.routing_error = Some(e);
                    },
                }
            },
            None => {
                self.routing_error = Some(NotFound);
            }
        }
    }

    /// The endpoint that matched the request.
    pub fn endpoint(&self) -> Option<String> {
        match self.url_rule {
            Some(ref rule) => Some(rule.endpoint.clone()),
            None => None,
        }
    }

    /// The parsed URL parameters.
    pub fn args(&mut self) -> &MultiDict<String> {
        if self.args.is_none() {
            let mut args = MultiDict::new();
            let query_pairs = self.query_string().map(|query| form_urlencoded::parse(query.as_bytes()));
            match query_pairs {
                Some(pairs) => {
                    for (k, v) in pairs {
                        args.add(k, v);
                    }
                },
                None => {},
            }
            self.args = Some(args);
        }
        return self.args.as_ref().unwrap();
    }

    /// Get content type.
    fn content_type(&self) -> Option<ContentType> {
        let content_type: Option<&ContentType> = self.request.headers.get();
        content_type.map(|c| c.clone())
    }

    /// This method is used internally to retrieve submitted data.
    fn load_form_data(&mut self) {
        if self.form.is_some() {
            return
        }
        let (form, files) = match self.content_type() {
            Some(ContentType(mimetype)) => {
                let parser = FormDataParser::new();
                parser.parse(&mut self.request, &mimetype)
            },
            None => {
                (MultiDict::new(), MultiDict::new())
            }
        };
        self.form = Some(form);
        self.files = Some(files);
    }

    /// The form parameters.
    pub fn form(&mut self) -> &MultiDict<String> {
        self.load_form_data();
        self.form.as_ref().unwrap()
    }

    /// All uploaded files.
    pub fn files(&mut self) -> &MultiDict<UploadedFile> {
        self.load_form_data();
        self.files.as_ref().unwrap()
    }

    /// The headers.
    pub fn headers(&self) -> &Headers {
        &self.request.headers
    }

    /// Requested path.
    pub fn path(&self) -> Option<String> {
        match self.request.uri {
            AbsolutePath(ref path) => {
                Some(path.splitn(2, '?').next().unwrap().to_string())
            },
            AbsoluteUri(ref url) => {
                url.serialize_path()
            },
            Authority(_) | Star => None
        }
    }

    /// Requested path including the query string.
    pub fn full_path(&self) -> Option<String> {
        let path = self.path();
        let query_string = self.query_string();
        if path.is_some() && query_string.is_some() {
            return Some(path.unwrap() + "?" + &query_string.unwrap());
        } else  {
            return path;
        }
    }

    /// The host including the port if available.
    pub fn host(&self) -> Option<String> {
        let host: Option<&hyper::header::Host> = self.request.headers.get();
        host.map(|host| get_host_value(host))
    }

    /// The query string.
    pub fn query_string(&self) -> Option<String> {
        match self.request.uri {
            AbsolutePath(ref path) => {
                match UrlParser::new().parse_path(path) {
                    Ok((_, query, _)) => {
                        query
                    },
                    Err(_) => None
                }
            },
            AbsoluteUri(ref url) => {
                url.query.clone()
            },
            Authority(_) | Star => None
        }
    }

    /// The retrieved cookies.
    pub fn cookies(&self) -> Option<&Cookie> {
        self.request.headers.get()
    }

    /// The request method.
    pub fn method(&self) -> String {
        match self.request.method {
            Method::Options => "OPTIONS".to_string(),
            Method::Get => "GET".to_string(),
            Method::Post => "POST".to_string(),
            Method::Put => "PUT".to_string(),
            Method::Delete => "DELETE".to_string(),
            Method::Head => "HEAD".to_string(),
            Method::Trace => "TRACE".to_string(),
            Method::Connect => "CONNECT".to_string(),
            Method::Patch => "PATCH".to_string(),
            Method::Extension(ref method) => method.clone(),
        }
    }

    /// The remote address of the client.
    pub fn remote_addr(&self) -> SocketAddr {
        self.request.remote_addr.clone()
    }

    /// URL scheme (http or https)
    pub fn scheme(&self) -> String {
        match self.request.uri {
            AbsoluteUri(ref url) => {
                return url.scheme.clone();
            },
            _ => {}
        }
        String::from("http")
    }

    /// Just the host with scheme.
    pub fn host_url(&self) -> Option<String> {
        match self.host() {
            Some(host) => {
                Some(self.scheme() + "://" + &host + "/")
            },
            None => None,
        }
    }

    /// The current url.
    pub fn url(&self) -> Option<String> {
        let host_url = self.host_url();
        let full_path = self.full_path();
        if host_url.is_some() && full_path.is_some() {
            Some(host_url.unwrap() + &(full_path.unwrap()).trim_left_matches('/'))
        } else {
            None
        }
    }

    /// The current url without the query string.
    pub fn base_url(&self) -> Option<String> {
        let host_url = self.host_url();
        let path = self.path();
        if host_url.is_some() && path.is_some() {
            Some(host_url.unwrap() + &path.unwrap().trim_left_matches('/'))
        } else {
            None
        }
    }

    /// Whether the request is secure (https).
    pub fn is_secure(&self) -> bool {
        self.scheme() == "https".to_string()
    }
}

impl<'r, 'a, 'b: 'a> fmt::Debug for Request<'r, 'a, 'b> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.url() {
            Some(url) => {
                write!(f, "Pencil Request '{}' {}", url, self.method())
            },
            None => {
                write!(f, "Pencil Request")
            }
        }
    }
}

impl<'r, 'a, 'b: 'a> Read for Request<'r, 'a, 'b> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.request.read(buf)
    }
}

/// Response type.  It is just one container with a couple of parameters
/// (headers, body, status code etc).
#[derive(Clone)]
pub struct Response {
    pub status_code: isize,
    pub headers: Headers,
    pub body: String,
}

impl Response {
    /// Create a `Response`.
    pub fn new(body: String) -> Response {
        let mut response = Response {
            status_code: 200,
            headers: Headers::new(),
            body: body,
        };
        let mime: Mime = "text/html; charset=UTF-8".parse().unwrap();
        let content_type = ContentType(mime);
        let content_length = ContentLength(response.body.len() as u64);
        response.headers.set(content_type);
        response.headers.set(content_length);
        return response;
    }

    /// Get status name.
    pub fn status_name(&self) -> &str {
        match get_name_by_http_code(self.status_code) {
            Some(name) => name,
            None => "UNKNOWN",
        }
    }

    /// Sets a new string as response body.  The content length is set
    /// automatically.
    pub fn set_data(&mut self, value: String) {
        self.body = value;
        let content_length = self.body.len();
        self.set_content_length(content_length);
    }

    /// Returns the response content type if available.
    pub fn content_type(&self) -> Option<&ContentType> {
        self.headers.get()
    }

    /// Set response content type.
    pub fn set_content_type(&mut self, mimetype: &str) {
        let mimetype = get_content_type(mimetype, "UTF-8");
        let mime: Mime = (&mimetype).parse().unwrap();
        let content_type = ContentType(mime);
        self.headers.set(content_type);
    }

    /// Returns the response content length if available.
    pub fn content_length(&self) -> Option<usize> {
        let content_length: Option<&ContentLength> = self.headers.get();
        match content_length {
            Some(&ContentLength(length)) => Some(length as usize),
            None => None,
        }
    }

    /// Set content length.
    pub fn set_content_length(&mut self, value: usize) {
        let content_length = ContentLength(value as u64);
        self.headers.set(content_length);
    }

    /// Sets a cookie(TODO).
    pub fn set_cookie(&mut self) {
    }

    /// Delete a cookie(TODO).
    pub fn delete_cookie(&mut self) {
    }

    /// Return `true` if the response is streamed(currently we do not support
    /// streaming yet, always return `false`).
    pub fn is_streamed(&self) -> bool {
        false
    }

    /// Write the response out.  Mostly you shouldn't use this directly.
    pub fn write(self, request_method: String, mut res: hyper::server::Response) {
        // write status.
        let status_code = self.status_code;
        *res.status_mut() = get_status_from_code(status_code);

        // write headers.
        *res.headers_mut() = self.headers;

        // write data.
        if request_method == String::from("HEAD") ||
           (100 <= status_code && status_code < 200) ||
           status_code == 204 || status_code == 304 {
            res.headers_mut().set(ContentLength(0));
            try_return!(res.start().and_then(|w| w.end()));
        } else {
            let mut res = try_return!(res.start());
            try_return!(res.write_all(self.body.as_bytes()));
            try_return!(res.end());
        }
    }
}
<commit_msg>Added get_json for request<commit_after>//! This module implements simple request and response objects.

use std::fmt;
use std::collections::HashMap;
use std::net::SocketAddr;
use std::io;
use std::io::{Read, Write};

use hyper;
use hyper::uri::RequestUri::{AbsolutePath, AbsoluteUri, Authority, Star};
use hyper::header::{Headers, ContentLength, ContentType, Cookie};
use hyper::mime::Mime;
use hyper::method::Method;
use url::UrlParser;
use url::form_urlencoded;
use formdata::uploaded_file::UploadedFile;
use rustc_serialize::json;

use app::Pencil;
use datastructures::MultiDict;
use httputils::{get_name_by_http_code, get_content_type, get_host_value};
use httputils::get_status_from_code;
use routing::Rule;
use types::ViewArgs;
use http_errors::{HTTPError, NotFound};
use formparser::FormDataParser;

/// Request type.
pub struct Request<'r, 'a, 'b: 'a> {
    pub app: &'r Pencil,
    /// The original hyper request object.
    pub request: hyper::server::request::Request<'a, 'b>,
    /// The URL rule that matched the request.  This is
    /// going to be `None` if nothing matched.
    pub url_rule: Option<Rule>,
    /// A dict of view arguments that matched the request.
    pub view_args: ViewArgs,
    /// If matching the URL failed, this will be the error.
    pub routing_error: Option<HTTPError>,
    args: Option<MultiDict<String>>,
    form: Option<MultiDict<String>>,
    files: Option<MultiDict<UploadedFile>>,
    cached_json: Option<Option<json::Json>>
}

impl<'r, 'a, 'b: 'a> Request<'r, 'a, 'b> {
    /// Create a `Request`.
    pub fn new(app: &'r Pencil, request: hyper::server::request::Request<'a, 'b>) -> Request<'r, 'a, 'b> {
        Request {
            app: app,
            request: request,
            url_rule: None,
            view_args: HashMap::new(),
            routing_error: None,
            args: None,
            form: None,
            files: None,
            cached_json: None,
        }
    }

    /// Match the request, set the `url_rule` and `view_args` field.
    pub fn match_request(&mut self) {
        match self.path() {
            Some(path) => {
                let url_adapter = self.app.url_map.bind(path, self.method());
                match url_adapter.matched() {
                    Ok(caps) => {
                        let (rule, view_args) = caps;
                        self.url_rule = Some(rule);
                        self.view_args = view_args;
                    },
                    Err(e) => {
                        self.routing_error = Some(e);
                    },
                }
            },
            None => {
                self.routing_error = Some(NotFound);
            }
        }
    }

    /// The endpoint that matched the request.
    pub fn endpoint(&self) -> Option<String> {
        match self.url_rule {
            Some(ref rule) => Some(rule.endpoint.clone()),
            None => None,
        }
    }

    /// The parsed URL parameters.
    pub fn args(&mut self) -> &MultiDict<String> {
        if self.args.is_none() {
            let mut args = MultiDict::new();
            let query_pairs = self.query_string().map(|query| form_urlencoded::parse(query.as_bytes()));
            match query_pairs {
                Some(pairs) => {
                    for (k, v) in pairs {
                        args.add(k, v);
                    }
                },
                None => {},
            }
            self.args = Some(args);
        }
        return self.args.as_ref().unwrap();
    }

    /// Get content type.
    fn content_type(&self) -> Option<ContentType> {
        let content_type: Option<&ContentType> = self.request.headers.get();
        content_type.map(|c| c.clone())
    }

    /// Parses the incoming JSON request data.
    pub fn get_json(&mut self) -> &Option<json::Json> {
        if self.cached_json.is_none() {
            let mut data = String::from("");
            let rv = match self.request.read_to_string(&mut data) {
                Ok(_) => {
                    match json::Json::from_str(&data) {
                        Ok(json) => Some(json),
                        Err(_) => None
                    }
                },
                Err(_) => {
                    None
                }
            };
            self.cached_json = Some(rv);
        }
        return self.cached_json.as_ref().unwrap();
    }

    /// This method is used internally to retrieve submitted data.
    fn load_form_data(&mut self) {
        if self.form.is_some() {
            return
        }
        let (form, files) = match self.content_type() {
            Some(ContentType(mimetype)) => {
                let parser = FormDataParser::new();
                parser.parse(&mut self.request, &mimetype)
            },
            None => {
                (MultiDict::new(), MultiDict::new())
            }
        };
        self.form = Some(form);
        self.files = Some(files);
    }

    /// The form parameters.
    pub fn form(&mut self) -> &MultiDict<String> {
        self.load_form_data();
        self.form.as_ref().unwrap()
    }

    /// All uploaded files.
    pub fn files(&mut self) -> &MultiDict<UploadedFile> {
        self.load_form_data();
        self.files.as_ref().unwrap()
    }

    /// The headers.
    pub fn headers(&self) -> &Headers {
        &self.request.headers
    }

    /// Requested path.
    pub fn path(&self) -> Option<String> {
        match self.request.uri {
            AbsolutePath(ref path) => {
                Some(path.splitn(2, '?').next().unwrap().to_string())
            },
            AbsoluteUri(ref url) => {
                url.serialize_path()
            },
            Authority(_) | Star => None
        }
    }

    /// Requested path including the query string.
    pub fn full_path(&self) -> Option<String> {
        let path = self.path();
        let query_string = self.query_string();
        if path.is_some() && query_string.is_some() {
            return Some(path.unwrap() + "?" + &query_string.unwrap());
        } else  {
            return path;
        }
    }

    /// The host including the port if available.
    pub fn host(&self) -> Option<String> {
        let host: Option<&hyper::header::Host> = self.request.headers.get();
        host.map(|host| get_host_value(host))
    }

    /// The query string.
    pub fn query_string(&self) -> Option<String> {
        match self.request.uri {
            AbsolutePath(ref path) => {
                match UrlParser::new().parse_path(path) {
                    Ok((_, query, _)) => {
                        query
                    },
                    Err(_) => None
                }
            },
            AbsoluteUri(ref url) => {
                url.query.clone()
            },
            Authority(_) | Star => None
        }
    }

    /// The retrieved cookies.
    pub fn cookies(&self) -> Option<&Cookie> {
        self.request.headers.get()
    }

    /// The request method.
    pub fn method(&self) -> String {
        match self.request.method {
            Method::Options => "OPTIONS".to_string(),
            Method::Get => "GET".to_string(),
            Method::Post => "POST".to_string(),
            Method::Put => "PUT".to_string(),
            Method::Delete => "DELETE".to_string(),
            Method::Head => "HEAD".to_string(),
            Method::Trace => "TRACE".to_string(),
            Method::Connect => "CONNECT".to_string(),
            Method::Patch => "PATCH".to_string(),
            Method::Extension(ref method) => method.clone(),
        }
    }

    /// The remote address of the client.
    pub fn remote_addr(&self) -> SocketAddr {
        self.request.remote_addr.clone()
    }

    /// URL scheme (http or https)
    pub fn scheme(&self) -> String {
        match self.request.uri {
            AbsoluteUri(ref url) => {
                return url.scheme.clone();
            },
            _ => {}
        }
        String::from("http")
    }

    /// Just the host with scheme.
    pub fn host_url(&self) -> Option<String> {
        match self.host() {
            Some(host) => {
                Some(self.scheme() + "://" + &host + "/")
            },
            None => None,
        }
    }

    /// The current url.
    pub fn url(&self) -> Option<String> {
        let host_url = self.host_url();
        let full_path = self.full_path();
        if host_url.is_some() && full_path.is_some() {
            Some(host_url.unwrap() + &(full_path.unwrap()).trim_left_matches('/'))
        } else {
            None
        }
    }

    /// The current url without the query string.
    pub fn base_url(&self) -> Option<String> {
        let host_url = self.host_url();
        let path = self.path();
        if host_url.is_some() && path.is_some() {
            Some(host_url.unwrap() + &path.unwrap().trim_left_matches('/'))
        } else {
            None
        }
    }

    /// Whether the request is secure (https).
    pub fn is_secure(&self) -> bool {
        self.scheme() == "https".to_string()
    }
}

impl<'r, 'a, 'b: 'a> fmt::Debug for Request<'r, 'a, 'b> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.url() {
            Some(url) => {
                write!(f, "Pencil Request '{}' {}", url, self.method())
            },
            None => {
                write!(f, "Pencil Request")
            }
        }
    }
}

impl<'r, 'a, 'b: 'a> Read for Request<'r, 'a, 'b> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.request.read(buf)
    }
}

/// Response type.  It is just one container with a couple of parameters
/// (headers, body, status code etc).
#[derive(Clone)]
pub struct Response {
    pub status_code: isize,
    pub headers: Headers,
    pub body: String,
}

impl Response {
    /// Create a `Response`.
    pub fn new(body: String) -> Response {
        let mut response = Response {
            status_code: 200,
            headers: Headers::new(),
            body: body,
        };
        let mime: Mime = "text/html; charset=UTF-8".parse().unwrap();
        let content_type = ContentType(mime);
        let content_length = ContentLength(response.body.len() as u64);
        response.headers.set(content_type);
        response.headers.set(content_length);
        return response;
    }

    /// Get status name.
    pub fn status_name(&self) -> &str {
        match get_name_by_http_code(self.status_code) {
            Some(name) => name,
            None => "UNKNOWN",
        }
    }

    /// Sets a new string as response body.  The content length is set
    /// automatically.
    pub fn set_data(&mut self, value: String) {
        self.body = value;
        let content_length = self.body.len();
        self.set_content_length(content_length);
    }

    /// Returns the response content type if available.
    pub fn content_type(&self) -> Option<&ContentType> {
        self.headers.get()
    }

    /// Set response content type.
    pub fn set_content_type(&mut self, mimetype: &str) {
        let mimetype = get_content_type(mimetype, "UTF-8");
        let mime: Mime = (&mimetype).parse().unwrap();
        let content_type = ContentType(mime);
        self.headers.set(content_type);
    }

    /// Returns the response content length if available.
    pub fn content_length(&self) -> Option<usize> {
        let content_length: Option<&ContentLength> = self.headers.get();
        match content_length {
            Some(&ContentLength(length)) => Some(length as usize),
            None => None,
        }
    }

    /// Set content length.
    pub fn set_content_length(&mut self, value: usize) {
        let content_length = ContentLength(value as u64);
        self.headers.set(content_length);
    }

    /// Sets a cookie(TODO).
    pub fn set_cookie(&mut self) {
    }

    /// Delete a cookie(TODO).
    pub fn delete_cookie(&mut self) {
    }

    /// Return `true` if the response is streamed(currently we do not support
    /// streaming yet, always return `false`).
    pub fn is_streamed(&self) -> bool {
        false
    }

    /// Write the response out.  Mostly you shouldn't use this directly.
    pub fn write(self, request_method: String, mut res: hyper::server::Response) {
        // write status.
        let status_code = self.status_code;
        *res.status_mut() = get_status_from_code(status_code);

        // write headers.
        *res.headers_mut() = self.headers;

        // write data.
        if request_method == String::from("HEAD") ||
           (100 <= status_code && status_code < 200) ||
           status_code == 204 || status_code == 304 {
            res.headers_mut().set(ContentLength(0));
            try_return!(res.start().and_then(|w| w.end()));
        } else {
            let mut res = try_return!(res.start());
            try_return!(res.write_all(self.body.as_bytes()));
            try_return!(res.end());
        }
    }
}
<|endoftext|>


<commit_before>use {Field, Value, Borrowed, Matrix2d, Color};
use vecmath::{multiply, translate, rotate_radians, scale, shear};
use {Transform2d};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> Transform2d<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}
<commit_msg>Implemented Fill for PolygonColorContext<commit_after>use {Field, Value, Borrowed, Matrix2d, Color};
use vecmath::{multiply, translate, rotate_radians, scale, shear};
use {Transform2d, Fill, BackEnd};
use triangulation::{with_polygon_tri_list_xy_rgba_f32};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> Transform2d<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for PolygonColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_rgba_f32() {
            let polygon = self.polygon.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_polygon_tri_list_xy_rgba_f32(
                self.transform.get(),
                *polygon,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}
<|endoftext|>