<commit_before>//! # A Library for Safe SIMD Operations
//!
//! The `simdop` library provides SIMD functionality
//! for building applications using fast operations
//! on homogeneous vector types.
//! It provides safety on a type-level using traits.
//!
//! ## CPU identification and feature detection
//!
//! In order to use a specific operations on a specific vector type,
//! you have to provide proof that the operation is valid on your architecture.
//! This is achieved by executing one or more detection functions, which return
//! an `Option<T>` type. You need to retrieve the wrapped value, which provides access
//! to the operations in the detected feature set in the form of trait implementations.
//!
//! ## Vector representation and encoding
//!
//! Since the number of elements in a vector is always a power of two,
//! vectors are represented as a perfect binary tree, which encodes the length
//! of the vector as a logarithm in the height of the tree.
//! This makes structural modifications very easy, while providing strong type guarantees,
//! e.g. when splitting or joining vectors.
//!
//! To perform SIMD operation, the tree is flattened into an array, and restored afterwards.
//! When combining vector operations, the compiler is able to perform "deforestation"
//! optimisations on the data structures, elminating most of the structural overhead.

extern crate simdty;

/// Core data structures and traits.
pub mod core {

  #[derive(Debug, Copy, Clone)]
  pub struct Twice<N> {
    pub lo: N,
    pub hi: N
  }

  pub trait Multi {
    type Elem;
    type Repr;
    fn wrap(Self::Repr) -> Self;
    fn unwrap(self) -> Self::Repr;
  }

  pub trait Half {
    type Half;
  }

  impl<N> Half for Twice<N> {
    type Half = N;
  }

  pub trait Widen {
    type Widen;
  }

  impl<T: Widen> Widen for Twice<T> {
    type Widen = Twice<T::Widen>;
  }

  impl Widen for Twice<i16> {
    type Widen = i32;
  }

  impl Widen for Twice<i32> {
    type Widen = i64;
  }

  pub trait Narrow {
    type Narrow;
  }

  impl<T: Narrow> Narrow for Twice<T> {
    type Narrow = Twice<T::Narrow>;
  }

  impl Narrow for Twice<i16> {
    type Narrow = Twice<Twice<i8>>;
  }

  impl Narrow for Twice<i32> {
    type Narrow = Twice<Twice<i16>>;
  }

}

use self::core::*;

/// A vector of 2 elements of type `N`.
pub type M2<N> = Twice<N>;
/// A vector of 4 elements of type `N`.
pub type M4<N> = Twice<M2<N>>;
/// A vector of 8 elements of type `N`.
pub type M8<N> = Twice<M4<N>>;
/// A vector of 16 elements of type `N`.
pub type M16<N> = Twice<M8<N>>;
/// A vector of 32 elements of type `N`.
pub type M32<N> = Twice<M16<N>>;

impl Multi for M2<i64> {
  type Elem = i64;
  type Repr = simdty::i64x2;
#[inline(always)]
  fn wrap(s: Self::Repr) -> Self {
    Twice{lo: s.0, hi: s.1}
  }
#[inline(always)]
  fn unwrap(self) -> Self::Repr {
    simdty::i64x2(self.lo, self.hi)
  }
}

impl Multi for M4<i32> {
  type Elem = i32;
  type Repr = simdty::i32x4;
#[inline(always)]
  fn wrap(s: Self::Repr) -> Self {
    Twice{
      lo: Twice{lo: s.0, hi: s.1},
      hi: Twice{lo: s.2, hi: s.3}
    }
  }
#[inline(always)]
  fn unwrap(self) -> Self::Repr {
    simdty::i32x4(self.lo.lo, self.lo.hi, self.hi.lo, self.hi.hi)
  }
}

impl Multi for M8<i16> {
  type Elem = i16;
  type Repr = simdty::i16x8;
#[inline(always)]
  fn wrap(s: Self::Repr) -> Self {
    Twice{
      lo: Twice{
        lo: Twice{lo: s.0, hi: s.1},
        hi: Twice{lo: s.2, hi: s.3},
      },
      hi: Twice{
        lo: Twice{lo: s.4, hi: s.5},
        hi: Twice{lo: s.6, hi: s.7}
      }
    }
  }
#[inline(always)]
  fn unwrap(self) -> Self::Repr {
    simdty::i16x8(
      self.lo.lo.lo, self.lo.lo.hi, self.lo.hi.lo, self.lo.hi.hi,
      self.hi.lo.lo, self.hi.lo.hi, self.hi.hi.lo, self.hi.hi.hi
    )
  }
}

impl Multi for M16<i8> {
  type Elem = i8;
  type Repr = simdty::i8x16;
#[inline(always)]
  fn wrap(s: Self::Repr) -> Self {
    Twice{
      lo: Twice{
        lo: Twice{
          lo: Twice{lo: s.0, hi: s.1},
          hi: Twice{lo: s.2, hi: s.3},
        },
        hi: Twice{
          lo: Twice{lo: s.4, hi: s.5},
          hi: Twice{lo: s.6, hi: s.7},
        }
      },
      hi: Twice{
        lo: Twice{
          lo: Twice{lo: s.8, hi: s.9},
          hi: Twice{lo: s.10, hi: s.11}
        },
        hi: Twice{
          lo: Twice{lo: s.12, hi: s.13},
          hi: Twice{lo: s.14, hi: s.15}
        }
      }
    }
  }
#[inline(always)]
  fn unwrap(self) -> Self::Repr {
    simdty::i8x16(
      self.lo.lo.lo.lo, self.lo.lo.lo.hi, self.lo.lo.hi.lo, self.lo.lo.hi.hi,
      self.lo.hi.lo.lo, self.lo.hi.lo.hi, self.lo.hi.hi.lo, self.lo.hi.hi.hi,
      self.hi.lo.lo.lo, self.hi.lo.lo.hi, self.hi.lo.hi.lo, self.hi.lo.hi.hi,
      self.hi.hi.lo.lo, self.hi.hi.lo.hi, self.hi.hi.hi.lo, self.hi.hi.hi.hi
    )
  }
}

/// The `CmpEq` trait is used to specify equality comparison funtionality.
pub trait CmpEq<M: Multi> {
/// Compares elements in `a` and `b` for equality.
  fn cmpeq(&self, a: M, b: M) -> M;
}

/// The `CmpGt` trait is used to specify greater-than comparison funtionality.
pub trait CmpGt<M: Multi> {
/// Compares elements in `a` and `b` for greater-than.
  fn cmpgt(&self, a: M, b: M) -> M;
}

/// The `CmpLt` trait is used to specify less-than comparison funtionality.
pub trait CmpLt<M: Multi> {
/// Compares elements in `a` and `b` for less-than.
  fn cmplt(&self, a: M, b: M) -> M;
}

/// The `Set1` trait is used to specify broadcasting functionality.
pub trait Set1<M: Multi> {
/// Broadcasts `e` to all elements of the vector.
  fn set1(&self, e: M::Elem) -> M;
}

/// The `Add` trait is used to specify element-wise addition functionality.
pub trait Add<M: Multi> {
/// Adds elements in a and b.
  fn add(&self, a: M, b: M) -> M;
}

/// The `AddS` trait is used to specify element-wise saturated addition functionality.
pub trait AddS<M: Multi> {
/// Adds elements in a and b using saturation.
  fn adds(&self, a: M, b: M) -> M;
}

/// The `MAdd` trait is used to specify multiply-add functionality.
pub trait MAdd<M: Multi + Widen> {
/// Multiplies elements from `a` and `b`, producing intermediate elements of twice the size. Horizontally adds adjacent pairs of intermediate elements.
  fn madd(&self, a: M, b: M) -> M::Widen;
}

/// The `Min` trait is used to specify minimum comparison functionality.
pub trait Min<M: Multi> {
/// Compares elements in `a` and `b`, and finds the minimum values.
  fn min(&self, a: M, b: M) -> M;
}

/// The `Max` trait is used to specify maximum comparison functionality.
pub trait Max<M: Multi> {
/// Compares elements in `a` and `b`, and finds the maximum values.
  fn max(&self, a: M, b: M) -> M;
}

/// The `Shli` trait is used to specify immediate bit-wise left shift functionality.
pub trait Shli<M: Multi> {
/// Shifts all elements in the `a` left by `i` bits.
  fn shli(&self, a: M, i: i32) -> M;
}

/// The `Shri` trait is used to specify immediate bit-wise right shift functionality.
pub trait Shri<M: Multi> {
/// Shifts all elements in the `a` right by `i` bits.
  fn shri(&self, a: M, i32) -> M;
}

/// The `Mullo` trait is used to specify low element-wise multiplication functionality.
pub trait Mullo<M: Multi> {
/// Multiplies the elements in `a` and `b` and stores the lower halves of the results.
  fn mullo(&self, a: M, b: M) -> M;
}

/// The `Mulhi` trait is used to specify high element-wise multiplication functionality.
pub trait Mulhi<M: Multi> {
/// Multiplies the elements in `a` and `b` and stores the higher halves of the results.
  fn mulhi(&self, a: M, b: M) -> M;
}

/// The `Abs` trait is used to specify absolute value computation functionality.
pub trait Abs<M: Multi> {
/// Computes the absolute value of the elements in `a`
  fn abs(&self, a: M) -> M;
}

/// The `HAdd` trait is used to specify horizontal addition functionality.
pub trait HAdd<M: Multi> {
/// Horizontally adds adjacent pairs of elements in `a` and `b`.
  fn hadd(&self, a: M, b: M) -> M;
}

/// The `HSub` trait is used to specify horizontal subtraction functionality.
pub trait HSub<M: Multi> {
/// Horizontally subtracts adjacent pairs of elements in `a` and `b`.
  fn hsub(&self, a: M, b: M) -> M;
}

