<commit_before>//! Define trait for general matrix

use std::cmp::min;
use std::fmt::Debug;
use ndarray::prelude::*;
use ndarray::LinalgScalar;
use lapack::c::Layout;

use error::LapackError;
use qr::ImplQR;
use svd::ImplSVD;
use norm::ImplNorm;
use solve::ImplSolve;

/// Methods for general matrices
pub trait Matrix: Sized {
    type Scalar;
    type Vector;
    type Permutator;
    /// number of (rows, columns)
    fn size(&self) -> (usize, usize);
    /// Layout (C/Fortran) of matrix
    fn layout(&self) -> Layout;
    /// Operator norm for L-1 norm
    fn norm_1(&self) -> Self::Scalar;
    /// Operator norm for L-inf norm
    fn norm_i(&self) -> Self::Scalar;
    /// Frobenius norm
    fn norm_f(&self) -> Self::Scalar;
    /// singular-value decomposition (SVD)
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError>;
    /// QR decomposition
    fn qr(self) -> Result<(Self, Self), LapackError>;
    /// LU decomposition
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError>;
    /// permutate matrix (inplace)
    fn permutate(&mut self, p: &Self::Permutator);
    /// permutate matrix (outplace)
    fn permutated(mut self, p: &Self::Permutator) -> Self {
        self.permutate(p);
        self
    }
}