/// The `Sign` trait is used to specify negation functionality.
pub trait Sign<M: Multi> {
/// Negates elements in `a` if the corresponding element in `b` is negative.
/// Zeroes out the element if the corresponding element in `b` is zero.
  fn sign(&self, a: M, b: M) -> M;
}

/// The `PackS` trait is used to specify signed element narrowing functionality.
pub trait PackS<M: Multi + Narrow> {
/// Narrows elements from `a` and `b` using signed saturation.
  fn packs(&self, a: M, b: M) -> M::Narrow;
}

/// The `PackUS` trait is used to specify unsigned element narrowing functionality.
pub trait PackUS<M: Multi + Narrow> {
/// Narrows elements from `a` and `b` using unsigned saturation.
  fn packus(&self, a: M, b: M) -> M::Narrow;
}

/// CPU identification and feature detection, as well as trait implementations.
pub mod arch {

  enum Token { Token }

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
  pub mod x86;

#[cfg(target_arch = "arm")]
  pub mod arm;

}
<commit_msg>refactor: use macro for multi instances<commit_after>//! # A Library for Safe SIMD Operations
//!
//! The `simdop` library provides SIMD functionality
//! for building applications using fast operations
//! on homogeneous vector types.
//! It provides safety on a type-level using traits.
//!
//! ## CPU identification and feature detection
//!
//! In order to use a specific operations on a specific vector type,
//! you have to provide proof that the operation is valid on your architecture.
//! This is achieved by executing one or more detection functions, which return
//! an `Option<T>` type. You need to retrieve the wrapped value, which provides access
//! to the operations in the detected feature set in the form of trait implementations.
//!
//! ## Vector representation and encoding
//!
//! Since the number of elements in a vector is always a power of two,
//! vectors are represented as a perfect binary tree, which encodes the length
//! of the vector as a logarithm in the height of the tree.
//! This makes structural modifications very easy, while providing strong type guarantees,
//! e.g. when splitting or joining vectors.
//!
//! To perform SIMD operation, the tree is flattened into an array, and restored afterwards.
//! When combining vector operations, the compiler is able to perform "deforestation"
//! optimisations on the data structures, elminating most of the structural overhead.

extern crate simdty;

/// Core data structures and traits.
pub mod core {

  #[derive(Debug, Copy, Clone)]
  #[repr(C, packed)]
  pub struct Twice<N> {
    pub lo: N,
    pub hi: N
  }

  pub trait Multi {
    type Elem;
    type Repr;
    fn wrap(Self::Repr) -> Self;
    fn unwrap(self) -> Self::Repr;
  }

  pub trait Half {
    type Half;
  }

  impl<N> Half for Twice<N> {
    type Half = N;
  }

  pub trait Widen {
    type Widen;
  }

  impl<T: Widen> Widen for Twice<T> {
    type Widen = Twice<T::Widen>;
  }

  impl Widen for Twice<i16> {
    type Widen = i32;
  }

  impl Widen for Twice<i32> {
    type Widen = i64;
  }

  pub trait Narrow {
    type Narrow;
  }

  impl<T: Narrow> Narrow for Twice<T> {
    type Narrow = Twice<T::Narrow>;
  }

  impl Narrow for Twice<i16> {
    type Narrow = Twice<Twice<i8>>;
  }

  impl Narrow for Twice<i32> {
    type Narrow = Twice<Twice<i16>>;
  }

}

use std::mem;
use self::core::*;

/// A vector of 2 elements of type `N`.
pub type M2<N> = Twice<N>;
/// A vector of 4 elements of type `N`.
pub type M4<N> = Twice<M2<N>>;
/// A vector of 8 elements of type `N`.
pub type M8<N> = Twice<M4<N>>;
/// A vector of 16 elements of type `N`.
pub type M16<N> = Twice<M8<N>>;
/// A vector of 32 elements of type `N`.
pub type M32<N> = Twice<M16<N>>;

macro_rules! multi {
  ($m:ty, $e:ty, $r:ty) => {
    impl Multi for $m {
      type Elem = $e;
      type Repr = $r;
#[inline(always)]
      fn wrap(s: Self::Repr) -> Self {
        unsafe { mem::transmute(s) }
      }
#[inline(always)]
      fn unwrap(self) -> Self::Repr {
        unsafe { mem::transmute(self) }
      }
    }
  }
}

multi!(M2<i64>, i64, simdty::i64x2);
multi!(M4<i32>, i32, simdty::i32x4);
multi!(M8<i16>, i16, simdty::i16x8);
multi!(M16<i8>,  i8, simdty::i8x16);

/// The `CmpEq` trait is used to specify equality comparison funtionality.
pub trait CmpEq<M: Multi> {
/// Compares elements in `a` and `b` for equality.
  fn cmpeq(&self, a: M, b: M) -> M;
}

/// The `CmpGt` trait is used to specify greater-than comparison funtionality.
pub trait CmpGt<M: Multi> {
/// Compares elements in `a` and `b` for greater-than.
  fn cmpgt(&self, a: M, b: M) -> M;
}

/// The `CmpLt` trait is used to specify less-than comparison funtionality.
pub trait CmpLt<M: Multi> {
/// Compares elements in `a` and `b` for less-than.
  fn cmplt(&self, a: M, b: M) -> M;
}

/// The `Set1` trait is used to specify broadcasting functionality.
pub trait Set1<M: Multi> {
/// Broadcasts `e` to all elements of the vector.
  fn set1(&self, e: M::Elem) -> M;
}

/// The `Add` trait is used to specify element-wise addition functionality.
pub trait Add<M: Multi> {
/// Adds elements in a and b.
  fn add(&self, a: M, b: M) -> M;
}

/// The `AddS` trait is used to specify element-wise saturated addition functionality.
pub trait AddS<M: Multi> {
/// Adds elements in a and b using saturation.
  fn adds(&self, a: M, b: M) -> M;
}

/// The `MAdd` trait is used to specify multiply-add functionality.
pub trait MAdd<M: Multi + Widen> {
/// Multiplies elements from `a` and `b`, producing intermediate elements of twice the size. Horizontally adds adjacent pairs of intermediate elements.
  fn madd(&self, a: M, b: M) -> M::Widen;
}

/// The `Min` trait is used to specify minimum comparison functionality.
pub trait Min<M: Multi> {
/// Compares elements in `a` and `b`, and finds the minimum values.
  fn min(&self, a: M, b: M) -> M;
}

/// The `Max` trait is used to specify maximum comparison functionality.
pub trait Max<M: Multi> {
/// Compares elements in `a` and `b`, and finds the maximum values.
  fn max(&self, a: M, b: M) -> M;
}

/// The `Shli` trait is used to specify immediate bit-wise left shift functionality.
pub trait Shli<M: Multi> {
/// Shifts all elements in the `a` left by `i` bits.
  fn shli(&self, a: M, i: i32) -> M;
}

/// The `Shri` trait is used to specify immediate bit-wise right shift functionality.
pub trait Shri<M: Multi> {
/// Shifts all elements in the `a` right by `i` bits.
  fn shri(&self, a: M, i32) -> M;
}

/// The `Mullo` trait is used to specify low element-wise multiplication functionality.
pub trait Mullo<M: Multi> {
/// Multiplies the elements in `a` and `b` and stores the lower halves of the results.
  fn mullo(&self, a: M, b: M) -> M;
}

/// The `Mulhi` trait is used to specify high element-wise multiplication functionality.
pub trait Mulhi<M: Multi> {
/// Multiplies the elements in `a` and `b` and stores the higher halves of the results.
  fn mulhi(&self, a: M, b: M) -> M;
}

/// The `Abs` trait is used to specify absolute value computation functionality.
pub trait Abs<M: Multi> {
/// Computes the absolute value of the elements in `a`
  fn abs(&self, a: M) -> M;
}

/// The `HAdd` trait is used to specify horizontal addition functionality.
pub trait HAdd<M: Multi> {
/// Horizontally adds adjacent pairs of elements in `a` and `b`.
  fn hadd(&self, a: M, b: M) -> M;
}

/// The `HSub` trait is used to specify horizontal subtraction functionality.
pub trait HSub<M: Multi> {
/// Horizontally subtracts adjacent pairs of elements in `a` and `b`.
  fn hsub(&self, a: M, b: M) -> M;
}

/// The `Sign` trait is used to specify negation functionality.
pub trait Sign<M: Multi> {
/// Negates elements in `a` if the corresponding element in `b` is negative.
/// Zeroes out the element if the corresponding element in `b` is zero.
  fn sign(&self, a: M, b: M) -> M;
}

/// The `PackS` trait is used to specify signed element narrowing functionality.
pub trait PackS<M: Multi + Narrow> {
/// Narrows elements from `a` and `b` using signed saturation.
  fn packs(&self, a: M, b: M) -> M::Narrow;
}

/// The `PackUS` trait is used to specify unsigned element narrowing functionality.
pub trait PackUS<M: Multi + Narrow> {
/// Narrows elements from `a` and `b` using unsigned saturation.
  fn packus(&self, a: M, b: M) -> M::Narrow;
}

/// CPU identification and feature detection, as well as trait implementations.
pub mod arch {

  enum Token { Token }

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
  pub mod x86;

#[cfg(target_arch = "arm")]
  pub mod arm;

}
<|endoftext|>


<commit_before>#![license = "MIT"]
#![deny(missing_docs)]
#![feature(unsafe_destructor)]

//! A library for setting current values for stack scope,
//! such as application structure.

pub use current::{ Current, CurrentGuard };

use std::cell::RefCell;

mod current;

/// Specifies whether to use a shared reference,
/// or the current object of that type.
pub enum Usage<'a, T: 'a> {
    /// Use a shared reference.
    Use(&'a RefCell<T>),
    /// Use the current object.
    UseCurrent,
}

impl<'a, T: 'a> Usage<'a, T> {
    /// Calls closure with a shared reference to used object.
    pub fn with<U>(&self, f: |&RefCell<T>| -> U) -> Option<U> {
        match *self {
            Use(val) => Some(f(val)),
            UseCurrent => Current::with_current(f),
        }
    }

    /// Calls closure with a shared reference to used object.
    /// Gives a nicer error message if current object is not set.
    pub fn with_unwrap<U>(&self, f: |&RefCell<T>| -> U) -> U {
        match *self {
            Use(val) => f(val),
            UseCurrent => Current::with_current_unwrap(f),
        }
    }

    /// Unwraps to the scope of usage.
    /// Should only be called when the usage object or returned reference
    /// does not outlives the guard of the current object.
    #[inline(always)]
    pub unsafe fn unsafe_unwrap(&self) -> &RefCell<T> {
        match *self {
            Use(val) => val,
            UseCurrent => {
                Current::with_current_unwrap(|current: &RefCell<T>| {
                    use std::mem::transmute;
                    transmute(current)
                })
            }
        }
    }
}

impl<'a, T: Get<U>, U> Get<U> for Usage<'a, T> {
    #[inline(always)]
    fn get(&self) -> U {
        self.with_unwrap(|val: &RefCell<T>| {
            val.borrow().deref().get()
        })
    }
}

impl<'a, F, T: Modifier<F>> Modifier<Usage<'a, F>> for T {
    #[inline(always)]
    fn modify(self, obj: &mut Usage<'a, F>) {
        unsafe {
            let val: &RefCell<F> = obj.unsafe_unwrap();
            self.modify(val.borrow_mut().deref_mut())
        }
    }
}

impl<T: Get<U>, U> Get<U> for RefCell<T> {
    #[inline(always)]
    fn get(&self) -> U {
        self.borrow().deref().get()
    }
}

impl<F, T: Modifier<F>> Modifier<RefCell<F>> for T {
    #[inline(always)]
    fn modify(self, obj: &mut RefCell<F>) {
        self.modify(obj.borrow_mut().deref_mut())
    }
}

/// Allows use of the implemented type as an argument to Set::set.
///
/// This allows types to be used for ad-hoc overloading of Set::set
/// to perform complex updates to the parameter of Modifier.
pub trait Modifier<F> {
    /// Modify `F` with self.
    fn modify(self, &mut F);
}

/// A blanket trait providing the set and set_mut methods for all types.
pub trait Set<M: Modifier<Self>> {
    /// Modify self using the provided modifier.
    #[inline(always)]
    fn set(mut self, modifier: M) -> Self {
        modifier.modify(&mut self);
        self
    }

    /// Modify self through a mutable reference with the provided modifier.
    #[inline(always)]
    fn set_mut(&mut self, modifier: M) -> &mut Self {
        modifier.modify(self);
        self
    }
}

impl<T, U: Modifier<T>> Set<U> for T {}

/// Implemented by types that can be constructed from another value.
pub trait Get<T> {
    /// Returns new value.
    fn get(&self) -> T;
}

/// Transmutes the current value to a lifetime scope.
/// The scope must not outlive the guard.
/// This is used to work around issues with closure that require move by value.
pub unsafe fn unsafe_current_unwrap<T>(_scope: &()) -> &T {
    Current::with_current_unwrap(|current: &T| {
        use std::mem::transmute;
        transmute(current)
    })
}

/// Sets value on current type, assuming using a `RefCell` to make it safe.
/// Panics if there is no current object of type `T`.
pub fn set<T, U: Modifier<T>>(val: U) {
    let scope = &();
    let current: &RefCell<T> = unsafe { unsafe_current_unwrap(scope) };
    val.modify(&mut*current.borrow_mut());
}

/// Gets value from current object of type `T`.
/// The returned type must implement the `GetFrom` trait.
pub fn get<T: Get<U>, U>() -> U {
    Current::with_current_unwrap(|current: &RefCell<T>| {
        match current.try_borrow() {
            Some(val) => val.get(),
            None => {
                use std::intrinsics::get_tydesc;
                let name = unsafe { (*get_tydesc::<T>()).name };
                panic!("The current `{}` is already in use", name);
            }
        }
    })
}
<commit_msg>Changed to `Modifier<&'a RefCell<F>>`<commit_after>#![license = "MIT"]
#![deny(missing_docs)]
#![feature(unsafe_destructor)]

//! A library for setting current values for stack scope,
//! such as application structure.

pub use current::{ Current, CurrentGuard };

use std::cell::RefCell;

mod current;

/// Specifies whether to use a shared reference,
/// or the current object of that type.
pub enum Usage<'a, T: 'a> {
    /// Use a shared reference.
    Use(&'a RefCell<T>),
    /// Use the current object.
    UseCurrent,
}

impl<'a, T: 'a> Usage<'a, T> {
    /// Calls closure with a shared reference to used object.
    pub fn with<U>(&self, f: |&RefCell<T>| -> U) -> Option<U> {
        match *self {
            Use(val) => Some(f(val)),
            UseCurrent => Current::with_current(f),
        }
    }

    /// Calls closure with a shared reference to used object.
    /// Gives a nicer error message if current object is not set.
    pub fn with_unwrap<U>(&self, f: |&RefCell<T>| -> U) -> U {
        match *self {
            Use(val) => f(val),
            UseCurrent => Current::with_current_unwrap(f),
        }
    }

    /// Unwraps to the scope of usage.
    /// Should only be called when the usage object or returned reference
    /// does not outlives the guard of the current object.
    #[inline(always)]
    pub unsafe fn unsafe_unwrap(&self) -> &RefCell<T> {
        match *self {
            Use(val) => val,
            UseCurrent => {
                Current::with_current_unwrap(|current: &RefCell<T>| {
                    use std::mem::transmute;
                    transmute(current)
                })
            }
        }
    }
}

impl<'a, T: Get<U>, U> Get<U> for Usage<'a, T> {
    #[inline(always)]
    fn get(&self) -> U {
        self.with_unwrap(|val: &RefCell<T>| {
            val.borrow().deref().get()
        })
    }
}

impl<'a, F, T: Modifier<F>> Modifier<Usage<'a, F>> for T {
    #[inline(always)]
    fn modify(self, obj: &mut Usage<'a, F>) {
        unsafe {
            let val: &RefCell<F> = obj.unsafe_unwrap();
            self.modify(val.borrow_mut().deref_mut())
        }
    }
}

impl<T: Get<U>, U> Get<U> for RefCell<T> {
    #[inline(always)]
    fn get(&self) -> U {
        self.borrow().deref().get()
    }
}

impl<'a, F, T: Modifier<F>> Modifier<&'a RefCell<F>> for T {
    #[inline(always)]
    fn modify(self, obj: &mut &'a RefCell<F>) {
        self.modify(obj.borrow_mut().deref_mut())
    }
}

/// Allows use of the implemented type as an argument to Set::set.
///
/// This allows types to be used for ad-hoc overloading of Set::set
/// to perform complex updates to the parameter of Modifier.
pub trait Modifier<F> {
    /// Modify `F` with self.
    fn modify(self, &mut F);
}

/// A blanket trait providing the set and set_mut methods for all types.
pub trait Set<M: Modifier<Self>> {
    /// Modify self using the provided modifier.
    #[inline(always)]
    fn set(mut self, modifier: M) -> Self {
        modifier.modify(&mut self);
        self
    }

    /// Modify self through a mutable reference with the provided modifier.
    #[inline(always)]
    fn set_mut(&mut self, modifier: M) -> &mut Self {
        modifier.modify(self);
        self
    }
}

impl<T, U: Modifier<T>> Set<U> for T {}

/// Implemented by types that can be constructed from another value.
pub trait Get<T> {
    /// Returns new value.
    fn get(&self) -> T;
}

/// Transmutes the current value to a lifetime scope.
/// The scope must not outlive the guard.
/// This is used to work around issues with closure that require move by value.
pub unsafe fn unsafe_current_unwrap<T>(_scope: &()) -> &T {
    Current::with_current_unwrap(|current: &T| {
        use std::mem::transmute;
        transmute(current)
    })
}

/// Sets value on current type, assuming using a `RefCell` to make it safe.
/// Panics if there is no current object of type `T`.
pub fn set<T, U: Modifier<T>>(val: U) {
    let scope = &();
    let current: &RefCell<T> = unsafe { unsafe_current_unwrap(scope) };
    val.modify(&mut*current.borrow_mut());
}