impl<A> Matrix for Array<A, Ix2>
    where A: ImplQR + ImplSVD + ImplNorm + ImplSolve + LinalgScalar + Debug
{
    type Scalar = A;
    type Vector = Array<A, Ix>;
    type Permutator = Vec<i32>;

    fn size(&self) -> (usize, usize) {
        (self.rows(), self.cols())
    }
    fn layout(&self) -> Layout {
        let strides = self.strides();
        if strides[0] < strides[1] {
            Layout::ColumnMajor
        } else {
            Layout::RowMajor
        }
    }
    fn norm_1(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_i(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_1(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_i(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_1(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_i(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_f(&self) -> Self::Scalar {
        let (m, n) = self.size();
        ImplNorm::norm_f(m, n, self.clone().into_raw_vec())
    }
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError> {
        let strides = self.strides();
        let (m, n) = if strides[0] > strides[1] {
            self.size()
        } else {
            let (n, m) = self.size();
            (m, n)
        };
        let (u, s, vt) = try!(ImplSVD::svd(m, n, self.clone().into_raw_vec()));
        let sv = Array::from_vec(s);
        if strides[0] > strides[1] {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap();
            Ok((va, sv, ua))
        } else {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap().reversed_axes();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap().reversed_axes();
            Ok((ua, sv, va))
        }
    }
    fn qr(self) -> Result<(Self, Self), LapackError> {
        let (n, m) = self.size();
        let strides = self.strides();
        let k = min(n, m);
        let (q, r) = if strides[0] < strides[1] {
            try!(ImplQR::qr(m, n, self.clone().into_raw_vec()))
        } else {
            try!(ImplQR::lq(n, m, self.clone().into_raw_vec()))
        };
        let (qa, ra) = if strides[0] < strides[1] {
            (Array::from_vec(q).into_shape((m, n)).unwrap().reversed_axes(),
             Array::from_vec(r).into_shape((m, n)).unwrap().reversed_axes())
        } else {
            (Array::from_vec(q).into_shape((n, m)).unwrap(),
             Array::from_vec(r).into_shape((n, m)).unwrap())
        };
        let qm = if m > k {
            let (qsl, _) = qa.view().split_at(Axis(1), k);
            qsl.to_owned()
        } else {
            qa
        };
        let mut rm = if n > k {
            let (rsl, _) = ra.view().split_at(Axis(0), k);
            rsl.to_owned()
        } else {
            ra
        };
        for ((i, j), val) in rm.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok((qm, rm))
    }
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError> {
        let (n, m) = self.size();
        println!("n={}, m={}", n, m);
        let k = min(n, m);
        let (p, mut a) = match self.layout() {
            Layout::ColumnMajor => {
                println!("ColumnMajor");
                let (p, l) = ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec())?;
                (p, Array::from_vec(l).into_shape((m, n)).unwrap().reversed_axes())
            }
            Layout::RowMajor => {
                println!("RowMajor");
                let (p, l) = ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec())?;
                (p, Array::from_vec(l).into_shape((n, m)).unwrap())
            }
        };
        println!("a (after LU) = \n{:?}", &a);
        let mut lm = Array::zeros((n, k));
        for ((i, j), val) in lm.indexed_iter_mut() {
            if i > j {
                *val = a[(i, j)];
            } else if i == j {
                *val = A::one();
            }
        }
        for ((i, j), val) in a.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        let am = if n > k {
            a.slice(s![0..k as isize, ..]).to_owned()
        } else {
            a
        };
        println!("am = \n{:?}", am);
        Ok((p, lm, am))
    }
    fn permutate(&mut self, ipiv: &Self::Permutator) {
        let (_, m) = self.size();
        for (i, j_) in ipiv.iter().enumerate().rev() {
            let j = (j_ - 1) as usize;
            if i == j {
                continue;
            }
            for k in 0..m {
                self.swap((i, k), (j, k));
            }
        }
    }
}
<commit_msg>Bug fixed<commit_after>//! Define trait for general matrix

use std::cmp::min;
use std::fmt::Debug;
use ndarray::prelude::*;
use ndarray::LinalgScalar;
use lapack::c::Layout;

use error::LapackError;
use qr::ImplQR;
use svd::ImplSVD;
use norm::ImplNorm;
use solve::ImplSolve;

/// Methods for general matrices
pub trait Matrix: Sized {
    type Scalar;
    type Vector;
    type Permutator;
    /// number of (rows, columns)
    fn size(&self) -> (usize, usize);
    /// Layout (C/Fortran) of matrix
    fn layout(&self) -> Layout;
    /// Operator norm for L-1 norm
    fn norm_1(&self) -> Self::Scalar;
    /// Operator norm for L-inf norm
    fn norm_i(&self) -> Self::Scalar;
    /// Frobenius norm
    fn norm_f(&self) -> Self::Scalar;
    /// singular-value decomposition (SVD)
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError>;
    /// QR decomposition
    fn qr(self) -> Result<(Self, Self), LapackError>;
    /// LU decomposition
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError>;
    /// permutate matrix (inplace)
    fn permutate(&mut self, p: &Self::Permutator);
    /// permutate matrix (outplace)
    fn permutated(mut self, p: &Self::Permutator) -> Self {
        self.permutate(p);
        self
    }
}

impl<A> Matrix for Array<A, Ix2>
    where A: ImplQR + ImplSVD + ImplNorm + ImplSolve + LinalgScalar + Debug
{
    type Scalar = A;
    type Vector = Array<A, Ix1>;
    type Permutator = Vec<i32>;

    fn size(&self) -> (usize, usize) {
        (self.rows(), self.cols())
    }
    fn layout(&self) -> Layout {
        let strides = self.strides();
        if strides[0] < strides[1] {
            Layout::ColumnMajor
        } else {
            Layout::RowMajor
        }
    }
    fn norm_1(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_i(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_1(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_i(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_1(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_i(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_f(&self) -> Self::Scalar {
        let (m, n) = self.size();
        ImplNorm::norm_f(m, n, self.clone().into_raw_vec())
    }
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError> {
        let strides = self.strides();
        let (m, n) = if strides[0] > strides[1] {
            self.size()
        } else {
            let (n, m) = self.size();
            (m, n)
        };
        let (u, s, vt) = try!(ImplSVD::svd(m, n, self.clone().into_raw_vec()));
        let sv = Array::from_vec(s);
        if strides[0] > strides[1] {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap();
            Ok((va, sv, ua))
        } else {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap().reversed_axes();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap().reversed_axes();
            Ok((ua, sv, va))
        }
    }
    fn qr(self) -> Result<(Self, Self), LapackError> {
        let (n, m) = self.size();
        let strides = self.strides();
        let k = min(n, m);
        let (q, r) = if strides[0] < strides[1] {
            try!(ImplQR::qr(m, n, self.clone().into_raw_vec()))
        } else {
            try!(ImplQR::lq(n, m, self.clone().into_raw_vec()))
        };
        let (qa, ra) = if strides[0] < strides[1] {
            (Array::from_vec(q).into_shape((m, n)).unwrap().reversed_axes(),
             Array::from_vec(r).into_shape((m, n)).unwrap().reversed_axes())
        } else {
            (Array::from_vec(q).into_shape((n, m)).unwrap(),
             Array::from_vec(r).into_shape((n, m)).unwrap())
        };
        let qm = if m > k {
            let (qsl, _) = qa.view().split_at(Axis(1), k);
            qsl.to_owned()
        } else {
            qa
        };
        let mut rm = if n > k {
            let (rsl, _) = ra.view().split_at(Axis(0), k);
            rsl.to_owned()
        } else {
            ra
        };
        for ((i, j), val) in rm.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok((qm, rm))
    }
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError> {
        let (n, m) = self.size();
        println!("n={}, m={}", n, m);
        let k = min(n, m);
        let (p, mut a) = match self.layout() {
            Layout::ColumnMajor => {
                println!("ColumnMajor");
                let (p, l) = ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec())?;
                (p, Array::from_vec(l).into_shape((m, n)).unwrap().reversed_axes())
            }
            Layout::RowMajor => {
                println!("RowMajor");
                let (p, l) = ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec())?;
                (p, Array::from_vec(l).into_shape((n, m)).unwrap())
            }
        };
        println!("a (after LU) = \n{:?}", &a);
        let mut lm = Array::zeros((n, k));
        for ((i, j), val) in lm.indexed_iter_mut() {
            if i > j {
                *val = a[(i, j)];
            } else if i == j {
                *val = A::one();
            }
        }
        for ((i, j), val) in a.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        let am = if n > k {
            a.slice(s![0..k as isize, ..]).to_owned()
        } else {
            a
        };
        println!("am = \n{:?}", am);
        Ok((p, lm, am))
    }
    fn permutate(&mut self, ipiv: &Self::Permutator) {
        let (_, m) = self.size();
        for (i, j_) in ipiv.iter().enumerate().rev() {
            let j = (j_ - 1) as usize;
            if i == j {
                continue;
            }
            for k in 0..m {
                self.swap((i, k), (j, k));
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Number theory

extern crate core;
extern crate num;

use core::num::Zero;
use core::num::One;
use num::Integer;
use core::fmt;
use core::fmt::Show;

/// A modular integer type
pub struct ModInt<T> {
    value : T,
    modulus : T
}

impl<T: Integer> ModInt<T> {
    /// Construct a new modular integer with given value and modulus
    pub fn new(v : T, m : T) -> ModInt<T> {
        let r=v%m;
        if r >= Zero::zero() {
            ModInt {value : r, modulus : m}
        } else {
            ModInt {value : r + m, modulus : m}
        }
    }

    /// Construct a new modular integer with given value and modulus
    ///
    /// Doesn't normalize v to the range [0,m).
    pub fn new_nocheck(v : T, m : T) -> ModInt<T> {
        ModInt {value : v, modulus : m}
    }
}

impl<T: Show> Show for ModInt<T> {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} (mod {})", self.value, self.modulus)
    }
}

impl<T: Clone + Integer> Add<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn add(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value + other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer> Sub<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn sub(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value - other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer> Mul<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn mul(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value * other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer + Show> Div<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn div(&self, other : &ModInt<T>) -> ModInt<T> {
        let inv = mod_inverse(other.value.clone(), self.modulus.clone());
        match inv {
            Some(i) => ModInt::new_nocheck(self.value * i % self.modulus, self.modulus.clone()),
            None    => fail!("{} is not a unit (mod {})", other.value, self.modulus)
        }
    }
}

/// For given integers `a` and `b` returns three integers `(x, y, g)` that satisfy ax + by = g and g=gcd(a,b).
pub fn bezout<T: Integer + Clone>(a : T, b : T) -> (T, T, T) {
    if a == Zero::zero() {
        return (Zero::zero(), One::one(), b);
    }
    if b <= a {
        return bezout(b, a);
    }
    let (x, y, g) = bezout(b%a, a.clone());
    return (y - (b/a)*x, x, g);
}

/// For integers `a` and `m` computes an integer `x` such that ax = 1 (mod m), if such an integer exists.
pub fn mod_inverse<T: Integer + Clone>(a : T, m : T) -> Option<T> {
    let (x,_,g) = bezout(a, m);
    if g == One::one() {
        Some(x)
    } else {
        None
    }
}

<commit_msg>Fixed and added stuff.<commit_after>//! Number theory

extern crate core;
extern crate num;

use core::num::Zero;
use core::num::One;
use num::Integer;
use core::fmt;
use core::fmt::Show;

/// A modular integer type
pub struct ModInt<T> {
    value : T,
    modulus : T
}

impl<T: Integer> ModInt<T> {
    /// Construct a new modular integer with given value and modulus
    pub fn new(v : T, m : T) -> ModInt<T> {
        let r=v%m;
        if r >= Zero::zero() {
            ModInt {value : r, modulus : m}
        } else {
            ModInt {value : r + m, modulus : m}
        }
    }

    /// Construct a new modular integer with given value and modulus
    ///
    /// Doesn't normalize v to the range [0,m).
    pub fn new_nocheck(v : T, m : T) -> ModInt<T> {
        ModInt {value : v, modulus : m}
    }
}

impl<T: Show> Show for ModInt<T> {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} (mod {})", self.value, self.modulus)
    }
}

impl<T: Clone + Integer> Add<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn add(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value + other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer> Sub<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn sub(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value - other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer> Mul<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn mul(&self, other : &ModInt<T>) -> ModInt<T> {
        ModInt::new_nocheck((self.value * other.value) % self.modulus, self.modulus.clone())
    }
}

impl<T: Clone + Integer> ModInt<T> {
    /// Calculates `self` to the power `exp`.
    pub fn pow(&self, mut exp : uint) -> ModInt<T> {
        let mut base = ModInt::new(self.value.clone(), self.modulus.clone());
        if exp == 1 {
            base
        } else {
            let mut acc = ModInt::new(One::one(), self.modulus.clone());
            while exp > 0 {
                if (exp & 1) == 1 {
                    acc = acc * base;
                }
                base = base*base;
                exp = exp >> 1;
            }
            acc
        }
    }
}

impl<T: Clone> Clone for ModInt<T> {
    fn clone(&self) -> ModInt<T> {
        ModInt{value: self.value.clone(), modulus: self.modulus.clone()}
    }
}

impl<T: Clone + Integer + Show> Div<ModInt<T>,ModInt<T>> for ModInt<T> {
    fn div(&self, other : &ModInt<T>) -> ModInt<T> {
        let inv = mod_inverse(other.value.clone(), self.modulus.clone());
        match inv {
            Some(i) => ModInt::new(self.value * i % self.modulus, self.modulus.clone()),
            None    => fail!("{} is not a unit (mod {})", other.value, self.modulus)
        }
    }
}

impl<T: PartialEq> PartialEq for ModInt<T> {
    fn eq(&self, other: &ModInt<T>) -> bool {
        self.value == other.value && self.modulus == other.modulus
    }
}

/// For given integers `a` and `b` returns three integers `(x, y, g)` that satisfy ax + by = g and g=gcd(a,b).
pub fn bezout<T: Integer + Clone>(a : T, b : T) -> (T, T, T) {
    if a == Zero::zero() {
        return (Zero::zero(), One::one(), b);
    }
    if b <= a {
        return bezout(b, a);
    }
    let (x, y, g) = bezout(b%a, a.clone());
    //x*(b - [b/a]a) + y*a == g
    //(y - (b/a)*x)*a + x*b == g
    return (y - (b/a)*x, x, g);
}

/// For integers `a` and `m` computes an integer `x` such that ax = 1 (mod m), if such an integer exists.
pub fn mod_inverse<T: Integer + Clone>(a : T, m : T) -> Option<T> {
    let (x,_,g) = bezout(a, m.clone());
    if g == One::one() {
        Some(x%m)
    } else {
        None
    }
}

<|endoftext|>


<commit_before>pub mod learning;

use rand;
use rand::Rng;
use rand::distributions::normal::StandardNormal;
use na::{DMatrix, DVector, IterableMut};

/// Artificial Neural Network
///
/// This struct represents a simple Artificial Neural Network (ANN) using
/// feedforward and backpropagation. It uses Stochastic Gradient Descent(SGD)
/// and a sigmoid activation function.
///
/// [Source](http://neuralnetworksanddeeplearning.com/chap1.html)
///
/// # Example
///
/// ```rust
/// // This will create a new ANN with the following topology:
/// // 3 "neurons" in the input layer
/// // 5 "neurons" in the first hidden layer
/// // 3 "neurons" in the second hidden layer
/// // 2 "neurons" in the output layer
/// let nnet = Network::new(vec![3, 5, 2]);
/// ```
#[derive(Debug, Clone)]
pub struct Network {
    /// a Vec outlining the topology of the ANN
    /// the first entry corresponds to the inputlayer,
    /// the intermediate entries correspond to the hidden layers
    /// and the last entry corresponds to the outputlayer.
    layers: Vec<u8>,
    /// a Vec that contains the weights of the respective layer
    weights: Vec<DMatrix<f32>>,
    /// a Vec cointaining the biases of the respective layer
    biases: Vec<DVector<f32>>,
}

impl Network {
    /// build a new Network with a topology Vector
    pub fn new(sizes: Vec<u8>) -> Result<Network, &'static str> {
        assert!(sizes.len() >= 3, "at least three layers required");

        // Store the weights and biases in lists
        // We will not need weights or biases for input layer, so ignore that (hence -1)
        let mut weights = Vec::with_capacity(sizes.len() - 1);
        let mut biases = Vec::with_capacity(sizes.len() - 1);

        let mut rng = rand::thread_rng();

        // we use the standard normal distribution to initialize weights and biases - why?
        for (i, layer) in sizes.iter().enumerate().skip(1) {
            // initialize weight matrices
            weights.push(DMatrix::from_fn(*layer as usize, sizes[i - 1] as usize, |_, _| {
                let StandardNormal(x) = rng.gen();
                x as f32
            }));

            // initialize biases
            biases.push(DVector::from_fn(*layer as usize, |_| {
                let StandardNormal(x) = rng.gen();
                x as f32
            }));
        }

        Ok(Network {
            layers: sizes,
            weights: weights,
            biases: biases,
        })
    }

    /// Feed input through network, return output layer activation level
    pub fn feedforward(&self, a: &DVector<f32>) -> DVector<f32> {
        let mut act = a.clone();
        for (weight, bias) in self.weights.iter().zip(self.biases.clone().into_iter()) {
            act = sigmoid(&(weight * act + bias));
        }
        act
    }

    /// return the layers used to initialize the ANN
    pub fn get_layers(&self) -> &[u8] {
        &self.layers
    }

    /// return a vector of the weight matrices of the ANN
    pub fn get_weights(&self) -> &[DMatrix<f32>] {
        &self.weights
    }

    /// return a mutable vector of the weight matrices of the ANN
    pub fn get_weights_mut(&mut self) -> &mut Vec<DMatrix<f32>> {
        &mut self.weights
    }

    /// return a vector of the bias matrices of the ANN
    pub fn get_biases(&self) -> &[DVector<f32>] {
        &self.biases
    }

    /// return a vector of the bias matrices of the ANN
    pub fn get_biases_mut(&mut self) -> &mut Vec<DVector<f32>> {
        &mut self.biases
    }
}

// calculate elementwise sigmoid function
pub fn sigmoid(arr: &DVector<f32>) -> DVector<f32> {
    let mut sig = arr.clone();
    for elem in sig.iter_mut() {
        *elem = 1.0 / (1.0 + (elem).exp());
    }
    sig
}

#[test]
fn test_sigmoid() {
    let mut arr_orig = DVector::from_element(3, 1.0f32);
    arr_orig[2] = 2.4137;
    let arr = sigmoid(arr_orig);
    assert_eq!(arr[0], arr[1]);
    assert_eq!(arr[0], 0.26894142137f32);
    assert_eq!(0.082133951f32, arr[2]);
}
<commit_msg>Fixed test method<commit_after>pub mod learning;

use rand;
use rand::Rng;
use rand::distributions::normal::StandardNormal;
use na::{DMatrix, DVector, IterableMut};

/// Artificial Neural Network
///
/// This struct represents a simple Artificial Neural Network (ANN) using
/// feedforward and backpropagation. It uses Stochastic Gradient Descent(SGD)
/// and a sigmoid activation function.
///
/// [Source](http://neuralnetworksanddeeplearning.com/chap1.html)
///
/// # Example
///
/// ```rust
/// // This will create a new ANN with the following topology:
/// // 3 "neurons" in the input layer
/// // 5 "neurons" in the first hidden layer
/// // 3 "neurons" in the second hidden layer
/// // 2 "neurons" in the output layer
/// let nnet = Network::new(vec![3, 5, 2]);
/// ```
#[derive(Debug, Clone)]
pub struct Network {
    /// a Vec outlining the topology of the ANN
    /// the first entry corresponds to the inputlayer,
    /// the intermediate entries correspond to the hidden layers
    /// and the last entry corresponds to the outputlayer.
    layers: Vec<u8>,
    /// a Vec that contains the weights of the respective layer
    weights: Vec<DMatrix<f32>>,
    /// a Vec cointaining the biases of the respective layer
    biases: Vec<DVector<f32>>,
}

impl Network {
    /// build a new Network with a topology Vector
    pub fn new(sizes: Vec<u8>) -> Result<Network, &'static str> {
        assert!(sizes.len() >= 3, "at least three layers required");

        // Store the weights and biases in lists
        // We will not need weights or biases for input layer, so ignore that (hence -1)
        let mut weights = Vec::with_capacity(sizes.len() - 1);
        let mut biases = Vec::with_capacity(sizes.len() - 1);

        let mut rng = rand::thread_rng();

        // we use the standard normal distribution to initialize weights and biases - why?
        for (i, layer) in sizes.iter().enumerate().skip(1) {
            // initialize weight matrices
            weights.push(DMatrix::from_fn(*layer as usize, sizes[i - 1] as usize, |_, _| {
                let StandardNormal(x) = rng.gen();
                x as f32
            }));

            // initialize biases
            biases.push(DVector::from_fn(*layer as usize, |_| {
                let StandardNormal(x) = rng.gen();
                x as f32
            }));
        }

        Ok(Network {
            layers: sizes,
            weights: weights,
            biases: biases,
        })
    }

    /// Feed input through network, return output layer activation level
    pub fn feedforward(&self, a: &DVector<f32>) -> DVector<f32> {
        let mut act = a.clone();
        for (weight, bias) in self.weights.iter().zip(self.biases.clone().into_iter()) {
            act = sigmoid(&(weight * act + bias));
        }
        act
    }

    /// return the layers used to initialize the ANN
    pub fn get_layers(&self) -> &[u8] {
        &self.layers
    }

    /// return a vector of the weight matrices of the ANN
    pub fn get_weights(&self) -> &[DMatrix<f32>] {
        &self.weights
    }

    /// return a mutable vector of the weight matrices of the ANN
    pub fn get_weights_mut(&mut self) -> &mut Vec<DMatrix<f32>> {
        &mut self.weights
    }

    /// return a vector of the bias matrices of the ANN
    pub fn get_biases(&self) -> &[DVector<f32>] {
        &self.biases
    }

    /// return a vector of the bias matrices of the ANN
    pub fn get_biases_mut(&mut self) -> &mut Vec<DVector<f32>> {
        &mut self.biases
    }
}

// calculate elementwise sigmoid function
pub fn sigmoid(arr: &DVector<f32>) -> DVector<f32> {
    let mut sig = arr.clone();
    for elem in sig.iter_mut() {
        *elem = 1.0 / (1.0 + (elem).exp());
    }
    sig
}

#[test]
fn test_sigmoid() {
    let mut arr_orig = DVector::from_element(3, 1.0f32);
    arr_orig[2] = 2.4137;
    let arr = sigmoid(&arr_orig);
    assert_eq!(arr[0], arr[1]);
    assert_eq!(arr[0], 0.26894142137f32);
    assert_eq!(0.082133951f32, arr[2]);
}
<|endoftext|>


<commit_before>use std::cmp::max;
use std::iter::{AdditiveIterator, repeat};

use column::{Column, Cell};
use column::Alignment::Left;
use dir::Dir;
use file::{File, GREY};
use options::{Columns, FileFilter};
use users::OSUsers;

use ansi_term::Style::Plain;

#[derive(PartialEq, Copy, Debug)]
pub enum View {
    Details(Columns, bool, bool),
    Lines,
    Grid(bool, usize),
}

impl View {
    pub fn view(&self, dir: Option<&Dir>, files: &[File], filter: FileFilter) {
        match *self {
            View::Grid(across, width)       => grid_view(across, width, files),
            View::Details(ref cols, header, tree) => details_view(&*cols.for_dir(dir), files, header, tree, filter),
            View::Lines                     => lines_view(files),
        }
    }
}

/// The lines view literally just displays each file, line-by-line.
fn lines_view(files: &[File]) {
    for file in files.iter() {
        println!("{}", file.file_name_view());
    }
}

fn fit_into_grid(across: bool, console_width: usize, files: &[File]) -> Option<(usize, Vec<usize>)> {
    // TODO: this function could almost certainly be optimised...
    // surely not *all* of the numbers of lines are worth searching through!

    // Instead of numbers of columns, try to find the fewest number of *lines*
    // that the output will fit in.
    for num_lines in range(1, files.len()) {

        // The number of columns is the number of files divided by the number
        // of lines, *rounded up*.
        let mut num_columns = files.len() / num_lines;
        if files.len() % num_lines != 0 {
            num_columns += 1;
        }

        // Early abort: if there are so many columns that the width of the
        // *column separators* is bigger than the width of the screen, then
        // don't even try to tabulate it.
        // This is actually a necessary check, because the width is stored as
        // a usize, and making it go negative makes it huge instead, but it
        // also serves as a speed-up.
        let separator_width = (num_columns - 1) * 2;
        if console_width < separator_width {
            continue;
        }

        // Remove the separator width from the available space.
        let adjusted_width = console_width - separator_width;

        // Find the width of each column by adding the lengths of the file
        // names in that column up.
        let mut column_widths: Vec<usize> = repeat(0).take(num_columns).collect();
        for (index, file) in files.iter().enumerate() {
            let index = if across {
                index % num_columns
            }
            else {
                index / num_lines
            };
            column_widths[index] = max(column_widths[index], file.name.len());
        }

        // If they all fit in the terminal, combined, then success!
        if column_widths.iter().map(|&x| x).sum() < adjusted_width {
            return Some((num_lines, column_widths));
        }
    }

    // If you get here you have really long file names.
    return None;
}

fn grid_view(across: bool, console_width: usize, files: &[File]) {
    if let Some((num_lines, widths)) = fit_into_grid(across, console_width, files) {
        for y in range(0, num_lines) {
            for x in range(0, widths.len()) {
                let num = if across {
                    y * widths.len() + x
                }
                else {
                    y + num_lines * x
                };

                // Show whitespace in the place of trailing files
                if num >= files.len() {
                    continue;
                }

                let ref file = files[num];
                let styled_name = file.file_colour().paint(file.name.as_slice()).to_string();
                if x == widths.len() - 1 {
                    // The final column doesn't need to have trailing spaces
                    print!("{}", styled_name);
                }
                else {
                    assert!(widths[x] >= file.name.len());
                    print!("{}", Left.pad_string(&styled_name, widths[x] - file.name.len() + 2));
                }
            }
            print!("\n");
        }
    }
    else {
        // Drop down to lines view if the file names are too big for a grid
        lines_view(files);
    }
}

fn details_view(columns: &[Column], files: &[File], header: bool, tree: bool, filter: FileFilter) {
    // The output gets formatted into columns, which looks nicer. To
    // do this, we have to write the results into a table, instead of
    // displaying each file immediately, then calculating the maximum
    // width of each column based on the length of the results and
    // padding the fields during output.

    let mut cache = OSUsers::empty_cache();

    let mut table = Vec::new();
    get_files(columns, &mut cache, tree, &mut table, files, 0, filter);

    if header {
        let row = Row {
            depth: 0,
            cells: columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name: Plain.underline().paint("Name").to_string(),
            last: false,
            children: false,
        };

        table.insert(0, row);
    }

    let column_widths: Vec<usize> = range(0, columns.len())
        .map(|n| table.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
        .collect();

    let mut stack = Vec::new();

    for row in table.iter() {
        for (num, column) in columns.iter().enumerate() {
            let padding = column_widths[num] - row.cells[num].length;
            print!("{} ", column.alignment().pad_string(&row.cells[num].text, padding));
        }

        if tree {
            stack.resize(row.depth  + 1, "├──");
            stack[row.depth ] = if row.last { "└──" } else { "├──" };

            for i in range(1, row.depth + 1) {
                print!("{}", GREY.paint(stack[i ]));
            }

            if row.children {
                stack[row.depth ] = if row.last { "   " } else { "│  " };
            }

            if row.depth != 0 {
                print!(" ");
            }
        }

        print!("{}\n", row.name);
    }
}

fn get_files(columns: &[Column], cache: &mut OSUsers, recurse: bool, dest: &mut Vec<Row>, src: &[File], depth: usize, filter: FileFilter) {
    for (index, file) in src.iter().enumerate() {

        let row = Row {
            depth: depth,
            cells: columns.iter().map(|c| file.display(c, cache)).collect(),
            name:  file.file_name_view(),
            last: index == src.len() - 1,
            children: file.this.is_some(),
        };

        dest.push(row);

        if recurse {
            if let Some(ref dir) = file.this {
                let mut files = dir.files(true);
                filter.transform_files(&mut files);
                get_files(columns, cache, recurse, dest, files.as_slice(), depth + 1, filter);
            }
        }
    }
}

struct Row {
    pub depth: usize,
    pub cells: Vec<Cell>,
    pub name: String,
    pub last: bool,
    pub children: bool,
}
<commit_msg>Use the new IntoIterator trait<commit_after>use std::cmp::max;
use std::iter::{AdditiveIterator, repeat};

use column::{Column, Cell};
use column::Alignment::Left;
use dir::Dir;
use file::{File, GREY};
use options::{Columns, FileFilter};
use users::OSUsers;

use ansi_term::Style::Plain;

#[derive(PartialEq, Copy, Debug)]
pub enum View {
    Details(Columns, bool, bool),
    Lines,
    Grid(bool, usize),
}

impl View {
    pub fn view(&self, dir: Option<&Dir>, files: &[File], filter: FileFilter) {
        match *self {
            View::Grid(across, width)       => grid_view(across, width, files),
            View::Details(ref cols, header, tree) => details_view(&*cols.for_dir(dir), files, header, tree, filter),
            View::Lines                     => lines_view(files),
        }
    }
}

/// The lines view literally just displays each file, line-by-line.
fn lines_view(files: &[File]) {
    for file in files {
        println!("{}", file.file_name_view());
    }
}

fn fit_into_grid(across: bool, console_width: usize, files: &[File]) -> Option<(usize, Vec<usize>)> {
    // TODO: this function could almost certainly be optimised...
    // surely not *all* of the numbers of lines are worth searching through!

    // Instead of numbers of columns, try to find the fewest number of *lines*
    // that the output will fit in.
    for num_lines in 1 .. files.len() {

        // The number of columns is the number of files divided by the number
        // of lines, *rounded up*.
        let mut num_columns = files.len() / num_lines;
        if files.len() % num_lines != 0 {
            num_columns += 1;
        }

        // Early abort: if there are so many columns that the width of the
        // *column separators* is bigger than the width of the screen, then
        // don't even try to tabulate it.
        // This is actually a necessary check, because the width is stored as
        // a usize, and making it go negative makes it huge instead, but it
        // also serves as a speed-up.
        let separator_width = (num_columns - 1) * 2;
        if console_width < separator_width {
            continue;
        }

        // Remove the separator width from the available space.
        let adjusted_width = console_width - separator_width;

        // Find the width of each column by adding the lengths of the file
        // names in that column up.
        let mut column_widths: Vec<usize> = repeat(0).take(num_columns).collect();
        for (index, file) in files.iter().enumerate() {
            let index = if across {
                index % num_columns
            }
            else {
                index / num_lines
            };
            column_widths[index] = max(column_widths[index], file.name.len());
        }

        // If they all fit in the terminal, combined, then success!
        if column_widths.iter().map(|&x| x).sum() < adjusted_width {
            return Some((num_lines, column_widths));
        }
    }

    // If you get here you have really long file names.
    return None;
}

fn grid_view(across: bool, console_width: usize, files: &[File]) {
    if let Some((num_lines, widths)) = fit_into_grid(across, console_width, files) {
        for y in 0 .. num_lines {
            for x in 0 .. widths.len() {
                let num = if across {
                    y * widths.len() + x
                }
                else {
                    y + num_lines * x
                };

                // Show whitespace in the place of trailing files
                if num >= files.len() {
                    continue;
                }

                let ref file = files[num];
                let styled_name = file.file_colour().paint(file.name.as_slice()).to_string();
                if x == widths.len() - 1 {
                    // The final column doesn't need to have trailing spaces
                    print!("{}", styled_name);
                }
                else {
                    assert!(widths[x] >= file.name.len());
                    print!("{}", Left.pad_string(&styled_name, widths[x] - file.name.len() + 2));
                }
            }
            print!("\n");
        }
    }
    else {
        // Drop down to lines view if the file names are too big for a grid
        lines_view(files);
    }
}

fn details_view(columns: &[Column], files: &[File], header: bool, tree: bool, filter: FileFilter) {
    // The output gets formatted into columns, which looks nicer. To
    // do this, we have to write the results into a table, instead of
    // displaying each file immediately, then calculating the maximum
    // width of each column based on the length of the results and
    // padding the fields during output.

    let mut cache = OSUsers::empty_cache();

    let mut table = Vec::new();
    get_files(columns, &mut cache, tree, &mut table, files, 0, filter);

    if header {
        let row = Row {
            depth: 0,
            cells: columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name: Plain.underline().paint("Name").to_string(),
            last: false,
            children: false,
        };

        table.insert(0, row);
    }

    let column_widths: Vec<usize> = range(0, columns.len())
        .map(|n| table.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
        .collect();

    let mut stack = Vec::new();

    for row in table {
        for (num, column) in columns.iter().enumerate() {
            let padding = column_widths[num] - row.cells[num].length;
            print!("{} ", column.alignment().pad_string(&row.cells[num].text, padding));
        }

        if tree {
            stack.resize(row.depth  + 1, "├──");
            stack[row.depth ] = if row.last { "└──" } else { "├──" };

            for i in 1 .. row.depth + 1 {
                print!("{}", GREY.paint(stack[i ]));
            }

            if row.children {
                stack[row.depth ] = if row.last { "   " } else { "│  " };
            }

            if row.depth != 0 {
                print!(" ");
            }
        }

        print!("{}\n", row.name);
    }
}

fn get_files(columns: &[Column], cache: &mut OSUsers, recurse: bool, dest: &mut Vec<Row>, src: &[File], depth: usize, filter: FileFilter) {
    for (index, file) in src.iter().enumerate() {

        let row = Row {
            depth: depth,
            cells: columns.iter().map(|c| file.display(c, cache)).collect(),
            name:  file.file_name_view(),
            last: index == src.len() - 1,
            children: file.this.is_some(),
        };

        dest.push(row);

        if recurse {
            if let Some(ref dir) = file.this {
                let mut files = dir.files(true);
                filter.transform_files(&mut files);
                get_files(columns, cache, recurse, dest, files.as_slice(), depth + 1, filter);
            }
        }
    }
}

struct Row {
    pub depth: usize,
    pub cells: Vec<Cell>,
    pub name: String,
    pub last: bool,
    pub children: bool,
}
<|endoftext|>


<commit_before>use tokenizer::Tokenizer;
use event::{Event, Rule};
use variable_mapper::VariableMapper;

pub fn nested<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    nested_inner(&mut vm, &mut parents)
}

pub fn nested_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
       match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = nested_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&nested_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                current.push_str(&format!("{} ", name));
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!("{{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }\n"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }");
                    },
                    (0, _) => {
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n  ");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children.split('\n').collect::<Vec<_>>().connect("\n  "));
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn compressed<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compressed_inner(&mut vm, &mut parents)
}

fn compressed_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
         match token.clone() {
             Event::Start(_) => {
                 match children.len() {
                     0 => children = compressed_inner(tokenizer, parents),
                     _ => {
                         children.push_str(&compressed_inner(tokenizer, parents));
                     },
                 };
             },
             Event::Selector(name) => {
                 parents.push((*name).to_string());
                 match last {
                     Event::Selector(_) => current.push_str(&format!(" {}", name)),
                     _ => current.push_str(&format!("{}", name)),
                 }
             },
             Event::Property(name, value) => {
                 match last {
                     Event::Selector(..) => properties.push_str(&format!("{{{}:{}", name, value)),
                     Event::Property(..) => properties.push_str(&format!(";{}:{}", name, value)),
                     _ => properties.push_str(&format!("{}:{}", name, value)),
                 }
             },
             Event::End(_) => {
                 match (properties.len(), children.len()) {
                     (0, 0) => current.push_str("}"),
                     (_, 0) => {
                         current.push_str(&properties);
                         current.push_str("}");
                     },
                     (0, _) => {
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                     (_, _) => {
                         current.push_str(&properties);
                         current.push_str("}");
                         current.push_str(&parents.connect(" "));
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                 }
                 parents.pop();
                 return current
             },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn expanded<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    expanded_inner(&mut vm, &mut parents)
}

fn expanded_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = expanded_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&expanded_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str("\n}");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str("\n}\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };

        last = token;
    }
    children
}

pub fn compact<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compact_inner(&mut vm, &mut parents)
}

fn compact_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = compact_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n");
                        children.push_str(&compact_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{ {}: {};", name, value)),
                    _ => properties.push_str(&format!(" {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn debug(tokenizer: &mut Tokenizer) -> String {
    let mut output = String::new();
    let mut current = String::new();

    while let Some(token) = tokenizer.next() {
        current.push_str(&format!("{:?}\n", token));
        match token {
            Event::End(_) => {
                output.push_str(&current);
                current = String::new();
            },
            _ => {},
        }
    }
    output
}
<commit_msg>Fix incorrect indentation of one extra space<commit_after>use tokenizer::Tokenizer;
use event::{Event, Rule};
use variable_mapper::VariableMapper;

pub fn nested<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    nested_inner(&mut vm, &mut parents)
}

pub fn nested_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
       match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = nested_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&nested_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                current.push_str(&format!("{} ", name));
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!("{{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }\n"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }");
                    },
                    (0, _) => {
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n  ");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children.split('\n').collect::<Vec<_>>().connect("\n  "));
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn compressed<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compressed_inner(&mut vm, &mut parents)
}

fn compressed_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = compressed_inner(tokenizer, parents),
                    _ => {
                        children.push_str(&compressed_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(..) => properties.push_str(&format!("{{{}:{}", name, value)),
                    Event::Property(..) => properties.push_str(&format!(";{}:{}", name, value)),
                    _ => properties.push_str(&format!("{}:{}", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str("}"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str("}");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str("}");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn expanded<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    expanded_inner(&mut vm, &mut parents)
}

fn expanded_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = expanded_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&expanded_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str("\n}");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str("\n}\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };

        last = token;
    }
    children
}

pub fn compact<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compact_inner(&mut vm, &mut parents)
}

fn compact_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = compact_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n");
                        children.push_str(&compact_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{ {}: {};", name, value)),
                    _ => properties.push_str(&format!(" {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
            Event::Comment(body) => unimplemented!(),
        };
        last = token;
    }
    children
}

pub fn debug(tokenizer: &mut Tokenizer) -> String {
    let mut output = String::new();
    let mut current = String::new();

    while let Some(token) = tokenizer.next() {
        current.push_str(&format!("{:?}\n", token));
        match token {
            Event::End(_) => {
                output.push_str(&current);
                current = String::new();
            },
            _ => {},
        }
    }
    output
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//! The portable PortAudio API.

use ffi;
use libc::c_double;
use std::ptr;
use std::marker::PhantomData;

pub use self::error::Error;
pub use self::stream::Stream;
pub use self::types::{
    DeviceIndex,
    DeviceInfo,
    Frames,
    HostApiIndex,
    HostApiInfo,
    HostApiTypeId,
    HostErrorInfo,
    SampleFormat,
    StreamAvailable,
    stream_callback_flags,
    StreamCallbackFlags,
    StreamCallbackTimeInfo,
    StreamCallbackResult,
    stream_flags,
    StreamFlags,
    StreamInfo,
    StreamParameters,
    Time,
    FRAMES_PER_BUFFER_UNSPECIFIED,
    NO_DEVICE,
    USE_HOST_API_SPECIFIC_DEVICE_SPECIFICATION,
};

pub mod error;
pub mod device;
pub mod host;
pub mod stream;
mod types;

/// A type-safe wrapper around the PortAudio API.
///
/// We use a type here instead of pure functions in order to ensure correct intialisation and
/// termination of the underlying PortAudio instance.
#[derive(Debug)]
pub struct PortAudio {
    /// This is solely used for checking whether or not the PortAudio API has already been
    /// terminated manually (via the `PortAudio::terminate` method) when `Drop::drop` is called.
    is_terminated: bool,
}

impl PortAudio {

    /// Construct a **PortAudio** instance.
    ///
    /// This calls PortAudio's `Pa_Initialize` function which initializes internal data structures
    /// and prepares underlying host APIs for use.
    ///
    /// Using the C API, a user would normally have to call `Pa_Terminate` when shutting down
    /// PortAudio, however this **PortAudio** type will automatically take care of this when
    /// `Drop`ped.
    ///
    /// It is safe to simultaneously construct more than one **PortAudio** instance, however this
    /// is rarely necessary.
    pub fn new() -> Result<Self, Error> {
        unsafe {
            match ffi::Pa_Initialize() {
                Error::NoError => Ok(PortAudio { is_terminated: false }),
                err => Err(err),
            }
        }
    }

    /// Takes ownership of `self` and terminates the PortAudio API using `Pa_Terminate`.
    ///
    /// This function deallocates all resources allocated by PortAudio since it was constructed.
    ///
    /// **Calling this method is optional**. It is only necessary if you require handling any
    /// PortAudio termination errors. Otherwise, `Pa_Terminate` will be called and all necessary
    /// cleanup will occur automatically when this **PortAudio** instance is **Drop**ped.
    pub fn terminate(mut self) -> Result<(), Error> {
        self.is_terminated = true;
        terminate()
    }

}

impl Drop for PortAudio {
    fn drop(&mut self) {
        if !self.is_terminated {
            terminate();
        }
    }
}

/// Retrieve the release number of the currently running PortAudio build.
pub fn get_version() -> i32 {
    unsafe {
        ffi::Pa_GetVersion()
    }
}

/// Retrieve a textual description of the current PortAudio build.
pub fn get_version_text() -> String {
    unsafe {
        ffi::c_str_to_string(&ffi::Pa_GetVersionText())
    }
}

/// Translate the supplied PortAudio error code into a human readable message.
///
/// # Arguments
/// * error_code - The error code
///
/// Return the error as a string.
pub fn get_error_text(error_code: Error) -> String {
    unsafe {
        ffi::c_str_to_string(&ffi::Pa_GetErrorText(error_code))
    }
}

// /// Library initialization function - call this before using PortAudio.
// /// This function initializes internal data structures and prepares underlying
// /// host APIs for use. With the exception of get_version(), get_version_text(),
// /// and get_error_text(), this function MUST be called before using any other
// /// PortAudio API functions.
// ///
// /// Note that if initialize() returns an error code, Pa_Terminate() should NOT be
// /// called.
// ///
// /// Return NoError if successful, otherwise an error code indicating the cause
// /// of failure.
// fn initialize() -> Result<(), Error> {
//     unsafe {
//         match ffi::Pa_Initialize() {
//             Error::NoError => Ok(()),
//             err => Err(err),
//         }
//     }
// }

/// Library termination function - call this when finished using PortAudio.
/// This function deallocates all resources allocated by PortAudio since it was
/// initialized by a call to initialize(). In cases where initialise() has been
/// called multiple times, each call must be matched with a corresponding call to
/// terminate(). The final matching call to terminate() will automatically close
/// any PortAudio streams that are still open.
///
/// terminate() MUST be called before exiting a program which uses PortAudio.
/// Failure to do so may result in serious resource leaks, such as audio devices
/// not being available until the next reboot.
///
/// **Note:** The above resource management is automatically handled by the
/// **PortAudio** type.
///
/// Return NoError if successful, otherwise an error code indicating the cause
/// of failure.
fn terminate() -> Result<(), Error> {
    unsafe {
        match ffi::Pa_Terminate() {
            Error::NoError => Ok(()),
            err => Err(err),
        }
    }
}

/// Return information about the last host error encountered.
/// The error information returned by get_last_host_error_info() will never be
/// modified asynchronously by errors occurring in other PortAudio owned threads
/// (such as the thread that manages the stream callback.)
///
/// This function is provided as a last resort, primarily to enhance debugging
/// by providing clients with access to all available error information.
///
/// Return a pointer to an immuspacespacespacele structure constraining
/// information about the host error. The values in this structure will only be
/// valid if a PortAudio function has previously returned the
/// UnanticipatedHostError error code.
pub fn get_last_host_error_info() -> HostErrorInfo {
    let c_error = unsafe { ffi::Pa_GetLastHostErrorInfo() };
    HostErrorInfo::wrap(c_error)
}

/// Determine whether it would be possible to open a stream with the specified
/// parameters.
///
/// # Arguments
/// * input_parameters - A structure that describes the input parameters used to
/// open a stream.
/// The suggestedLatency field is ignored. See StreamParameters for a
/// description of these parameters. inputParameters must be None for output-only
/// streams.
/// * output_parameters - A structure that describes the output parameters used to
/// open a stream. The suggestedLatency field is ignored. See StreamParameters
/// for a description of these parameters. outputParameters must be None for
/// input-only streams.
/// * sample_rate - The required sampleRate. For full-duplex streams it is the
/// sample rate for both input and output.
///
/// Return 0 if the format is supported, and an error code indicating why the
/// format is not supported otherwise. The constant PaFormatIsSupported is
/// provided to compare with the return value for success.
pub fn is_format_supported(maybe_input_parameters: Option<&StreamParameters>,
                           maybe_output_parameters: Option<&StreamParameters>,
                           sample_rate : f64) -> Result<(), Error> {
    let c_input = maybe_input_parameters.map(StreamParameters::unwrap).as_ref().map(|input| input as *const _);
    let c_output = maybe_output_parameters.map(StreamParameters::unwrap).as_ref().map(|output| output as *const _);
    if c_input.is_none() && c_output.is_none() {
        Err(Error::InvalidDevice)
    } else {
        unsafe {
            match ffi::Pa_IsFormatSupported(c_input.unwrap_or(ptr::null()),
                                            c_output.unwrap_or(ptr::null()),
                                            sample_rate as c_double) {
                Error::NoError => Ok(()),
                err => Err(err),
            }
        }
    }
}

/// Retrieve the size of a given sample format in bytes.
///
/// Return the size in bytes of a single sample in the specified format,
/// or SampleFormatNotSupported if the format is not supported.
pub fn get_sample_size(format: SampleFormat) -> Result<(), Error> {
    match unsafe {
        ffi::Pa_GetSampleSize(format as u64)
    } {
        Error::NoError => Ok(()),
        err => Err(err),
    }
}

/// Put the caller to sleep for at least 'msec' milliseconds.
/// This function is provided only as a convenience for authors of portable code
/// (such as the tests and examples in the PortAudio distribution.)
///
/// The function may sleep longer than requested so don't rely on this for
/// accurate musical timing.
pub fn sleep(m_sec : i32) -> () {
    unsafe {
        ffi::Pa_Sleep(m_sec)
    }
}

mod private {

    use num::{FromPrimitive, ToPrimitive};
    use std::ops::{Add, Sub, Mul, Div};
    use super::types::SampleFormat;

    /// internal private trait for Sample format management
    pub trait SamplePrivate: ::std::default::Default + Copy + Clone + ::std::fmt::Debug
                             + ToPrimitive + FromPrimitive + Add + Sub + Mul + Div {
        /// return the size of a sample format
        fn size<S: SamplePrivate>() -> usize {
            ::std::mem::size_of::<S>()
        }
        /// get the sample format
        fn to_sample_format() -> SampleFormat;
    }

}

impl private::SamplePrivate for f32 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Float32 }
}

impl private::SamplePrivate for i32 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Int32 }
}

impl private::SamplePrivate for u8 {
    fn to_sample_format() -> SampleFormat { SampleFormat::UInt8 }
}

impl private::SamplePrivate for i8 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Int8 }
}

/// public trait to constraint pa::Stream for specific types
pub trait Sample: private::SamplePrivate {
    /// Retrieve the SampleFormat variant associated with the type.
    fn sample_format_for<S: Sample>() -> SampleFormat {
        S::to_sample_format()
    }
    /// Retrieve the SampleFormat variant associated with the type.
    fn sample_format(&self) -> SampleFormat { Self::to_sample_format() }
}

impl Sample for f32 {}
impl Sample for i32 {}
impl Sample for i8 {}
impl Sample for u8 {}
<commit_msg>Remove unnecessary get_error_text function. Users should instead use Error::description as is rusty convention.<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//! The portable PortAudio API.

use ffi;
use libc::c_double;
use std::ptr;
use std::marker::PhantomData;

pub use self::error::Error;
pub use self::stream::Stream;
pub use self::types::{
    DeviceIndex,
    DeviceInfo,
    Frames,
    HostApiIndex,
    HostApiInfo,
    HostApiTypeId,
    HostErrorInfo,
    SampleFormat,
    StreamAvailable,
    stream_callback_flags,
    StreamCallbackFlags,
    StreamCallbackTimeInfo,
    StreamCallbackResult,
    stream_flags,
    StreamFlags,
    StreamInfo,
    StreamParameters,
    Time,
    FRAMES_PER_BUFFER_UNSPECIFIED,
    NO_DEVICE,
    USE_HOST_API_SPECIFIC_DEVICE_SPECIFICATION,
};

pub mod error;
pub mod device;
pub mod host;
pub mod stream;
mod types;

/// A type-safe wrapper around the PortAudio API.
///
/// We use a type here instead of pure functions in order to ensure correct intialisation and
/// termination of the underlying PortAudio instance.
#[derive(Debug)]
pub struct PortAudio {
    /// This is solely used for checking whether or not the PortAudio API has already been
    /// terminated manually (via the `PortAudio::terminate` method) when `Drop::drop` is called.
    is_terminated: bool,
}

impl PortAudio {

    /// Construct a **PortAudio** instance.
    ///
    /// This calls PortAudio's `Pa_Initialize` function which initializes internal data structures
    /// and prepares underlying host APIs for use.
    ///
    /// Using the C API, a user would normally have to call `Pa_Terminate` when shutting down
    /// PortAudio, however this **PortAudio** type will automatically take care of this when
    /// `Drop`ped.
    ///
    /// It is safe to simultaneously construct more than one **PortAudio** instance, however this
    /// is rarely necessary.
    pub fn new() -> Result<Self, Error> {
        unsafe {
            match ffi::Pa_Initialize() {
                Error::NoError => Ok(PortAudio { is_terminated: false }),
                err => Err(err),
            }
        }
    }

    /// Takes ownership of `self` and terminates the PortAudio API using `Pa_Terminate`.
    ///
    /// This function deallocates all resources allocated by PortAudio since it was constructed.
    ///
    /// **Calling this method is optional**. It is only necessary if you require handling any
    /// PortAudio termination errors. Otherwise, `Pa_Terminate` will be called and all necessary
    /// cleanup will occur automatically when this **PortAudio** instance is **Drop**ped.
    pub fn terminate(mut self) -> Result<(), Error> {
        self.is_terminated = true;
        terminate()
    }

}

impl Drop for PortAudio {
    fn drop(&mut self) {
        if !self.is_terminated {
            terminate();
        }
    }
}

/// Retrieve the release number of the currently running PortAudio build.
pub fn get_version() -> i32 {
    unsafe {
        ffi::Pa_GetVersion()
    }
}

/// Retrieve a textual description of the current PortAudio build.
pub fn get_version_text() -> String {
    unsafe {
        ffi::c_str_to_string(&ffi::Pa_GetVersionText())
    }
}

// /// Library initialization function - call this before using PortAudio.
// /// This function initializes internal data structures and prepares underlying
// /// host APIs for use. With the exception of get_version(), get_version_text(),
// /// and get_error_text(), this function MUST be called before using any other
// /// PortAudio API functions.
// ///
// /// Note that if initialize() returns an error code, Pa_Terminate() should NOT be
// /// called.
// ///
// /// Return NoError if successful, otherwise an error code indicating the cause
// /// of failure.
// fn initialize() -> Result<(), Error> {
//     unsafe {
//         match ffi::Pa_Initialize() {
//             Error::NoError => Ok(()),
//             err => Err(err),
//         }
//     }
// }

/// Library termination function - call this when finished using PortAudio.
/// This function deallocates all resources allocated by PortAudio since it was
/// initialized by a call to initialize(). In cases where initialise() has been
/// called multiple times, each call must be matched with a corresponding call to
/// terminate(). The final matching call to terminate() will automatically close
/// any PortAudio streams that are still open.
///
/// terminate() MUST be called before exiting a program which uses PortAudio.
/// Failure to do so may result in serious resource leaks, such as audio devices
/// not being available until the next reboot.
///
/// **Note:** The above resource management is automatically handled by the
/// **PortAudio** type.
///
/// Return NoError if successful, otherwise an error code indicating the cause
/// of failure.
fn terminate() -> Result<(), Error> {
    unsafe {
        match ffi::Pa_Terminate() {
            Error::NoError => Ok(()),
            err => Err(err),
        }
    }
}

/// Return information about the last host error encountered.
/// The error information returned by get_last_host_error_info() will never be
/// modified asynchronously by errors occurring in other PortAudio owned threads
/// (such as the thread that manages the stream callback.)
///
/// This function is provided as a last resort, primarily to enhance debugging
/// by providing clients with access to all available error information.
///
/// Return a pointer to an immuspacespacespacele structure constraining
/// information about the host error. The values in this structure will only be
/// valid if a PortAudio function has previously returned the
/// UnanticipatedHostError error code.
pub fn get_last_host_error_info() -> HostErrorInfo {
    let c_error = unsafe { ffi::Pa_GetLastHostErrorInfo() };
    HostErrorInfo::wrap(c_error)
}

/// Determine whether it would be possible to open a stream with the specified
/// parameters.
///
/// # Arguments
/// * input_parameters - A structure that describes the input parameters used to
/// open a stream.
/// The suggestedLatency field is ignored. See StreamParameters for a
/// description of these parameters. inputParameters must be None for output-only
/// streams.
/// * output_parameters - A structure that describes the output parameters used to
/// open a stream. The suggestedLatency field is ignored. See StreamParameters
/// for a description of these parameters. outputParameters must be None for
/// input-only streams.
/// * sample_rate - The required sampleRate. For full-duplex streams it is the
/// sample rate for both input and output.
///
/// Return 0 if the format is supported, and an error code indicating why the
/// format is not supported otherwise. The constant PaFormatIsSupported is
/// provided to compare with the return value for success.
pub fn is_format_supported(maybe_input_parameters: Option<&StreamParameters>,
                           maybe_output_parameters: Option<&StreamParameters>,
                           sample_rate : f64) -> Result<(), Error> {
    let c_input = maybe_input_parameters.map(StreamParameters::unwrap).as_ref().map(|input| input as *const _);
    let c_output = maybe_output_parameters.map(StreamParameters::unwrap).as_ref().map(|output| output as *const _);
    if c_input.is_none() && c_output.is_none() {
        Err(Error::InvalidDevice)
    } else {
        unsafe {
            match ffi::Pa_IsFormatSupported(c_input.unwrap_or(ptr::null()),
                                            c_output.unwrap_or(ptr::null()),
                                            sample_rate as c_double) {
                Error::NoError => Ok(()),
                err => Err(err),
            }
        }
    }
}

/// Retrieve the size of a given sample format in bytes.
///
/// Return the size in bytes of a single sample in the specified format,
/// or SampleFormatNotSupported if the format is not supported.
pub fn get_sample_size(format: SampleFormat) -> Result<(), Error> {
    match unsafe {
        ffi::Pa_GetSampleSize(format as u64)
    } {
        Error::NoError => Ok(()),
        err => Err(err),
    }
}

/// Put the caller to sleep for at least 'msec' milliseconds.
/// This function is provided only as a convenience for authors of portable code
/// (such as the tests and examples in the PortAudio distribution.)
///
/// The function may sleep longer than requested so don't rely on this for
/// accurate musical timing.
pub fn sleep(m_sec : i32) -> () {
    unsafe {
        ffi::Pa_Sleep(m_sec)
    }
}

mod private {

    use num::{FromPrimitive, ToPrimitive};
    use std::ops::{Add, Sub, Mul, Div};
    use super::types::SampleFormat;

    /// internal private trait for Sample format management
    pub trait SamplePrivate: ::std::default::Default + Copy + Clone + ::std::fmt::Debug
                             + ToPrimitive + FromPrimitive + Add + Sub + Mul + Div {
        /// return the size of a sample format
        fn size<S: SamplePrivate>() -> usize {
            ::std::mem::size_of::<S>()
        }
        /// get the sample format
        fn to_sample_format() -> SampleFormat;
    }

}

impl private::SamplePrivate for f32 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Float32 }
}

impl private::SamplePrivate for i32 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Int32 }
}

impl private::SamplePrivate for u8 {
    fn to_sample_format() -> SampleFormat { SampleFormat::UInt8 }
}

impl private::SamplePrivate for i8 {
    fn to_sample_format() -> SampleFormat { SampleFormat::Int8 }
}

/// public trait to constraint pa::Stream for specific types
pub trait Sample: private::SamplePrivate {
    /// Retrieve the SampleFormat variant associated with the type.
    fn sample_format_for<S: Sample>() -> SampleFormat {
        S::to_sample_format()
    }
    /// Retrieve the SampleFormat variant associated with the type.
    fn sample_format(&self) -> SampleFormat { Self::to_sample_format() }
}

impl Sample for f32 {}
impl Sample for i32 {}
impl Sample for i8 {}
impl Sample for u8 {}
<|endoftext|>


<commit_before>//! Contains the `SwitchHeader` structure, storing the packet header
//! used by the Switch, as defined by
//! https://github.com/cjdelisle/cjdns/blob/cjdns-v17.4/doc/Whitepaper.md#in-memory-representation

use operation::{switch, reverse_label, Director, RoutingDecision, Label};

pub enum PacketType {
    Opaque,
    SwitchControlMessage,
}

pub struct SwitchPacket {
    pub raw: Vec<u8>,
}

impl SwitchPacket {
    pub fn new(route_label: &[u8; 8], type_: &PacketType, mut payload: Vec<u8>) -> SwitchPacket {
        let mut raw = Vec::with_capacity(12 + payload.len());
        raw.resize(12, 0);
        raw[0..8].copy_from_slice(route_label);
        raw[8] = match *type_ {
            PacketType::Opaque => 0u8,
            PacketType::SwitchControlMessage => 1u8,
        };
        raw.append(&mut payload);
        SwitchPacket { raw: raw }
    }

    /// Returns the type of the packet. Errors with the type number if
    /// the type number is unknown.
    pub fn packet_type(&self) -> Result<PacketType, u8> {
        match self.raw[8] {
            0u8 => Ok(PacketType::Opaque),
            1u8 => Ok(PacketType::SwitchControlMessage),
            n => Err(n),
        }
    }

    /// Returns the address label of the packet.
    pub fn label(&self) -> Label {
        let mut label = [0u8; 8];
        label.copy_from_slice(&self.raw[0..8]);
        label
    }

    /// Returns a reference to the content of the packet.
    pub fn payload(&self) -> &[u8] {
        &self.raw[12..]
    }

    pub fn switch(&mut self, director_length: u8, reversed_origin_iface: &Director) -> RoutingDecision {
        let (new_label, decision) = switch(&self.label(), director_length, reversed_origin_iface);
        self.raw[0..8].copy_from_slice(&new_label);
        decision
    }

    pub fn reverse_label(&mut self) {
        // TODO: do this in-place/no-copy.
        let mut label = [0u8; 8];
        reverse_label(&mut label);
        self.raw[0..8].copy_from_slice(&label);
    }

}
<commit_msg>Add support for detecting the payload type.<commit_after>//! Contains the `SwitchHeader` structure, storing the packet header
//! used by the Switch, as defined by
//! https://github.com/cjdelisle/cjdns/blob/cjdns-v17.4/doc/Whitepaper.md#in-memory-representation

use byteorder::BigEndian;
use byteorder::ByteOrder;

use operation::{switch, reverse_label, Director, RoutingDecision, Label};

#[derive(Debug)]
pub enum PacketType {
    Opaque,
    SwitchControlMessage,
}

#[derive(Debug)]
pub enum Payload {
    CryptoAuthHandshake(Vec<u8>),
    Control(Vec<u8>),
    Other(u32, Vec<u8>), // First argument is the session handle
}

pub struct SwitchPacket {
    pub raw: Vec<u8>,
}

impl SwitchPacket {
    pub fn new(route_label: &[u8; 8], type_: &PacketType, payload: Payload) -> SwitchPacket {
        let payload_length = match payload {
            Payload::CryptoAuthHandshake(ref msg) => msg.len(),
            Payload::Control(ref msg) => msg.len(),
            Payload::Other(_, ref msg) => 4 + msg.len(),
        };
        let mut raw = Vec::with_capacity(12 + payload_length);
        raw.resize(16, 0);
        raw[0..8].copy_from_slice(route_label);
        raw[8] = match *type_ {
            PacketType::Opaque => 0u8,
            PacketType::SwitchControlMessage => 1u8,
        };
        match payload {
            Payload::CryptoAuthHandshake(mut msg) => {
                let session_state = BigEndian::read_u32(&msg[0..4]);
                assert!(session_state < 4);
                assert!(session_state != 0xffffffff);
                raw.append(&mut msg);
            },
            Payload::Control(mut msg) => {
                raw.append(&mut vec![0xff, 0xff, 0xff, 0xff]);
                raw.append(&mut msg);
            },
            Payload::Other(session_handle, mut msg) => {
                assert!(session_handle >= 4);
                assert!(session_handle != 0xffffffff);
                let mut raw_handle = vec![0u8; 4];
                BigEndian::write_u32(&mut raw_handle, session_handle);
                raw.append(&mut raw_handle);
                raw.append(&mut msg);
            },
        }
        SwitchPacket { raw: raw }
    }

    /// Returns the type of the packet. Errors with the type number if
    /// the type number is unknown.
    pub fn packet_type(&self) -> Result<PacketType, u8> {
        match self.raw[8] {
            0u8 => Ok(PacketType::Opaque),
            1u8 => Ok(PacketType::SwitchControlMessage),
            n => Err(n),
        }
    }

    /// Returns the address label of the packet.
    pub fn label(&self) -> Label {
        let mut label = [0u8; 8];
        label.copy_from_slice(&self.raw[0..8]);
        label
    }

    pub fn derivation(&self) -> [u8; 2] {
        let mut d = [0u8; 2];
        d.copy_from_slice(&self.raw[8..10]);
        d
    }

    pub fn additional(&self) -> [u8; 2] {
        let mut a = [0u8; 2];
        a.copy_from_slice(&self.raw[10..12]);
        a
    }

    /// Returns a reference to the content of the packet.
    pub fn payload(&self) -> Payload {
        match BigEndian::read_u32(&self.raw[12..16]) {
            0 | 1 | 2 | 3 => Payload::CryptoAuthHandshake(self.raw[12..].to_vec()),
            0xffffffff => Payload::Control(self.raw[16..].to_vec()),
            handle => Payload::Other(handle, self.raw[16..].to_vec()),
        }
    }

    pub fn switch(&mut self, director_length: u8, reversed_origin_iface: &Director) -> RoutingDecision {
        let (new_label, decision) = switch(&self.label(), director_length, reversed_origin_iface);
        self.raw[0..8].copy_from_slice(&new_label);
        decision
    }

    pub fn reverse_label(&mut self) {
        // TODO: do this in-place/no-copy.
        let mut label = [0u8; 8];
        reverse_label(&mut label);
        self.raw[0..8].copy_from_slice(&label);
    }

}
<|endoftext|>


<commit_before>use nom::{IResult, alpha, alphanumeric, rest};
use std::vec::Vec;

use template::Chunk;

named!(var_name<&[u8], Vec<u8>>,
    map!(
        recognize!(
            do_parse!(
                alpha >>
                many0!(alt!(alphanumeric | tag!("_"))) >>
                ()
            )
        ), Vec::from
    )
);

named!(var<&[u8], Chunk>,
    map!(
        ws!(
            delimited!(
                tag!("{%"),
                var_name,
                tag!("%}")
            )
        ),
        |v| Chunk::Var(Vec::from(v))
    )
);

named!(literal<&[u8], Chunk>,
    map!(
        alt_complete!(take_until!("{%") | rest),
        |s| Chunk::Str(Vec::from(s))
    )
);

named!(pub template<&[u8], Vec<Chunk>>,
    many0!(
        alt!(var | literal)
    )
);
<commit_msg>Refactor<commit_after>use nom::{alpha, alphanumeric, rest};
use std::vec::Vec;

use template::Chunk;

named!(var_name<Vec<u8>>,
    map!(
        recognize!(
            do_parse!(
                alpha >>
                many0!(alt!(alphanumeric | tag!("_"))) >>
                ()
            )
        ), Vec::from
    )
);

named!(var<Chunk>,
    map!(
        ws!(
            delimited!(
                tag!("{%"),
                var_name,
                tag!("%}")
            )
        ),
        |v| Chunk::Var(Vec::from(v))
    )
);

named!(literal<Chunk>,
    map!(
        alt_complete!(take_until!("{%") | rest),
        |s| Chunk::Str(Vec::from(s))
    )
);

named!(pub template<Vec<Chunk>>,
    many0!(
        alt!(var | literal)
    )
);
<|endoftext|>