/// Gets value from current object of type `T`.
/// The returned type must implement the `GetFrom` trait.
pub fn get<T: Get<U>, U>() -> U {
    Current::with_current_unwrap(|current: &RefCell<T>| {
        match current.try_borrow() {
            Some(val) => val.get(),
            None => {
                use std::intrinsics::get_tydesc;
                let name = unsafe { (*get_tydesc::<T>()).name };
                panic!("The current `{}` is already in use", name);
            }
        }
    })
}
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone)]
struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(
        &'a mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler)
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern.clone());
            extensions.insert(m.params.clone());
        }

        (*m.handler.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate conduit_test;

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(req.extensions().find::<RoutePattern>().unwrap().0.to_string());

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<commit_msg>Derive `Copy` for `RoutePattern` struct<commit_after>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(
        &'a mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler)
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<'a, H: Handler>(&'a mut self, pattern: &'static str, handler: H) -> &'a mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern);
            extensions.insert(m.params.clone());
        }

        (*m.handler.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate conduit_test;

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(req.extensions().find::<RoutePattern>().unwrap().0.to_string());

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<|endoftext|>


<commit_before>//! Crate ruma_client is a [Matrix](https://matrix.org/) client library.

#![feature(try_from)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

extern crate hyper;
extern crate ruma_client_api;
extern crate ruma_identifiers;
extern crate serde;
extern crate serde_json;
extern crate url;

use std::convert::TryInto;

use hyper::client::{Client as Hyper, IntoUrl};
use hyper::method::Method as HyperMethod;
use ruma_client_api::{Endpoint, Method, supported_versions};
use url::Url;

pub use error::Error;
pub use session::Session;
pub use response::Response;

mod error;
mod response;
mod session;

/// A client for the Matrix client-server API.
#[derive(Debug)]
pub struct Client {
    homeserver_url: Url,
    hyper: Hyper,
    session: Option<Session>,
}

trait IntoHyperMethod {
    fn into_hyper(self) -> HyperMethod;
}

impl IntoHyperMethod for Method {
    fn into_hyper(self) -> HyperMethod {
        match self {
            Method::Delete => HyperMethod::Delete,
            Method::Get => HyperMethod::Get,
            Method::Put => HyperMethod::Put,
            Method::Post => HyperMethod::Post,
        }
    }
}

impl Client {
    /// Creates a new client for making requests to the given homeserver.
    ///
    /// # Errors
    ///
    /// Returns an error if the given homserver URL cannot be parsed as a URL.
    pub fn new<U>(homeserver_url: U) -> Result<Self, Error> where U: IntoUrl {
        Ok(Client {
            homeserver_url: homeserver_url.into_url()?,
            hyper: Hyper::new(),
            session: None,
        })
    }

    /// Get the versions of the Matrix client-server specification supported by the homeserver.
    pub fn get_supported_versions(&self)
    -> Result<Response<<supported_versions::Endpoint as Endpoint>::Response>, Error> {
        let response = self.hyper.request(
            supported_versions::Endpoint::method().into_hyper(),
            self.homeserver_url.join(&supported_versions::Endpoint::request_path(()))?,
        ).send()?;

        Ok(response.try_into()?)
    }
}
<commit_msg>Update get_supported_versions for new module structure in ruma-client-api.<commit_after>//! Crate ruma_client is a [Matrix](https://matrix.org/) client library.

#![feature(try_from)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

extern crate hyper;
extern crate ruma_client_api;
extern crate ruma_identifiers;
extern crate serde;
extern crate serde_json;
extern crate url;

use std::convert::TryInto;

use hyper::client::{Client as Hyper, IntoUrl};
use hyper::method::Method as HyperMethod;
use ruma_client_api::{Endpoint, Method};
use ruma_client_api::unversioned::get_supported_versions;
use url::Url;

pub use error::Error;
pub use session::Session;
pub use response::Response;

mod error;
mod response;
mod session;

/// A client for the Matrix client-server API.
#[derive(Debug)]
pub struct Client {
    homeserver_url: Url,
    hyper: Hyper,
    session: Option<Session>,
}

trait IntoHyperMethod {
    fn into_hyper(self) -> HyperMethod;
}

impl IntoHyperMethod for Method {
    fn into_hyper(self) -> HyperMethod {
        match self {
            Method::Delete => HyperMethod::Delete,
            Method::Get => HyperMethod::Get,
            Method::Put => HyperMethod::Put,
            Method::Post => HyperMethod::Post,
        }
    }
}

impl Client {
    /// Creates a new client for making requests to the given homeserver.
    ///
    /// # Errors
    ///
    /// Returns an error if the given homserver URL cannot be parsed as a URL.
    pub fn new<U>(homeserver_url: U) -> Result<Self, Error> where U: IntoUrl {
        Ok(Client {
            homeserver_url: homeserver_url.into_url()?,
            hyper: Hyper::new(),
            session: None,
        })
    }

    /// Get the versions of the Matrix client-server specification supported by the homeserver.
    pub fn get_supported_versions(&self)
    -> Result<Response<<get_supported_versions::Endpoint as Endpoint>::Response>, Error> {
        let response = self.hyper.request(
            supported_versions::Endpoint::method().into_hyper(),
            self.homeserver_url.join(&supported_versions::Endpoint::request_path(()))?,
        ).send()?;

        Ok(response.try_into()?)
    }
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(convert)]

use std::borrow::Cow;
use std::borrow::Cow::{Borrowed};
use std::collections::HashMap;

pub fn compile(sass: &str, style: &str) -> Result<String, &'static str> {
    let mut st = SassTokenizer::new(&sass);

    match style {
        "nested"     => Ok(nested_output(&mut st)),
        "compressed" => Ok(compressed_output(&mut st)),
        "expanded"   => Ok(expanded_output(&mut st)),
        "compact"    => Ok(compact_output(&mut st)),
        "debug"      => Ok(debug_output(&mut st)),
        _            => Err("Unknown style:. Please specify one of nested, compressed, expanded, or compact."),
    }
}

pub fn substitute_variables<'a>(value: &'a str, substitutions: &'a HashMap<String, String>) -> String {
    value.split(' ').map(|value_part|
        match substitutions.get(value_part) {
            Some(v) => &v[..],
            None => value_part,
        }
    ).collect::<Vec<_>>().connect(" ")
}

pub fn nested_output(tokenizer: &mut SassTokenizer) -> String {
    let mut output = String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables: HashMap<String, String> = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => format!("{} ", name),
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!("{{\n  {}: {};", name, real_value),
                    _ => format!("\n  {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!(" }}\n"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn compressed_output(tokenizer: &mut SassTokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!("{{{}:{}", name, real_value),
                    Event::Property(_, _) => format!(";{}:{}", name, real_value),
                    _ => format!("{}:{}", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!("}}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn expanded_output(tokenizer: &mut SassTokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    Event::End(_) => format!("\n{}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!(" {{\n  {}: {};", name, real_value),
                    _ => format!("\n  {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!("\n}}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn compact_output(tokenizer: &mut SassTokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    Event::End(_) => format!("\n{}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!(" {{ {}: {};", name, real_value),
                    _ => format!(" {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!(" }}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn debug_output(tokenizer: &mut SassTokenizer) -> String {
    let mut output =  String::from_str("");
    while let Some(token) = tokenizer.next() {
        output.push_str(format!("{:?}\n", token).as_str());
    }
    output
}

#[derive(PartialEq, Debug)]
pub enum State {
    StartRule,
    InSelectors,
    InProperties,
}

#[derive(Debug,Clone)]
pub enum Rule {
    SassRule,
}

#[derive(Debug,Clone)]
pub enum Event<'a> {
    Start(Rule),
    End(Rule),
    Selector(Cow<'a, str>),
    Property(Cow<'a, str>, Cow<'a, str>),
    Variable(Cow<'a, str>, Cow<'a, str>),
}

#[derive(Debug)]
pub struct SassTokenizer<'a> {
    sass: &'a str,
    offset: usize,
    stack: Vec<Rule>,
    state: State,
}

impl<'a> SassTokenizer<'a> {
    pub fn new(sass: &'a str) -> SassTokenizer<'a> {
        SassTokenizer {
            sass: &sass,
            offset: 0,
            stack: Vec::new(),
            state: State::StartRule,
        }
    }

    pub fn start_rule(&mut self) -> Option<Event<'a>> {
        self.skip_leading_whitespace();

        if self.offset == self.sass.len() {
            return None
        }

        let c = self.sass.as_bytes()[self.offset];
        if c == b'}' {
            self.offset += 1;
            return Some(self.end())
        }
        if c == b'$' {
            return Some(self.next_variable())
        }

        self.state = State::InSelectors;
        self.stack.push(Rule::SassRule);

        Some(Event::Start(Rule::SassRule))
    }

    fn end(&mut self) -> Event<'a> {
        let rule = match self.stack.pop() {
            Some(r) => r,
            None => {
                println!("Unexpected empty stack!");
                return Event::End(Rule::SassRule)
            },
        };
        self.state = State::StartRule;
        Event::End(rule)
    }

    fn scan_while<F>(&mut self, data: &str, f: F) -> usize
            where F: Fn(u8) -> bool {
        match data.as_bytes().iter().position(|&c| !f(c)) {
            Some(i) => i,
            None => data.len()
        }
    }

    fn skip_leading_whitespace(&mut self) {
        let i = self.offset;
        self.offset += self.scan_while(&self.sass[i..self.sass.len()], is_ascii_whitespace);
    }

    pub fn next_variable(&mut self) -> Event<'a> {
        // TODO: can parts of this be deduplicated with properties?
        let bytes = self.sass.as_bytes();
        let name_beginning = self.offset;
        let mut i = name_beginning;
        let limit = self.sass.len();

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b':' ) {
                Some(pos) => { i += pos; },
                None => { break; },
            }

            let name_end = i;

            i += 1;
            self.offset = i;
            self.skip_leading_whitespace();

            let value_beginning = self.offset;
            i = value_beginning;

            while i < limit {
                match bytes[i..limit].iter().position(|&c| c == b';') {
                    Some(pos) => { i += pos; },
                    None => { i = limit; break; },
                }

                let value_end = i;
                self.offset = i + 1;

                self.skip_leading_whitespace();

                return Event::Variable(
                    Borrowed(&self.sass[name_beginning..name_end]),
                    Borrowed(&self.sass[value_beginning..value_end])
                )
            }
        }
        self.offset = self.sass.len();
        Event::Property(Borrowed(""), Borrowed(""))
    }

    pub fn next_property(&mut self) -> Event<'a> {
        self.skip_leading_whitespace();

        let bytes = self.sass.as_bytes();
        let name_beginning = self.offset;
        let mut i = name_beginning;
        let limit = self.sass.len();

        let c = bytes[i];
        if c == b'}' {
            self.offset += 1;
            return self.end()
        }

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b':' || c == b'{') {
                Some(pos) => { i += pos; },
                None => { break; },
            }

            // Inefficient since we already skipped the whitespace and we'll have to
            // do it again but oh well
            let c = bytes[i];
            if c == b'{' {
                self.state = State::InSelectors;
                self.stack.push(Rule::SassRule);
                return Event::Start(Rule::SassRule)
            }

            let name_end = i;

            i += 1;
            self.offset = i;
            self.skip_leading_whitespace();

            let value_beginning = self.offset;
            i = value_beginning;

            while i < limit {
                match bytes[i..limit].iter().position(|&c| c == b';') {
                    Some(pos) => { i += pos; },
                    None => { i = limit; break; },
                }

                let value_end = i;
                self.offset = i + 1;

                self.skip_leading_whitespace();

                return Event::Property(
                    Borrowed(&self.sass[name_beginning..name_end]),
                    Borrowed(&self.sass[value_beginning..value_end])
                )

            }
        }
        self.offset = self.sass.len();
        Event::Property(Borrowed(""), Borrowed(""))
    }

    pub fn next_selector(&mut self) -> Event<'a> {
        let bytes = self.sass.as_bytes();
        let beginning = self.offset;
        let mut i = beginning;
        let limit = self.sass.len();

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b',' || c == b'{') {
                Some(pos) => { i += pos; },
                None => { i = limit; break; },
            }

            let c = bytes[i];

            if c == b',' || c == b'{' {
                let n = scan_trailing_whitespace(&self.sass[beginning..i]);
                let end = i - n;
                if end > beginning {
                    if c == b'{' {
                        self.state = State::InProperties;
                    }
                    self.offset = i + 1;
                    return Event::Selector(Borrowed(&self.sass[beginning..end]));
                }
            }

            self.offset = i;
            if i > beginning {
                return Event::Selector(Borrowed(&self.sass[beginning..i]))
            }
            i += 1;
        }

        if i > beginning {
            self.offset = i;
            Event::Selector(Borrowed(&self.sass[beginning..i]))
        } else {
            self.end()
        }
    }
}

impl<'a> Iterator for SassTokenizer<'a> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Event<'a>> {
        if self.offset < self.sass.len() {
            match self.state {
                State::StartRule => {
                    let ret = self.start_rule();
                    if ret.is_some() {
                        return ret
                    }
                },
                State::InSelectors => return Some(self.next_selector()),
                State::InProperties => return Some(self.next_property()),
            }
        }
        None
    }
}

pub fn char_at(s: &str, byte: usize) -> char {
    s[byte..].chars().next().unwrap()
}

pub fn is_ascii_whitespace(c: u8) -> bool {
    c == b'\n' || c == b'\r' || is_ascii_whitespace_no_nl(c)
}

pub fn is_ascii_whitespace_no_nl(c: u8) -> bool {
    c == b'\t' || c == 0x0b || c == 0x0c || c == b' '
}

// unusual among "scan" functions in that it scans from the _back_ of the string
// TODO: should also scan unicode whitespace?
pub fn scan_trailing_whitespace(data: &str) -> usize {
    match data.as_bytes().iter().rev().position(|&c| !is_ascii_whitespace_no_nl(c)) {
        Some(i) => i,
        None => data.len()
    }
}
<commit_msg>Rename SassTokenizer to Tokenizer<commit_after>#![feature(collections)]
#![feature(convert)]

use std::borrow::Cow;
use std::borrow::Cow::{Borrowed};
use std::collections::HashMap;

pub fn compile(sass: &str, style: &str) -> Result<String, &'static str> {
    let mut st = Tokenizer::new(&sass);

    match style {
        "nested"     => Ok(nested_output(&mut st)),
        "compressed" => Ok(compressed_output(&mut st)),
        "expanded"   => Ok(expanded_output(&mut st)),
        "compact"    => Ok(compact_output(&mut st)),
        "debug"      => Ok(debug_output(&mut st)),
        _            => Err("Unknown style:. Please specify one of nested, compressed, expanded, or compact."),
    }
}

pub fn substitute_variables<'a>(value: &'a str, substitutions: &'a HashMap<String, String>) -> String {
    value.split(' ').map(|value_part|
        match substitutions.get(value_part) {
            Some(v) => &v[..],
            None => value_part,
        }
    ).collect::<Vec<_>>().connect(" ")
}

pub fn nested_output(tokenizer: &mut Tokenizer) -> String {
    let mut output = String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables: HashMap<String, String> = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => format!("{} ", name),
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!("{{\n  {}: {};", name, real_value),
                    _ => format!("\n  {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!(" }}\n"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn compressed_output(tokenizer: &mut Tokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!("{{{}:{}", name, real_value),
                    Event::Property(_, _) => format!(";{}:{}", name, real_value),
                    _ => format!("{}:{}", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!("}}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn expanded_output(tokenizer: &mut Tokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    Event::End(_) => format!("\n{}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!(" {{\n  {}: {};", name, real_value),
                    _ => format!("\n  {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!("\n}}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn compact_output(tokenizer: &mut Tokenizer) -> String {
    let mut output =  String::from_str("");
    let mut last = Event::End(Rule::SassRule);
    let mut variables = HashMap::new();

    while let Some(token) = tokenizer.next() {
        let print_token = match token.clone() {
            Event::Start(_) => continue,
            Event::Variable(name, value) => {
                let val = substitute_variables(&value, &variables);
                variables.insert((*name).to_string(), val);
                continue
            },
            Event::Selector(name) => {
                match last {
                    Event::Selector(_) => format!(" {}", name),
                    Event::End(_) => format!("\n{}", name),
                    _ => format!("{}", name),
                }
            },
            Event::Property(name, value) => {
                let real_value = substitute_variables(&value, &variables);
                match last {
                    Event::Selector(_) => format!(" {{ {}: {};", name, real_value),
                    _ => format!(" {}: {};", name, real_value),
                }
            },
            Event::End(_) => {
                match last {
                    Event::End(_) => continue,
                    _ => format!(" }}"),
                }
            },
        };
        output.push_str(print_token.as_str());
        last = token;
    }
    output
}

pub fn debug_output(tokenizer: &mut Tokenizer) -> String {
    let mut output =  String::from_str("");
    while let Some(token) = tokenizer.next() {
        output.push_str(format!("{:?}\n", token).as_str());
    }
    output
}

#[derive(PartialEq, Debug)]
pub enum State {
    StartRule,
    InSelectors,
    InProperties,
}

#[derive(Debug,Clone)]
pub enum Rule {
    SassRule,
}

#[derive(Debug,Clone)]
pub enum Event<'a> {
    Start(Rule),
    End(Rule),
    Selector(Cow<'a, str>),
    Property(Cow<'a, str>, Cow<'a, str>),
    Variable(Cow<'a, str>, Cow<'a, str>),
}

#[derive(Debug)]
pub struct Tokenizer<'a> {
    sass: &'a str,
    offset: usize,
    stack: Vec<Rule>,
    state: State,
}

impl<'a> Tokenizer<'a> {
    pub fn new(sass: &'a str) -> Tokenizer<'a> {
        Tokenizer {
            sass: &sass,
            offset: 0,
            stack: Vec::new(),
            state: State::StartRule,
        }
    }

    pub fn start_rule(&mut self) -> Option<Event<'a>> {
        self.skip_leading_whitespace();

        if self.offset == self.sass.len() {
            return None
        }

        let c = self.sass.as_bytes()[self.offset];
        if c == b'}' {
            self.offset += 1;
            return Some(self.end())
        }
        if c == b'$' {
            return Some(self.next_variable())
        }

        self.state = State::InSelectors;
        self.stack.push(Rule::SassRule);

        Some(Event::Start(Rule::SassRule))
    }

    fn end(&mut self) -> Event<'a> {
        let rule = match self.stack.pop() {
            Some(r) => r,
            None => {
                println!("Unexpected empty stack!");
                return Event::End(Rule::SassRule)
            },
        };
        self.state = State::StartRule;
        Event::End(rule)
    }

    fn scan_while<F>(&mut self, data: &str, f: F) -> usize
            where F: Fn(u8) -> bool {
        match data.as_bytes().iter().position(|&c| !f(c)) {
            Some(i) => i,
            None => data.len()
        }
    }

    fn skip_leading_whitespace(&mut self) {
        let i = self.offset;
        self.offset += self.scan_while(&self.sass[i..self.sass.len()], is_ascii_whitespace);
    }

    pub fn next_variable(&mut self) -> Event<'a> {
        // TODO: can parts of this be deduplicated with properties?
        let bytes = self.sass.as_bytes();
        let name_beginning = self.offset;
        let mut i = name_beginning;
        let limit = self.sass.len();

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b':' ) {
                Some(pos) => { i += pos; },
                None => { break; },
            }

            let name_end = i;

            i += 1;
            self.offset = i;
            self.skip_leading_whitespace();

            let value_beginning = self.offset;
            i = value_beginning;

            while i < limit {
                match bytes[i..limit].iter().position(|&c| c == b';') {
                    Some(pos) => { i += pos; },
                    None => { i = limit; break; },
                }

                let value_end = i;
                self.offset = i + 1;

                self.skip_leading_whitespace();

                return Event::Variable(
                    Borrowed(&self.sass[name_beginning..name_end]),
                    Borrowed(&self.sass[value_beginning..value_end])
                )
            }
        }
        self.offset = self.sass.len();
        Event::Property(Borrowed(""), Borrowed(""))
    }

    pub fn next_property(&mut self) -> Event<'a> {
        self.skip_leading_whitespace();

        let bytes = self.sass.as_bytes();
        let name_beginning = self.offset;
        let mut i = name_beginning;
        let limit = self.sass.len();

        let c = bytes[i];
        if c == b'}' {
            self.offset += 1;
            return self.end()
        }

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b':' || c == b'{') {
                Some(pos) => { i += pos; },
                None => { break; },
            }

            // Inefficient since we already skipped the whitespace and we'll have to
            // do it again but oh well
            let c = bytes[i];
            if c == b'{' {
                self.state = State::InSelectors;
                self.stack.push(Rule::SassRule);
                return Event::Start(Rule::SassRule)
            }

            let name_end = i;

            i += 1;
            self.offset = i;
            self.skip_leading_whitespace();

            let value_beginning = self.offset;
            i = value_beginning;

            while i < limit {
                match bytes[i..limit].iter().position(|&c| c == b';') {
                    Some(pos) => { i += pos; },
                    None => { i = limit; break; },
                }

                let value_end = i;
                self.offset = i + 1;

                self.skip_leading_whitespace();

                return Event::Property(
                    Borrowed(&self.sass[name_beginning..name_end]),
                    Borrowed(&self.sass[value_beginning..value_end])
                )

            }
        }
        self.offset = self.sass.len();
        Event::Property(Borrowed(""), Borrowed(""))
    }

    pub fn next_selector(&mut self) -> Event<'a> {
        let bytes = self.sass.as_bytes();
        let beginning = self.offset;
        let mut i = beginning;
        let limit = self.sass.len();

        while i < limit {
            match bytes[i..limit].iter().position(|&c| c == b',' || c == b'{') {
                Some(pos) => { i += pos; },
                None => { i = limit; break; },
            }

            let c = bytes[i];

            if c == b',' || c == b'{' {
                let n = scan_trailing_whitespace(&self.sass[beginning..i]);
                let end = i - n;
                if end > beginning {
                    if c == b'{' {
                        self.state = State::InProperties;
                    }
                    self.offset = i + 1;
                    return Event::Selector(Borrowed(&self.sass[beginning..end]));
                }
            }

            self.offset = i;
            if i > beginning {
                return Event::Selector(Borrowed(&self.sass[beginning..i]))
            }
            i += 1;
        }

        if i > beginning {
            self.offset = i;
            Event::Selector(Borrowed(&self.sass[beginning..i]))
        } else {
            self.end()
        }
    }
}

impl<'a> Iterator for Tokenizer<'a> {
    type Item = Event<'a>;

    fn next(&mut self) -> Option<Event<'a>> {
        if self.offset < self.sass.len() {
            match self.state {
                State::StartRule => {
                    let ret = self.start_rule();
                    if ret.is_some() {
                        return ret
                    }
                },
                State::InSelectors => return Some(self.next_selector()),
                State::InProperties => return Some(self.next_property()),
            }
        }
        None
    }
}

pub fn char_at(s: &str, byte: usize) -> char {
    s[byte..].chars().next().unwrap()
}

pub fn is_ascii_whitespace(c: u8) -> bool {
    c == b'\n' || c == b'\r' || is_ascii_whitespace_no_nl(c)
}

pub fn is_ascii_whitespace_no_nl(c: u8) -> bool {
    c == b'\t' || c == 0x0b || c == 0x0c || c == b' '
}

// unusual among "scan" functions in that it scans from the _back_ of the string
// TODO: should also scan unicode whitespace?
pub fn scan_trailing_whitespace(data: &str) -> usize {
    match data.as_bytes().iter().rev().position(|&c| !is_ascii_whitespace_no_nl(c)) {
        Some(i) => i,
        None => data.len()
    }
}
<|endoftext|>


<commit_before>extern crate log;

use std::io::{Write, stderr};
use std::sync::Mutex;

use log::{Log, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError};

pub struct Writer(pub Box<Write + Send>);

struct Logger {
    writers: Mutex<Vec<Writer>>,
}

impl Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, rec: &LogRecord) {
        let mut writers = match self.writers.lock() {
            Ok(writers) => writers,
            Err(err) => {let _ = writeln!(stderr(), "{:?}", err); return},
        };
        let loc = rec.location();
        for i in 0..writers.len() {
            let _ = writeln!(
                writers[i].0,
                "{}:{}:{}:{}:\t{}",
                loc.module_path(), loc.file(), loc.line(),
                rec.level(), rec.args());
        }
    }
}

pub fn init(writers: Vec<Writer>) -> Result<(), SetLoggerError> {
    log::set_logger(|max_level| {
        max_level.set(LogLevelFilter::max());
        Box::new(Logger {writers: Mutex::new(writers)})
    })
}
<commit_msg>Improved code<commit_after>extern crate log;

use std::io::{Write, stderr};
use std::sync::Mutex;

use log::{Log, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError};

pub struct Writer(pub Box<Write + Send>);

struct Logger {
    writers: Mutex<Vec<Writer>>,
}

impl Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, rec: &LogRecord) {
        let mut writers = match self.writers.lock() {
            Ok(writers) => writers,
            Err(err) => {
                let _ = writeln!(stderr(), "{:?}", err);
                return;
            },
        };
        let loc = rec.location();
        for i in 0..writers.len() {
            let _ = writeln!(
                writers[i].0,
                "{}:{}:{}:{}:\t{}",
                loc.module_path(), loc.file(), loc.line(),
                rec.level(), rec.args());
        }
    }
}

pub fn init(writers: Vec<Writer>) -> Result<(), SetLoggerError> {
    log::set_logger(|max_level| {
        max_level.set(LogLevelFilter::max());
        Box::new(Logger {writers: Mutex::new(writers)})
    })
}
<|endoftext|>


<commit_before>#[allow(dead_code)]
pub struct RealVector<'a>
{
	data: &'a mut[f64],
	length_valids: usize,
	delta: f64
}

#[allow(dead_code)]
impl<'a> RealVector<'a>
{
	fn new<'b>(data: &'b mut[f64]) -> RealVector<'b>
	{
		let length_valids = data.len();
		return RealVector { data: data, length_valids: length_valids, delta: 1.0 };
	}

    fn len(&self) -> usize
	{
		let array_length = self.data.len();
        if  self.length_valids < array_length
		{
			return self.length_valids;
		}
		else
		{
			return array_length;
		}
    }

	fn allocated_length(&self) -> usize
	{
		return self.data.len();
	}
}

pub fn add_one(data: &mut RealVector)
{
	for i in 0..data.len()
	{
		data.data[i] = data.data[i] + 1.0;
	}
}

#[test]
fn add_one_test()
{
	let mut result =
	RealVector
	{
		data: &mut[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
		length_valids: 10,
		delta: 1.0
	};
	add_one(&mut result);
	assert_eq!(result.data, [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]);
}

#[test]
fn add_one_test_odd_number_of_elements()
{
	let mut result =
	RealVector
	{
		data: &mut[1.0, 2.0, 3.0],
		length_valids: 3,
		delta: 1.0
	};
	add_one(&mut result);
	assert_eq!(result.data, [2.0, 3.0, 4.0]);
}<commit_msg>Fixed indention<commit_after>#[allow(dead_code)]
pub struct RealVector<'a>
{
	data: &'a mut[f64],
	length_valids: usize,
	delta: f64
}

#[allow(dead_code)]
impl<'a> RealVector<'a>
{
	fn new<'b>(data: &'b mut[f64]) -> RealVector<'b>
	{
		let length_valids = data.len();
		return RealVector { data: data, length_valids: length_valids, delta: 1.0 };
	}

    fn len(&self) -> usize
	{
		let array_length = self.data.len();
        if  self.length_valids < array_length
		{
			return self.length_valids;
		}
		else
		{
			return array_length;
		}
    }

	fn allocated_length(&self) -> usize
	{
		return self.data.len();
	}
}

pub fn add_one(data: &mut RealVector)
{
	for i in 0..data.len()
	{
		data.data[i] = data.data[i] + 1.0;
	}
}

#[test]
fn add_one_test()
{
	let mut result =
		RealVector
		{
			data: &mut[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
			length_valids: 10,
			delta: 1.0
		};
	add_one(&mut result);
	assert_eq!(result.data, [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]);
}

#[test]
fn add_one_test_odd_number_of_elements()
{
	let mut result =
		RealVector
		{
			data: &mut[1.0, 2.0, 3.0],
			length_valids: 3,
			delta: 1.0
		};
	add_one(&mut result);
	assert_eq!(result.data, [2.0, 3.0, 4.0]);
}<|endoftext|>


<commit_before>#![feature(collections)]

#[derive(Copy, Clone)]
pub enum Case {
    Upper,
    Lower
}

pub trait ChangeCase {
    fn to_uppercase<'a>(&'a self) -> String;
    fn to_lowercase<'a>(&'a self) -> String;
    fn to_capitalized<'a>(&'a self) -> String;
    fn to_invertedcase<'a>(&'a self) -> String;
    fn to_altcase<'a>(&'a self, start_with: Case) -> String;
}

impl<'a> ChangeCase for String {
    fn to_uppercase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            for c in self.chars() {
                let upper = c.to_uppercase().next().unwrap();
                result.push(upper);
            }
        }

        result
    }

    fn to_lowercase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            for c in self.chars() {
                let lower = c.to_lowercase().next().unwrap();
                result.push(lower);
            }
        }

        result
    }

    fn to_capitalized(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            let mut chars = self.chars();
            let first = chars.next().unwrap().to_uppercase().next().unwrap();
            result.push(first);

            for c in chars {
                let lower = c.to_lowercase().next().unwrap();
                result.push(lower);
            }
        }

        result
    }

    fn to_invertedcase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {

            for c in self.chars() {
                if c.is_uppercase() {
                    let lower = c.to_lowercase().next().unwrap();
                    result.push(lower);
                } else if c.is_lowercase() {
                    let upper = c.to_uppercase().next().unwrap();
                    result.push(upper);
                } else {
                    result.push(c);
                }
            }
        }

        result
    }

    fn to_altcase(&self, start_with: Case) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            let mut current_case = start_with;

            for c in self.chars() {
                if c.is_uppercase() || c.is_lowercase() {
                    match current_case {
                        Case::Upper => {
                            let upper = c.to_uppercase().next().unwrap();
                            result.push(upper);
                            current_case = Case::Lower;
                        },
                        Case::Lower => {
                            let lower = c.to_lowercase().next().unwrap();
                            result.push(lower);
                            current_case = Case::Upper;
                        }
                    };
                } else {
                    result.push(c);
                }
            }
        }

        result
    }
}

impl<'a> ChangeCase for &'a str {
    fn to_uppercase(&self) -> String {
        String::from_str(self).to_uppercase()
    }
    fn to_lowercase(&self) -> String {
        String::from_str(self).to_lowercase()
    }
    fn to_capitalized(&self) -> String {
        String::from_str(self).to_capitalized()
    }
    fn to_invertedcase(&self) -> String {
        String::from_str(self).to_invertedcase()
    }
    fn to_altcase(&self, start_with: Case) -> String {
        String::from_str(self).to_altcase(start_with)
    }
}

#[test]
fn upper() {
    assert_eq!(String::from_str("Something").to_uppercase(), "SOMETHING");
    assert_eq!(String::from_str("sOmEtHiNg").to_uppercase(), "SOMETHING");
    assert_eq!(String::from_str("word word2").to_uppercase(), "WORD WORD2");
}

#[test]
fn lower() {
    assert_eq!(String::from_str("SOMETHING").to_lowercase(), "something");
    assert_eq!(String::from_str("sOmEtHiNg").to_lowercase(), "something");
    assert_eq!(String::from_str("Word WORD2").to_lowercase(), "word word2");
}

#[test]
fn capitalize() {
    assert_eq!(String::from_str("SOMETHING").to_capitalized(), "Something");
    assert_eq!(String::from_str("sOmEtHiNg").to_capitalized(), "Something");
    assert_eq!(String::from_str("Word WORD2").to_capitalized(), "Word word2");
}

#[test]
fn swapped() {
    assert_eq!(String::from_str("SOMETHING").to_invertedcase(), "something");
    assert_eq!(String::from_str("SoMeThInG").to_invertedcase(), "sOmEtHiNg");
    assert_eq!(String::from_str("Some WorD2").to_invertedcase(), "sOME wORd2");
}

#[test]
fn alternating() {
    assert_eq!(String::from_str("SOMETHING").to_altcase(Case::Lower), "sOmEtHiNg");
    assert_eq!(String::from_str("SOMETHING").to_altcase(Case::Upper), "SoMeThInG");
    assert_eq!(String::from_str("som3thing").to_altcase(Case::Lower), "sOm3ThInG");
    assert_eq!(String::from_str("som3thing").to_altcase(Case::Upper), "SoM3tHiNg");
    assert_eq!(String::from_str("some word").to_altcase(Case::Lower), "sOmE wOrD");
}

#[test]
fn str_lower() {
    assert_eq!("SOMETHING".to_lowercase(), "something");
    assert_eq!("sOmEtHiNg".to_lowercase(), "something");
    assert_eq!("Word WORD2".to_lowercase(), "word word2");
}

#[test]
fn str_capitalize() {
    assert_eq!("SOMETHING".to_capitalized(), "Something");
    assert_eq!("sOmEtHiNg".to_capitalized(), "Something");
    assert_eq!("Word WORD2".to_capitalized(), "Word word2");
}

#[test]
fn str_swapped() {
    assert_eq!("SOMETHING".to_invertedcase(), "something");
    assert_eq!("SoMeThInG".to_invertedcase(), "sOmEtHiNg");
    assert_eq!("Some WorD2".to_invertedcase(), "sOME wORd2");
}

#[test]
fn str_alternating() {
    assert_eq!("SOMETHING".to_altcase(Case::Lower), "sOmEtHiNg");
    assert_eq!("SOMETHING".to_altcase(Case::Upper), "SoMeThInG");
    assert_eq!("som3thing".to_altcase(Case::Lower), "sOm3ThInG");
    assert_eq!("som3thing".to_altcase(Case::Upper), "SoM3tHiNg");
    assert_eq!("some word".to_altcase(Case::Lower), "sOmE wOrD");
}
<commit_msg>Reomoved feature collections - it's in stable now.<commit_after>
#[derive(Copy, Clone)]
pub enum Case {
    Upper,
    Lower
}

pub trait ChangeCase {
    fn to_uppercase<'a>(&'a self) -> String;
    fn to_lowercase<'a>(&'a self) -> String;
    fn to_capitalized<'a>(&'a self) -> String;
    fn to_invertedcase<'a>(&'a self) -> String;
    fn to_altcase<'a>(&'a self, start_with: Case) -> String;
}

impl<'a> ChangeCase for String {
    fn to_uppercase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            for c in self.chars() {
                let upper = c.to_uppercase().next().unwrap();
                result.push(upper);
            }
        }

        result
    }

    fn to_lowercase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            for c in self.chars() {
                let lower = c.to_lowercase().next().unwrap();
                result.push(lower);
            }
        }

        result
    }

    fn to_capitalized(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            let mut chars = self.chars();
            let first = chars.next().unwrap().to_uppercase().next().unwrap();
            result.push(first);

            for c in chars {
                let lower = c.to_lowercase().next().unwrap();
                result.push(lower);
            }
        }

        result
    }

    fn to_invertedcase(&self) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {

            for c in self.chars() {
                if c.is_uppercase() {
                    let lower = c.to_lowercase().next().unwrap();
                    result.push(lower);
                } else if c.is_lowercase() {
                    let upper = c.to_uppercase().next().unwrap();
                    result.push(upper);
                } else {
                    result.push(c);
                }
            }
        }

        result
    }

    fn to_altcase(&self, start_with: Case) -> String {
        if self.is_empty() {
            return String::new();
        }

        let mut result = String::with_capacity(self.len());

        {
            let mut current_case = start_with;

            for c in self.chars() {
                if c.is_uppercase() || c.is_lowercase() {
                    match current_case {
                        Case::Upper => {
                            let upper = c.to_uppercase().next().unwrap();
                            result.push(upper);
                            current_case = Case::Lower;
                        },
                        Case::Lower => {
                            let lower = c.to_lowercase().next().unwrap();
                            result.push(lower);
                            current_case = Case::Upper;
                        }
                    };
                } else {
                    result.push(c);
                }
            }
        }

        result
    }
}

impl<'a> ChangeCase for &'a str {
    fn to_uppercase(&self) -> String {
        String::from_str(self).to_uppercase()
    }
    fn to_lowercase(&self) -> String {
        String::from_str(self).to_lowercase()
    }
    fn to_capitalized(&self) -> String {
        String::from_str(self).to_capitalized()
    }
    fn to_invertedcase(&self) -> String {
        String::from_str(self).to_invertedcase()
    }
    fn to_altcase(&self, start_with: Case) -> String {
        String::from_str(self).to_altcase(start_with)
    }
}

#[test]
fn upper() {
    assert_eq!(String::from_str("Something").to_uppercase(), "SOMETHING");
    assert_eq!(String::from_str("sOmEtHiNg").to_uppercase(), "SOMETHING");
    assert_eq!(String::from_str("word word2").to_uppercase(), "WORD WORD2");
}

#[test]
fn lower() {
    assert_eq!(String::from_str("SOMETHING").to_lowercase(), "something");
    assert_eq!(String::from_str("sOmEtHiNg").to_lowercase(), "something");
    assert_eq!(String::from_str("Word WORD2").to_lowercase(), "word word2");
}

#[test]
fn capitalize() {
    assert_eq!(String::from_str("SOMETHING").to_capitalized(), "Something");
    assert_eq!(String::from_str("sOmEtHiNg").to_capitalized(), "Something");
    assert_eq!(String::from_str("Word WORD2").to_capitalized(), "Word word2");
}

#[test]
fn swapped() {
    assert_eq!(String::from_str("SOMETHING").to_invertedcase(), "something");
    assert_eq!(String::from_str("SoMeThInG").to_invertedcase(), "sOmEtHiNg");
    assert_eq!(String::from_str("Some WorD2").to_invertedcase(), "sOME wORd2");
}

#[test]
fn alternating() {
    assert_eq!(String::from_str("SOMETHING").to_altcase(Case::Lower), "sOmEtHiNg");
    assert_eq!(String::from_str("SOMETHING").to_altcase(Case::Upper), "SoMeThInG");
    assert_eq!(String::from_str("som3thing").to_altcase(Case::Lower), "sOm3ThInG");
    assert_eq!(String::from_str("som3thing").to_altcase(Case::Upper), "SoM3tHiNg");
    assert_eq!(String::from_str("some word").to_altcase(Case::Lower), "sOmE wOrD");
}

#[test]
fn str_lower() {
    assert_eq!("SOMETHING".to_lowercase(), "something");
    assert_eq!("sOmEtHiNg".to_lowercase(), "something");
    assert_eq!("Word WORD2".to_lowercase(), "word word2");
}

#[test]
fn str_capitalize() {
    assert_eq!("SOMETHING".to_capitalized(), "Something");
    assert_eq!("sOmEtHiNg".to_capitalized(), "Something");
    assert_eq!("Word WORD2".to_capitalized(), "Word word2");
}

#[test]
fn str_swapped() {
    assert_eq!("SOMETHING".to_invertedcase(), "something");
    assert_eq!("SoMeThInG".to_invertedcase(), "sOmEtHiNg");
    assert_eq!("Some WorD2".to_invertedcase(), "sOME wORd2");
}

#[test]
fn str_alternating() {
    assert_eq!("SOMETHING".to_altcase(Case::Lower), "sOmEtHiNg");
    assert_eq!("SOMETHING".to_altcase(Case::Upper), "SoMeThInG");
    assert_eq!("som3thing".to_altcase(Case::Lower), "sOm3ThInG");
    assert_eq!("som3thing".to_altcase(Case::Upper), "SoM3tHiNg");
    assert_eq!("some word".to_altcase(Case::Lower), "sOmE wOrD");
}
<|endoftext|>


<commit_before>mod crypt;

extern crate rustc_serialize;
use rustc_serialize::json;

extern crate uuid;
use uuid::Uuid;

use std::io::prelude::*;
use std::fs;
use std::path;

const KEYS_PATH: &'static str = "/home/andrey/Documents/storages/keys";
const DATA_PATH: &'static str = "/home/andrey/Documents/storages/data";
const MAPS_PATH: &'static str = "/home/andrey/Documents/storages/maps";

#[derive(RustcDecodable, RustcEncodable)]
struct StorableKey {
    key: Box<[u8]>,
    iv: Box<[u8]>
}

#[derive(RustcDecodable, RustcEncodable)]
struct StorableData {
    ciphertext: Vec<u8>
}

#[derive(RustcDecodable, RustcEncodable)]
struct StorableMap {
    key_id: Uuid,
    data_id: Uuid,
    tag: Box<[u8]>
}

pub fn dump(external_id: String, data: Vec<u8>) -> Result<(), String>  {
    let result = crypt::encrypt(external_id.as_bytes(), &data);

    let key_id = store_key(KEYS_PATH.to_string(), StorableKey { key: result.key, iv: result.iv }).unwrap();
    let data_id = store_data(DATA_PATH.to_string(), StorableData { ciphertext: result.ciphertext }).unwrap();
    let external_uuid = Uuid::parse_str(&external_id).unwrap();
    store_map(MAPS_PATH.to_string(), external_uuid, StorableMap { key_id: key_id, data_id: data_id, tag: result.tag })
}

fn construct_store_path(path_prefix: &String, path_key_string: &String) -> path::PathBuf {
    let mut path = path::PathBuf::from(path_prefix);
    path.push(path_key_string[0..2].to_string());
    path.push(path_key_string[2..4].to_string());
    path.push(path_key_string[4..6].to_string());
    path
}

fn construct_storable_path(path_prefix: &path::PathBuf, path_key: &String) -> path::PathBuf {
    let mut path = path::PathBuf::from(path_prefix);
    path.push(path_key);
    path.set_extension("json");
    path
}

fn store_json_string(path_prefix: String, path_key: Uuid, json: String) -> Result<(), String> {
    let store_path = construct_store_path(&path_prefix, &path_key.to_simple_string());
    fs::create_dir_all(&store_path).ok();
    let mut file = fs::File::create(construct_storable_path(&store_path, &path_key.to_string())).ok().expect("Cannot create file");
    match file.write_all(json.as_bytes()) {
        Ok(_) => Ok(()),
        Err(error) => Err(format!("Error: {}", error))
    }
}

fn store_data(path_prefix: String, storable: StorableData) -> Result<Uuid, String> {
    let id = Uuid::new_v4();
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(id)
}

fn store_key(path_prefix: String, storable: StorableKey) -> Result<Uuid, String> {
    let id = Uuid::new_v4();
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(id)
}

fn store_map(path_prefix: String, external_id: Uuid, storable: StorableMap) -> Result<(), String> {
    let id = external_id;
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(())
}

fn read_from_storage(prefix: &String, id: &String) -> Result<String, String> {
    let path = construct_storable_path(&construct_store_path(prefix, id), id);
    let mut file = fs::File::open(&path).unwrap();
    let mut string = String::new();
    match file.read_to_string(&mut string) {
        Ok(_) => Ok(string),
        Err(error) => Err(format!("Error: {}", error))
    }
}

pub fn load(external_id: &String) -> Vec<u8> {
    let map: StorableMap = json::decode(&read_from_storage(&MAPS_PATH.to_string(), external_id).unwrap()).unwrap();
    let key: StorableKey = json::decode(&read_from_storage(&KEYS_PATH.to_string(), &map.key_id.to_string()).unwrap()).unwrap();
    let data: StorableData = json::decode(&read_from_storage(&DATA_PATH.to_string(), &map.data_id.to_string()).unwrap()).unwrap();

    let result = crypt::decrypt(external_id.as_bytes(), &key.key, &key.iv, &data.ciphertext, &map.tag);

    result.plaintext
}
<commit_msg>Works perfect.<commit_after>mod crypt;

extern crate rustc_serialize;
use rustc_serialize::json;

extern crate uuid;
use uuid::Uuid;

use std::io::prelude::*;
use std::fs;
use std::path;

use std::sync::mpsc::channel;
use std::thread;

const KEYS_PATH: &'static str = "/home/andrey/Documents/storages/keys";
const DATA_PATH: &'static str = "/home/andrey/Documents/storages/data";
const MAPS_PATH: &'static str = "/home/andrey/Documents/storages/maps";

#[derive(RustcDecodable, RustcEncodable)]
struct StorableKey {
    key: Box<[u8]>,
    iv: Box<[u8]>
}

#[derive(RustcDecodable, RustcEncodable)]
struct StorableData {
    ciphertext: Vec<u8>
}

#[derive(RustcDecodable, RustcEncodable)]
struct StorableMap {
    key_id: Uuid,
    data_id: Uuid,
    tag: Box<[u8]>
}

pub fn dump(external_id: String, data: Vec<u8>) -> Result<(), String>  {
    let result = crypt::encrypt(external_id.as_bytes(), &data);

    let (key_tx, key_rx) = channel();
    let storable_key = StorableKey { key: result.key, iv: result.iv };
    thread::spawn(move || {
        key_tx.send(store_key(KEYS_PATH.to_string(), storable_key).unwrap()).unwrap();
    });

    let (data_tx, data_rx) = channel();
    let storable_data = StorableData { ciphertext: result.ciphertext };
    thread::spawn(move || {
        data_tx.send(store_data(DATA_PATH.to_string(), storable_data).unwrap()).unwrap();
    });

    let key_id = key_rx.recv().unwrap();
    let data_id = data_rx.recv().unwrap();
    let external_uuid = Uuid::parse_str(&external_id).unwrap();
    store_map(MAPS_PATH.to_string(), external_uuid, StorableMap { key_id: key_id, data_id: data_id, tag: result.tag })
}

fn construct_store_path(path_prefix: &String, path_key_string: &String) -> path::PathBuf {
    let mut path = path::PathBuf::from(path_prefix);
    path.push(path_key_string[0..2].to_string());
    path.push(path_key_string[2..4].to_string());
    path.push(path_key_string[4..6].to_string());
    path
}

fn construct_storable_path(path_prefix: &path::PathBuf, path_key: &String) -> path::PathBuf {
    let mut path = path::PathBuf::from(path_prefix);
    path.push(path_key);
    path.set_extension("json");
    path
}

fn store_json_string(path_prefix: String, path_key: Uuid, json: String) -> Result<(), String> {
    let store_path = construct_store_path(&path_prefix, &path_key.to_simple_string());
    fs::create_dir_all(&store_path).ok();
    let mut file = fs::File::create(construct_storable_path(&store_path, &path_key.to_string())).ok().expect("Cannot create file");
    match file.write_all(json.as_bytes()) {
        Ok(_) => Ok(()),
        Err(error) => Err(format!("Error: {}", error))
    }
}

fn store_data(path_prefix: String, storable: StorableData) -> Result<Uuid, String> {
    let id = Uuid::new_v4();
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(id)
}

fn store_key(path_prefix: String, storable: StorableKey) -> Result<Uuid, String> {
    let id = Uuid::new_v4();
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(id)
}

fn store_map(path_prefix: String, external_id: Uuid, storable: StorableMap) -> Result<(), String> {
    let id = external_id;
    let json = json::encode(&storable).unwrap();
    store_json_string(path_prefix, id, json).ok();
    Ok(())
}

fn read_from_storage(prefix: &String, id: &String) -> Result<String, String> {
    let path = construct_storable_path(&construct_store_path(prefix, id), id);
    let mut file = fs::File::open(&path).unwrap();
    let mut string = String::new();
    match file.read_to_string(&mut string) {
        Ok(_) => Ok(string),
        Err(error) => Err(format!("Error: {}", error))
    }
}

pub fn load(external_id: &String) -> Vec<u8> {
    let map: StorableMap = json::decode(&read_from_storage(&MAPS_PATH.to_string(), external_id).unwrap()).unwrap();

    let (key_tx, key_rx) = channel();
    let key_id = map.key_id.to_string();
    thread::spawn(move || {
        key_tx.send(json::decode(&read_from_storage(&KEYS_PATH.to_string(), &key_id).unwrap()).unwrap()).unwrap();
    });

    let (data_tx, data_rx) = channel();
    let data_id = map.data_id.to_string();
    thread::spawn(move || {
        data_tx.send(json::decode(&read_from_storage(&DATA_PATH.to_string(), &data_id).unwrap()).unwrap()).unwrap();
    });

    let key: StorableKey = key_rx.recv().unwrap();
    let data: StorableData = data_rx.recv().unwrap();

    let result = crypt::decrypt(external_id.as_bytes(), &key.key, &key.iv, &data.ciphertext, &map.tag);

    result.plaintext
}
<|endoftext|>