<commit_before>//use nalgebra::Vector2;
//use std::cmp::max;
use num::FromPrimitive;
use num::traits::{Signed, Bounded};
use super::integer_math::*;
use std::ops::{Add, Sub, Mul, Neg, AddAssign, SubAssign, MulAssign};
use array_ext::*;
use smallvec::SmallVec;

pub type Time = i64;

pub trait Trajectory {
  type Coefficient: Vector;
}

pub trait ScalarTrajectory: Trajectory {
  /*fn next_time_ge (&self, start: Time, end: Time, target: Self::Coefficient)->Option <Time> {

  }
  fn next_time_gt (&self, start: Time, end: Time, target: Self::Coefficient)->Option <Time> {
    self.next_time_ge (now, target + Vector::one())
  }
  fn next_time_le (&self, start: Time, end: Time, target: Self::Coefficient)->Option <Time> {
    (-self).next_time_ge (now, -target)
  }
  fn next_time_lt (&self, start: Time, end: Time, target: Self::Coefficient)->Option <Time> {
    self.next_time_le (now, target - Vector::one())
  }*/
}

macro_rules! impl_binop {
  ([$($generic_parameters: tt)*], $Left:ty, $Right:ty, $Trait: ident, $method: ident, $TraitAssign: ident, $method_assign: ident, $self: ident, $other: ident, $owned_owned: expr, $owned_ref: expr, $ref_owned: expr, $ref_ref: expr, $assign_owned: expr, $assign_ref: expr,) => {

impl <$($generic_parameters)*> $Trait <$Right> for $Left where Time: From <T::Coordinate> {
  type Output = Self;
  fn $method (mut $self, $other: $Right)->Self {
    $owned_owned
  }
}

impl <'a, $($generic_parameters)*> $Trait <& 'a $Right> for $Left where Time: From <T::Coordinate> {
  type Output = Self;
  fn $method (mut $self, $other: & 'a $Right)->Self {
    $owned_ref
  }
}

impl <'a, $($generic_parameters)*> $Trait <$Right> for & 'a $Left where Time: From <T::Coordinate> {
  type Output = $Left;
  fn $method ($self, $other: $Right)->$Left {
    $ref_owned
  }
}

impl <'a, 'b, $($generic_parameters)*> $Trait <& 'b $Right> for & 'a $Left where Time: From <T::Coordinate> {
  type Output = $Left;
  fn $method ($self, $other: & 'b $Right)->$Left {
    $ref_ref
  }
}

impl <$($generic_parameters)*> $TraitAssign <$Right> for $Left where Time: From <T::Coordinate> {
  fn $method_assign (&mut $self, $other: $Right) {
    $assign_owned
  }
}

impl <'a, $($generic_parameters)*> $TraitAssign <& 'a $Right> for $Left where Time: From <T::Coordinate> {
  fn $method_assign (&mut $self, $other: & 'a $Right) {
    $assign_ref
  }
}

  }
}

macro_rules! impl_trajectory_add_sub {
  ($Trajectory:ident, $Trait: ident, $method: ident, $TraitAssign: ident, $method_assign: ident) => {

impl_binop! {
[T: Vector], $Trajectory <T>, $Trajectory <T>, $Trait, $method, $TraitAssign, $method_assign, self, other,
{
  self += other;
  self
},
{
  self += other;
  self
},
{
  self.clone() + other
},
{
  self.clone() + other.clone()
},
{
  let mut other = other;
  if self.origin < other.origin {self.set_origin (other.origin).unwrap();}
  if other.origin < self.origin {other.set_origin (self.origin).unwrap();}
  for (mine, others) in self.coefficients.iter_mut().zip (other.coefficients.into_iter()) {
    mine.$method_assign (others);
  }
},
{
  let mut other_clone;
  let mut other = other;
  if self.origin < other.origin {self.set_origin (other.origin).unwrap();}
  if other.origin < self.origin {
    other_clone = other.clone();
    other_clone.set_origin (self.origin).unwrap();
    other = & other_clone;
  }
  for (mine, others) in self.coefficients.iter_mut().zip (other.coefficients.iter()) {
    mine.$method_assign (others);
  }
},
}

impl_binop! {
[T: Vector], $Trajectory <T>, T, $Trait, $method, $TraitAssign, $method_assign, self, other,
{
  self.coefficients [0].$method_assign (other);
  self
},
{
  self.coefficients [0].$method_assign (other);
  self
},
{
  self.clone() + other
},
{
  self.clone() + other
},
{
  self.coefficients [0].$method_assign (other);
},
{
  self.coefficients [0].$method_assign (other);
},
}

  }
}

macro_rules! impl_trajectory {
  ($Trajectory: ident, $degree: expr) => {

#[derive (Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Debug, Default)]
pub struct $Trajectory <T> {
  origin: Time,
  coefficients: [T; $degree + 1],
}

impl <T: Vector> $Trajectory <T> where Time: From <T::Coordinate> {
  pub fn constant (value: T)->Self {
    let mut coefficients = [T::zero(); $degree + 1];
    coefficients [0] = value;
    $Trajectory {origin: 0, coefficients}
  }
  pub fn set_origin (&mut self, new_origin: Time)->Result <(), polynomial::OverflowError> {
    for dimension in 0..T::DIMENSIONS {
      let coefficients = self.coordinate_coefficients (dimension);
      polynomial::translate_check (&coefficients, new_origin - self.origin, |_| i64::max_value())?;
    }
    for dimension in 0..T::DIMENSIONS {
      let mut coefficients = self.coordinate_coefficients (dimension);
      polynomial::translate_unchecked (&mut coefficients, T::Coordinate::from_i64 (new_origin - self.origin)?);
      for (coefficient, destination) in coefficients.iter().zip (self.coefficients.iter_mut()) {
        destination.set_coordinate (dimension, *coefficient);
      }
    }
    self.origin = new_origin;
    Ok (())
  }

  pub fn coordinate_coefficients (&self, dimension: usize)->[T::Coordinate; $degree + 1] {
    Array::from_fn (| which | self.coefficients [which].coordinate (dimension))
  }
  pub fn coordinate_trajectory (&self, dimension: usize)->$Trajectory <T::Coordinate> {
    $Trajectory {
      origin: self.origin,
      coefficients: self.coordinate_coefficients (dimension),
    }
  }

  pub fn nth_coefficient (&self, which: usize, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {
    let mut result = T::zero();
    for dimension in 0..T::DIMENSIONS {
      result.set_coordinate(dimension, T::Coordinate::from_i64 (polynomial::evaluate_nth_taylor_coefficient_at_fractional_input (& self.coordinate_coefficients (dimension), which, time_numerator - (self.origin << time_shift), time_shift)?)?) ;
    }
    Ok (result)
  }
  pub fn set_nth_coefficient (&mut self, which: usize, time_numerator: Time, time_shift: u32, target_value: T)->Result <(), polynomial::OverflowError> {
    self.set_origin (time_numerator >> time_shift)?;
    let mut transformed_coefficients: SmallVec<[[T::Coordinate; $degree + 1]; 4]> = SmallVec::with_capacity (T::DIMENSIONS);
    for dimension in 0..T::DIMENSIONS {
      let mut coefficients = self.coordinate_coefficients (dimension);
      polynomial::set_nth_taylor_coefficient_at_fractional_input (&mut coefficients, which, time_numerator - (self.origin << time_shift), time_shift, target_value.coordinate (dimension).into())?;
      transformed_coefficients.push (coefficients);
    }
    for (dimension, coefficients) in transformed_coefficients.into_iter().enumerate() {
      for (coefficient, destination) in coefficients.iter().zip (self.coefficients.iter_mut()).take (which + 1) {
        destination.set_coordinate (dimension, *coefficient);
      }
    }
    Ok (())
  }
  pub fn add_nth_coefficient (&mut self, which: usize, time_numerator: Time, time_shift: u32, added_value: T)->Result <(), polynomial::OverflowError> {
    let current_value = self.nth_coefficient (which, time_numerator, time_shift)?;
    self.set_nth_coefficient (which, time_numerator, time_shift, current_value + added_value)
  }
  pub fn value (&mut self, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {self.nth_coefficient (0, time_numerator, time_shift)}
  pub fn velocity (&mut self, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {self.nth_coefficient (1, time_numerator, time_shift)}
  pub fn set_value (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.set_nth_coefficient (0, time_numerator, time_shift, value)}
  pub fn set_velocity (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.set_nth_coefficient (1, time_numerator, time_shift, value)}
  pub fn add_value (&mut self, value: T) {*self += value}
  pub fn add_velocity (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.add_nth_coefficient (1, time_numerator, time_shift, value)}
}

impl <T: Integer + Signed> $Trajectory <T> {
  /*pub fn next_time_lt (&self, now: Time, value: T)->Option <Time> {
    if self.value (now) < value {Some (now)}
    else {
      unimplemented!()
    }
  }
  pub fn next_time_le (&self, now: Time, value: T)->Option <Time> {
    self.next_time_lt (now, value + T::one())
  }
  pub fn next_time_gt (&self, now: Time, value: T)->Option <Time> {
    (-self).next_time_lt (now, -value)
  }
  pub fn next_time_ge (&self, now: Time, value: T)->Option <Time> {
    self.next_time_gt (now, value - T::one())
  }*/
}

impl_trajectory_add_sub! ($Trajectory, Add, add, AddAssign, add_assign);
impl_trajectory_add_sub! ($Trajectory, Sub, sub, SubAssign, sub_assign);

impl<T: Vector, Coordinate: Copy> Mul<Coordinate> for $Trajectory<T> where T: MulAssign <Coordinate> {
  type Output = Self;
  fn mul(mut self, other: Coordinate) -> Self {
    self *= other; self
  }
}

impl<'a, T: Vector, Coordinate: Copy> Mul<Coordinate> for & 'a $Trajectory<T> where T: MulAssign <Coordinate> {
  type Output = $Trajectory <T>;
  fn mul(self, other: Coordinate) ->$Trajectory <T> {
    self.clone()*other
  }
}

impl<T: Vector, Coordinate: Copy> MulAssign <Coordinate> for $Trajectory<T> where T: MulAssign <Coordinate> {
  fn mul_assign (&mut self, other: Coordinate) {
    for coefficient in self.coefficients.iter_mut (){MulAssign::<Coordinate>::mul_assign (coefficient, other);}
  }
}

/*impl_binop! {
[T: Vector], $Trajectory <T>, T::Coordinate, Mul, mul, MulAssign, mul_assign, self, other,
{
  self *= other;
  self
},
{
  self *= other;
  self
},
{
  self.clone()*other
},
{
  self.clone()*other
},
{
  for term in self.terms.iter_mut (){*term *= other;}
},
{
  for term in self.terms.iter_mut (){*term *= other;}
},
}*/

impl <T: Vector + Neg <Output = T>> Neg for $Trajectory <T> {
  type Output = Self;
  fn neg (self)->Self {
    $Trajectory {
      origin: self.origin,
      coefficients: Array::from_fn (| index | self.coefficients [index].clone().neg()),
    }
  }
}
impl <'a, T: Vector> Neg for & 'a $Trajectory <T> where & 'a T: Neg <Output = T> {
  type Output = $Trajectory <T>;
  fn neg (self)->$Trajectory <T> {
    $Trajectory {
      origin: self.origin,
      coefficients: Array::from_fn (| index | (& self.coefficients [index]).neg()),
    }
  }
}

  };
}

//impl_trajectory! (LinearTrajectory, 1) ;
impl_trajectory! (QuadraticTrajectory, 2) ;

<commit_msg>Implemented root search for trajectories<commit_after>//use nalgebra::Vector2;
//use std::cmp::max;
use num::{FromPrimitive, One};
use num::traits::{Signed, Bounded};
use super::integer_math::*;
use self::polynomial::RootSearchResult;
use std::ops::{Add, Sub, Mul, Neg, AddAssign, SubAssign, MulAssign};
use array_ext::*;
use smallvec::SmallVec;

pub type Time = i64;

pub trait Trajectory: Sized {
  type Coefficient: Vector;
}

pub trait ScalarTrajectory: Trajectory where Self::Coefficient: Integer, for <'a> & 'a Self: Neg <Output = Self> {
  /// Find the first time within a range when the trajectory value is "significantly" >= target.
  ///
  /// To be "significant", the output time will obey this condition: The value at the output time is >= target, and it will not dip back to < target due to rounding error (it will only dip back if the ideal slope actually becomes negative).
  ///
  /// In order to guarantee this, we have to be slightly permissive, skipping over some inputs where the value is observed to be >= target. However, it still obeys this guarantee: The output time will always be <= the first time when the value is >= output + 4.
  fn next_time_significantly_ge (&self, range: [Time; 2], input_shift: u32, target: Self::Coefficient)->RootSearchResult<Time>;
  fn next_time_significantly_gt (&self, range: [Time; 2], input_shift: u32, target: Self::Coefficient)->RootSearchResult<Time> {
    self.next_time_significantly_ge (range, input_shift, target + Self::Coefficient::one())
  }
  fn next_time_significantly_le (&self, range: [Time; 2], input_shift: u32, target: Self::Coefficient)->RootSearchResult<Time> {
    (-self).next_time_significantly_ge (range, input_shift, -target)
  }
  fn next_time_significantly_lt (&self, range: [Time; 2], input_shift: u32, target: Self::Coefficient)->RootSearchResult<Time> {
    self.next_time_significantly_le (range, input_shift, target - Self::Coefficient::one())
  }
}

macro_rules! impl_binop {
  ([$($generic_parameters: tt)*], $Left:ty, $Right:ty, $Trait: ident, $method: ident, $TraitAssign: ident, $method_assign: ident, $self: ident, $other: ident, $owned_owned: expr, $owned_ref: expr, $ref_owned: expr, $ref_ref: expr, $assign_owned: expr, $assign_ref: expr,) => {

impl <$($generic_parameters)*> $Trait <$Right> for $Left where Time: From <T::Coordinate> {
  type Output = Self;
  fn $method (mut $self, $other: $Right)->Self {
    $owned_owned
  }
}

impl <'a, $($generic_parameters)*> $Trait <& 'a $Right> for $Left where Time: From <T::Coordinate> {
  type Output = Self;
  fn $method (mut $self, $other: & 'a $Right)->Self {
    $owned_ref
  }
}

impl <'a, $($generic_parameters)*> $Trait <$Right> for & 'a $Left where Time: From <T::Coordinate> {
  type Output = $Left;
  fn $method ($self, $other: $Right)->$Left {
    $ref_owned
  }
}

impl <'a, 'b, $($generic_parameters)*> $Trait <& 'b $Right> for & 'a $Left where Time: From <T::Coordinate> {
  type Output = $Left;
  fn $method ($self, $other: & 'b $Right)->$Left {
    $ref_ref
  }
}

impl <$($generic_parameters)*> $TraitAssign <$Right> for $Left where Time: From <T::Coordinate> {
  fn $method_assign (&mut $self, $other: $Right) {
    $assign_owned
  }
}

impl <'a, $($generic_parameters)*> $TraitAssign <& 'a $Right> for $Left where Time: From <T::Coordinate> {
  fn $method_assign (&mut $self, $other: & 'a $Right) {
    $assign_ref
  }
}

  }
}

macro_rules! impl_trajectory_add_sub {
  ($Trajectory:ident, $Trait: ident, $method: ident, $TraitAssign: ident, $method_assign: ident) => {

impl_binop! {
[T: Vector], $Trajectory <T>, $Trajectory <T>, $Trait, $method, $TraitAssign, $method_assign, self, other,
{
  self += other;
  self
},
{
  self += other;
  self
},
{
  self.clone() + other
},
{
  self.clone() + other.clone()
},
{
  let mut other = other;
  if self.origin < other.origin {self.set_origin (other.origin).unwrap();}
  if other.origin < self.origin {other.set_origin (self.origin).unwrap();}
  for (mine, others) in self.coefficients.iter_mut().zip (other.coefficients.into_iter()) {
    mine.$method_assign (others);
  }
},
{
  let mut other_clone;
  let mut other = other;
  if self.origin < other.origin {self.set_origin (other.origin).unwrap();}
  if other.origin < self.origin {
    other_clone = other.clone();
    other_clone.set_origin (self.origin).unwrap();
    other = & other_clone;
  }
  for (mine, others) in self.coefficients.iter_mut().zip (other.coefficients.iter()) {
    mine.$method_assign (others);
  }
},
}

impl_binop! {
[T: Vector], $Trajectory <T>, T, $Trait, $method, $TraitAssign, $method_assign, self, other,
{
  self.coefficients [0].$method_assign (other);
  self
},
{
  self.coefficients [0].$method_assign (other);
  self
},
{
  self.clone() + other
},
{
  self.clone() + other
},
{
  self.coefficients [0].$method_assign (other);
},
{
  self.coefficients [0].$method_assign (other);
},
}

  }
}

macro_rules! impl_trajectory {
  ($Trajectory: ident, $degree: expr) => {

#[derive (Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Debug, Default)]
pub struct $Trajectory <T> {
  origin: Time,
  coefficients: [T; $degree + 1],
}

impl <T: Vector> Trajectory for $Trajectory <T> {
  type Coefficient = T;
}

impl <T: Vector> $Trajectory <T> where Time: From <T::Coordinate> {
  pub fn constant (value: T)->Self {
    let mut coefficients = [T::zero(); $degree + 1];
    coefficients [0] = value;
    $Trajectory {origin: 0, coefficients}
  }
  pub fn set_origin (&mut self, new_origin: Time)->Result <(), polynomial::OverflowError> {
    for dimension in 0..T::DIMENSIONS {
      let coefficients = self.coordinate_coefficients (dimension);
      polynomial::translate_check (&coefficients, new_origin - self.origin, |_| i64::max_value())?;
    }
    for dimension in 0..T::DIMENSIONS {
      let mut coefficients = self.coordinate_coefficients (dimension);
      polynomial::translate_unchecked (&mut coefficients, T::Coordinate::from_i64 (new_origin - self.origin)?);
      for (coefficient, destination) in coefficients.iter().zip (self.coefficients.iter_mut()) {
        destination.set_coordinate (dimension, *coefficient);
      }
    }
    self.origin = new_origin;
    Ok (())
  }

  pub fn coordinate_coefficients (&self, dimension: usize)->[T::Coordinate; $degree + 1] {
    Array::from_fn (| which | self.coefficients [which].coordinate (dimension))
  }
  pub fn coordinate_trajectory (&self, dimension: usize)->$Trajectory <T::Coordinate> {
    $Trajectory {
      origin: self.origin,
      coefficients: self.coordinate_coefficients (dimension),
    }
  }

  pub fn nth_coefficient (&self, which: usize, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {
    let mut result = T::zero();
    for dimension in 0..T::DIMENSIONS {
      result.set_coordinate(dimension, T::Coordinate::from_i64 (polynomial::evaluate_nth_taylor_coefficient_at_fractional_input (& self.coordinate_coefficients (dimension), which, time_numerator - (self.origin << time_shift), time_shift)?)?) ;
    }
    Ok (result)
  }
  pub fn set_nth_coefficient (&mut self, which: usize, time_numerator: Time, time_shift: u32, target_value: T)->Result <(), polynomial::OverflowError> {
    self.set_origin (time_numerator >> time_shift)?;
    let mut transformed_coefficients: SmallVec<[[T::Coordinate; $degree + 1]; 4]> = SmallVec::with_capacity (T::DIMENSIONS);
    for dimension in 0..T::DIMENSIONS {
      let mut coefficients = self.coordinate_coefficients (dimension);
      polynomial::set_nth_taylor_coefficient_at_fractional_input (&mut coefficients, which, time_numerator - (self.origin << time_shift), time_shift, target_value.coordinate (dimension).into())?;
      transformed_coefficients.push (coefficients);
    }
    for (dimension, coefficients) in transformed_coefficients.into_iter().enumerate() {
      for (coefficient, destination) in coefficients.iter().zip (self.coefficients.iter_mut()).take (which + 1) {
        destination.set_coordinate (dimension, *coefficient);
      }
    }
    Ok (())
  }
  pub fn add_nth_coefficient (&mut self, which: usize, time_numerator: Time, time_shift: u32, added_value: T)->Result <(), polynomial::OverflowError> {
    let current_value = self.nth_coefficient (which, time_numerator, time_shift)?;
    self.set_nth_coefficient (which, time_numerator, time_shift, current_value + added_value)
  }
  pub fn value (&self, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {self.nth_coefficient (0, time_numerator, time_shift)}
  pub fn velocity (&self, time_numerator: Time, time_shift: u32)->Result <T, polynomial::OverflowError> {self.nth_coefficient (1, time_numerator, time_shift)}
  pub fn set_value (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.set_nth_coefficient (0, time_numerator, time_shift, value)}
  pub fn set_velocity (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.set_nth_coefficient (1, time_numerator, time_shift, value)}
  pub fn add_value (&mut self, value: T) {*self += value}
  pub fn add_velocity (&mut self, time_numerator: Time, time_shift: u32, value: T)->Result <(), polynomial::OverflowError> {self.add_nth_coefficient (1, time_numerator, time_shift, value)}
}

impl <T: Integer + Signed> $Trajectory <T> {
  /*pub fn next_time_lt (&self, now: Time, value: T)->Option <Time> {
    if self.value (now) < value {Some (now)}
    else {
      unimplemented!()
    }
  }
  pub fn next_time_le (&self, now: Time, value: T)->Option <Time> {
    self.next_time_lt (now, value + T::one())
  }
  pub fn next_time_gt (&self, now: Time, value: T)->Option <Time> {
    (-self).next_time_lt (now, -value)
  }
  pub fn next_time_ge (&self, now: Time, value: T)->Option <Time> {
    self.next_time_gt (now, value - T::one())
  }*/
}

impl_trajectory_add_sub! ($Trajectory, Add, add, AddAssign, add_assign);
impl_trajectory_add_sub! ($Trajectory, Sub, sub, SubAssign, sub_assign);

impl<T: Vector, Coordinate: Copy> Mul<Coordinate> for $Trajectory<T> where T: MulAssign <Coordinate> {
  type Output = Self;
  fn mul(mut self, other: Coordinate) -> Self {
    self *= other; self
  }
}

impl<'a, T: Vector, Coordinate: Copy> Mul<Coordinate> for & 'a $Trajectory<T> where T: MulAssign <Coordinate> {
  type Output = $Trajectory <T>;
  fn mul(self, other: Coordinate) ->$Trajectory <T> {
    self.clone()*other
  }
}

impl<T: Vector, Coordinate: Copy> MulAssign <Coordinate> for $Trajectory<T> where T: MulAssign <Coordinate> {
  fn mul_assign (&mut self, other: Coordinate) {
    for coefficient in self.coefficients.iter_mut (){MulAssign::<Coordinate>::mul_assign (coefficient, other);}
  }
}

/*impl_binop! {
[T: Vector], $Trajectory <T>, T::Coordinate, Mul, mul, MulAssign, mul_assign, self, other,
{
  self *= other;
  self
},
{
  self *= other;
  self
},
{
  self.clone()*other
},
{
  self.clone()*other
},
{
  for term in self.terms.iter_mut (){*term *= other;}
},
{
  for term in self.terms.iter_mut (){*term *= other;}
},
}*/

impl <T: Vector + Neg <Output = T>> Neg for $Trajectory <T> {
  type Output = Self;
  fn neg (self)->Self {
    $Trajectory {
      origin: self.origin,
      coefficients: Array::from_fn (| index | self.coefficients [index].clone().neg()),
    }
  }
}
impl <'a, T: Vector> Neg for & 'a $Trajectory <T> where & 'a T: Neg <Output = T> {
  type Output = $Trajectory <T>;
  fn neg (self)->$Trajectory <T> {
    $Trajectory {
      origin: self.origin,
      coefficients: Array::from_fn (| index | (& self.coefficients [index]).neg()),
    }
  }
}

impl <T: Vector + Integer + Signed + HasCoordinates <Coordinate = T>> ScalarTrajectory for $Trajectory <T> where for <'a> & 'a Self: Neg <Output = Self>, Time: From <T> {
  fn next_time_significantly_ge (&self, range: [Time; 2], input_shift: u32, target: Self::Coefficient)->RootSearchResult<Time> {
    let relative = self - (target + T::one() + T::one());
    match polynomial::root_search (& relative.coefficients, range, input_shift) {
      RootSearchResult::Root (input) => RootSearchResult::Root (self.origin + if relative.value (self.origin + input, input_shift).unwrap() >= T::zero() {input} else {input + 1}),
      RootSearchResult::Overflow (input) => RootSearchResult::Overflow (self.origin + input),
      RootSearchResult::Finished => RootSearchResult::Finished,
    }
  }
}

  };
}

//impl_trajectory! (LinearTrajectory, 1) ;
impl_trajectory! (QuadraticTrajectory, 2) ;

<|endoftext|>


<commit_before>use super::allocator::Allocator;

use alloc::allocator::{Alloc, Layout};

// Bunch of different heaps as the tests run concurrently
const HEAP_SIZE: usize = 1000;

// Alloc tests

#[test]
fn alloc_0() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        let layout = Layout::from_size_align_unchecked(26, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_ok());
    }
}

#[test]
fn alloc_1() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap
        for _ in 0..10 {
            let size = 100 - ::core::mem::size_of::<::block::Block>();
            let layout = Layout::from_size_align_unchecked(size, 0);
            let result = allocator.alloc(layout);
            assert!(result.is_ok());
        }
    }
}

#[test]
fn returns_err_on_oom_01() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        let layout = Layout::from_size_align_unchecked(HEAP_SIZE + 1, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_err());
    }
}

#[test]
fn returns_err_on_oom_02() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap
        for _ in 0..10 {
            let size = 100 - ::core::mem::size_of::<::block::Block>();
            let layout = Layout::from_size_align_unchecked(size, 0);
            let result = allocator.alloc(layout);
            assert!(result.is_ok());
        }

        // And OOM it...
        let layout = Layout::from_size_align_unchecked(1, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_err());
    }
}

// Dealloc tests

#[test]
fn dealloc_0() {
    let mut heap = [0; HEAP_SIZE];
    let size = 100 - ::core::mem::size_of::<::block::Block>();

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate some memory
        let layout_a = Layout::from_size_align_unchecked(size, 0);
        let p1 = allocator.alloc(layout_a);

        // Deallocate it...
        let layout_d = Layout::from_size_align_unchecked(size, 0);
        allocator.dealloc(p1.unwrap(), layout_d);
    }
}

#[test]
fn dealloc_1() {
    let mut heap = [0; HEAP_SIZE];
    let size = 500 - ::core::mem::size_of::<::block::Block>();

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap in two allocs
        let layout_a1 = Layout::from_size_align_unchecked(size, 0);
        let p1 = allocator.alloc(layout_a1);
        assert!(p1.is_ok());

        let layout_a2 = Layout::from_size_align_unchecked(size, 0);
        let p2 = allocator.alloc(layout_a2);
        assert!(p2.is_ok());

        // Deallocate the first
        let layout_d = Layout::from_size_align_unchecked(size, 0);
        allocator.dealloc(p1.unwrap(), layout_d);

        // Try to reallocate the same memory freed from p1
        let layout_a3 = Layout::from_size_align_unchecked(size, 0);
        let p3 = allocator.alloc(layout_a3);
        assert!(p3.is_ok());
    }
}

#[test]
fn usable_size_0() {
    // This will change in the future but for now just test that it returns the size
    // we asked for
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        let size = 100;
        let align = 0;

        let _ = allocator.alloc(size, 0);
        assert!(allocator.usable_size(size, align) == size);
    }
}
<commit_msg>Remove test 'usable_size_01' in alloc_opsys as no longer relevant<commit_after>use super::allocator::Allocator;

use alloc::allocator::{Alloc, Layout};

// Bunch of different heaps as the tests run concurrently
const HEAP_SIZE: usize = 1000;

// Alloc tests

#[test]
fn alloc_0() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        let layout = Layout::from_size_align_unchecked(26, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_ok());
    }
}

#[test]
fn alloc_1() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap
        for _ in 0..10 {
            let size = 100 - ::core::mem::size_of::<::block::Block>();
            let layout = Layout::from_size_align_unchecked(size, 0);
            let result = allocator.alloc(layout);
            assert!(result.is_ok());
        }
    }
}

#[test]
fn returns_err_on_oom_01() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        let layout = Layout::from_size_align_unchecked(HEAP_SIZE + 1, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_err());
    }
}

#[test]
fn returns_err_on_oom_02() {
    let mut heap = [0; HEAP_SIZE];

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap
        for _ in 0..10 {
            let size = 100 - ::core::mem::size_of::<::block::Block>();
            let layout = Layout::from_size_align_unchecked(size, 0);
            let result = allocator.alloc(layout);
            assert!(result.is_ok());
        }

        // And OOM it...
        let layout = Layout::from_size_align_unchecked(1, 0);
        let result = allocator.alloc(layout);
        assert!(result.is_err());
    }
}

// Dealloc tests

#[test]
fn dealloc_0() {
    let mut heap = [0; HEAP_SIZE];
    let size = 100 - ::core::mem::size_of::<::block::Block>();

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate some memory
        let layout_a = Layout::from_size_align_unchecked(size, 0);
        let p1 = allocator.alloc(layout_a);

        // Deallocate it...
        let layout_d = Layout::from_size_align_unchecked(size, 0);
        allocator.dealloc(p1.unwrap(), layout_d);
    }
}

#[test]
fn dealloc_1() {
    let mut heap = [0; HEAP_SIZE];
    let size = 500 - ::core::mem::size_of::<::block::Block>();

    unsafe {
        let mut allocator = Allocator::new(&mut heap, HEAP_SIZE);

        // Allocate the entire heap in two allocs
        let layout_a1 = Layout::from_size_align_unchecked(size, 0);
        let p1 = allocator.alloc(layout_a1);
        assert!(p1.is_ok());

        let layout_a2 = Layout::from_size_align_unchecked(size, 0);
        let p2 = allocator.alloc(layout_a2);
        assert!(p2.is_ok());

        // Deallocate the first
        let layout_d = Layout::from_size_align_unchecked(size, 0);
        allocator.dealloc(p1.unwrap(), layout_d);

        // Try to reallocate the same memory freed from p1
        let layout_a3 = Layout::from_size_align_unchecked(size, 0);
        let p3 = allocator.alloc(layout_a3);
        assert!(p3.is_ok());
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
    packages: &'static [&'static str],
}

const TEST_REPOS: &'static [Test] = &[
    Test {
        name: "iron",
        repo: "https://github.com/iron/iron",
        sha: "21c7dae29c3c214c08533c2a55ac649b418f2fe3",
        lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
        packages: &[],
    },
    Test {
        name: "ripgrep",
        repo: "https://github.com/BurntSushi/ripgrep",
        sha: "b65bb37b14655e1a89c7cd19c8b011ef3e312791",
        lock: None,
        packages: &[],
    },
    Test {
        name: "tokei",
        repo: "https://github.com/Aaronepower/tokei",
        sha: "5e11c4852fe4aa086b0e4fe5885822fbe57ba928",
        lock: None,
        packages: &[],
    },
    Test {
        name: "treeify",
        repo: "https://github.com/dzamlo/treeify",
        sha: "999001b223152441198f117a68fb81f57bc086dd",
        lock: None,
        packages: &[],
    },
    Test {
        name: "xsv",
        repo: "https://github.com/BurntSushi/xsv",
        sha: "4b308adbe48ac81657fd124b90b44f7c3263f771",
        lock: None,
        packages: &[],
    },
    Test {
        name: "servo",
        repo: "https://github.com/servo/servo",
        sha: "38fe9533b93e985657f99a29772bf3d3c8694822",
        lock: None,
        // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox.
        // This takes much less time to build than all of Servo and supports stable Rust.
        packages: &["stylo_tests", "selectors"],
    },
    Test {
        name: "webrender",
        repo: "https://github.com/servo/webrender",
        sha: "57250b2b8fa63934f80e5376a29f7dcb3f759ad6",
        lock: None,
        packages: &[],
    },
];

fn main() {
    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock"))
            .expect("")
            .write_all(lockfile.as_bytes())
            .expect("");
    }
    if !run_cargo_test(cargo, &dir, test.packages) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
                         .arg("init")
                         .arg(&out_dir)
                         .status()
                         .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                             .arg("fetch")
                             .arg(test.repo)
                             .arg("master")
                             .arg(&format!("--depth={}", depth))
                             .current_dir(&out_dir)
                             .status()
                             .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
                         .arg("reset")
                         .arg(test.sha)
                         .arg("--hard")
                         .current_dir(&out_dir)
                         .status()
                         .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
                     .arg("clean")
                     .arg("-fdx")
                     .current_dir(&out_dir)
                     .status()
                     .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path, packages: &[&str]) -> bool {
    let mut command = Command::new(cargo_path);
    command.arg("test");
    for name in packages {
        command.arg("-p").arg(name);
    }
    let status = command
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<commit_msg>Auto merge of #45550 - kennytm:update-xsv, r=BurntSushi<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
    packages: &'static [&'static str],
}

const TEST_REPOS: &'static [Test] = &[
    Test {
        name: "iron",
        repo: "https://github.com/iron/iron",
        sha: "21c7dae29c3c214c08533c2a55ac649b418f2fe3",
        lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
        packages: &[],
    },
    Test {
        name: "ripgrep",
        repo: "https://github.com/BurntSushi/ripgrep",
        sha: "b65bb37b14655e1a89c7cd19c8b011ef3e312791",
        lock: None,
        packages: &[],
    },
    Test {
        name: "tokei",
        repo: "https://github.com/Aaronepower/tokei",
        sha: "5e11c4852fe4aa086b0e4fe5885822fbe57ba928",
        lock: None,
        packages: &[],
    },
    Test {
        name: "treeify",
        repo: "https://github.com/dzamlo/treeify",
        sha: "999001b223152441198f117a68fb81f57bc086dd",
        lock: None,
        packages: &[],
    },
    Test {
        name: "xsv",
        repo: "https://github.com/BurntSushi/xsv",
        sha: "66956b6bfd62d6ac767a6b6499c982eae20a2c9f",
        lock: None,
        packages: &[],
    },
    Test {
        name: "servo",
        repo: "https://github.com/servo/servo",
        sha: "38fe9533b93e985657f99a29772bf3d3c8694822",
        lock: None,
        // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox.
        // This takes much less time to build than all of Servo and supports stable Rust.
        packages: &["stylo_tests", "selectors"],
    },
    Test {
        name: "webrender",
        repo: "https://github.com/servo/webrender",
        sha: "57250b2b8fa63934f80e5376a29f7dcb3f759ad6",
        lock: None,
        packages: &[],
    },
];

fn main() {
    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock"))
            .expect("")
            .write_all(lockfile.as_bytes())
            .expect("");
    }
    if !run_cargo_test(cargo, &dir, test.packages) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
                         .arg("init")
                         .arg(&out_dir)
                         .status()
                         .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                             .arg("fetch")
                             .arg(test.repo)
                             .arg("master")
                             .arg(&format!("--depth={}", depth))
                             .current_dir(&out_dir)
                             .status()
                             .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
                         .arg("reset")
                         .arg(test.sha)
                         .arg("--hard")
                         .current_dir(&out_dir)
                         .status()
                         .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
                     .arg("clean")
                     .arg("-fdx")
                     .current_dir(&out_dir)
                     .status()
                     .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path, packages: &[&str]) -> bool {
    let mut command = Command::new(cargo_path);
    command.arg("test");
    for name in packages {
        command.arg("-p").arg(name);
    }
    let status = command
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::hash::{Hash, Hasher};

use ring::digest::Algorithm;

use hashutils::HashUtils;
use tree::Tree;

/// An inclusion proof represent the fact that a `value` is a member
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug)]
pub struct Proof<T> {
    /// The hashing algorithm used in the original `MerkleTree`
    #[cfg_attr(
        feature = "serialization-serde",
        serde(with = "algorithm_serde")
    )]
    pub algorithm: &'static Algorithm,

    /// The hash of the root of the original `MerkleTree`
    pub root_hash: Vec<u8>,

    /// The first `Lemma` of the `Proof`
    pub lemma: Lemma,

    /// The value concerned by this `Proof`
    pub value: T,
}

#[cfg(feature = "serialization-serde")]
mod algorithm_serde {
    use ring::digest::{self, Algorithm};
    use serde::de::Error;
    use serde::{Deserialize, Deserializer, Serialize, Serializer};

    pub fn serialize<S: Serializer>(
        algorithm: &'static Algorithm,
        se: S,
    ) -> Result<S::Ok, S::Error> {
        // The `Debug` implementation of `Algorithm` prints its ID.
        format!("{:?}", algorithm).serialize(se)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<&'static Algorithm, D::Error> {
        match Deserialize::deserialize(de)? {
            "SHA1" => Ok(&digest::SHA1),
            "SHA256" => Ok(&digest::SHA256),
            "SHA384" => Ok(&digest::SHA384),
            "SHA512" => Ok(&digest::SHA512),
            "SHA512_256" => Ok(&digest::SHA512_256),
            _ => Err(D::Error::custom("unknown hash algorithm")),
        }
    }

    mod test {
        use super::*;
        use ring::digest::{
            SHA1 as sha1, SHA256 as sha256, SHA384 as sha384, SHA512 as sha512,
            SHA512_256 as sha512_256,
        };

        static SHA1: &Algorithm = &sha1;
        static SHA256: &Algorithm = &sha256;
        static SHA384: &Algorithm = &sha384;
        static SHA512: &Algorithm = &sha512;
        static SHA512_256: &Algorithm = &sha512_256;

        #[test]
        fn test_serialize_known_algorithms() {
            extern crate serde_json;

            for alg in [SHA1, SHA256, SHA384, SHA512, SHA512_256].iter() {
                let mut serializer = serde_json::Serializer::with_formatter(
                    vec![],
                    serde_json::ser::PrettyFormatter::new(),
                );

                let _ = serialize(alg, &mut serializer).expect(&format!("{:?}", alg));
                let alg_ = deserialize(&mut serde_json::Deserializer::from_slice(
                    &serializer.into_inner()[..],
                )).expect(&format!("{:?}", alg));

                assert_eq!(*alg, alg_);
            }
        }

        #[test]
        #[should_panic(expected = "unknown hash algorithm")]
        fn test_serialize_unknown_algorithm() {
            extern crate serde_json;
            {
                let alg_str = "\"BLAKE2b\"";
                let mut deserializer = serde_json::Deserializer::from_str(alg_str);
                let _ = deserialize(&mut deserializer).expect(&format!("{:?}", alg_str));
            }
        }
    }
}

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

impl<T: Eq> Eq for Proof<T> {}

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

impl<T: Ord> Ord for Proof<T> {
    fn cmp(&self, other: &Proof<T>) -> Ordering {
        self.root_hash
            .cmp(&other.root_hash)
            .then(self.value.cmp(&other.value))
            .then_with(|| self.lemma.cmp(&other.lemma))
    }
}

impl<T: Hash> Hash for Proof<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.root_hash.hash(state);
        self.lemma.hash(state);
        self.value.hash(state);
    }
}

impl<T> Proof<T> {
    /// Constructs a new `Proof`
    pub fn new(algorithm: &'static Algorithm, root_hash: Vec<u8>, lemma: Lemma, value: T) -> Self {
        Proof {
            algorithm,
            root_hash,
            lemma,
            value,
        }
    }

    /// Checks whether this inclusion proof is well-formed,
    /// and whether its root hash matches the given `root_hash`.
    pub fn validate(&self, root_hash: &[u8]) -> bool {
        if self.root_hash != root_hash || self.lemma.node_hash != root_hash {
            return false;
        }

        self.lemma.validate(self.algorithm)
    }
}

/// A `Lemma` holds the hash of a node, the hash of its sibling node,
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
/// must be equal to this `node_hash`.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Lemma {
    pub node_hash: Vec<u8>,
    pub sibling_hash: Option<Positioned<Vec<u8>>>,
    pub sub_lemma: Option<Box<Lemma>>,
}

impl Lemma {
    /// Attempts to generate a proof that the a value with hash `needle` is a member of the given `tree`.
    pub fn new<T>(tree: &Tree<T>, needle: &[u8]) -> Option<Lemma> {
        match *tree {
            Tree::Empty { .. } => None,

            Tree::Leaf { ref hash, .. } => Lemma::new_leaf_proof(hash, needle),

            Tree::Node {
                ref hash,
                ref left,
                ref right,
            } => Lemma::new_tree_proof(hash, needle, left, right),
        }
    }

    fn new_leaf_proof(hash: &[u8], needle: &[u8]) -> Option<Lemma> {
        if *hash == *needle {
            Some(Lemma {
                node_hash: hash.into(),
                sibling_hash: None,
                sub_lemma: None,
            })
        } else {
            None
        }
    }

    fn new_tree_proof<T>(
        hash: &[u8],
        needle: &[u8],
        left: &Tree<T>,
        right: &Tree<T>,
    ) -> Option<Lemma> {
        Lemma::new(left, needle)
            .map(|lemma| {
                let right_hash = right.hash().clone();
                let sub_lemma = Some(Positioned::Right(right_hash));
                (lemma, sub_lemma)
            })
            .or_else(|| {
                let sub_lemma = Lemma::new(right, needle);
                sub_lemma.map(|lemma| {
                    let left_hash = left.hash().clone();
                    let sub_lemma = Some(Positioned::Left(left_hash));
                    (lemma, sub_lemma)
                })
            })
            .map(|(sub_lemma, sibling_hash)| Lemma {
                node_hash: hash.into(),
                sibling_hash,
                sub_lemma: Some(Box::new(sub_lemma)),
            })
    }

    fn validate(&self, algorithm: &'static Algorithm) -> bool {
        match self.sub_lemma {
            None => self.sibling_hash.is_none(),

            Some(ref sub) => match self.sibling_hash {
                None => false,

                Some(Positioned::Left(ref hash)) => {
                    let combined = algorithm.hash_nodes(hash, &sub.node_hash);
                    let hashes_match = combined.as_ref() == self.node_hash.as_slice();
                    hashes_match && sub.validate(algorithm)
                }

                Some(Positioned::Right(ref hash)) => {
                    let combined = algorithm.hash_nodes(&sub.node_hash, hash);
                    let hashes_match = combined.as_ref() == self.node_hash.as_slice();
                    hashes_match && sub.validate(algorithm)
                }
            },
        }
    }
}

/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Positioned<T> {
    /// The value was found in the left branch
    Left(T),

    /// The value was found in the right branch
    Right(T),
}
<commit_msg>Fix proof deserialization.<commit_after>use std::cmp::Ordering;
use std::hash::{Hash, Hasher};

use ring::digest::Algorithm;

use hashutils::HashUtils;
use tree::Tree;

/// An inclusion proof represent the fact that a `value` is a member
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug)]
pub struct Proof<T> {
    /// The hashing algorithm used in the original `MerkleTree`
    #[cfg_attr(
        feature = "serialization-serde",
        serde(with = "algorithm_serde")
    )]
    pub algorithm: &'static Algorithm,

    /// The hash of the root of the original `MerkleTree`
    pub root_hash: Vec<u8>,

    /// The first `Lemma` of the `Proof`
    pub lemma: Lemma,

    /// The value concerned by this `Proof`
    pub value: T,
}

#[cfg(feature = "serialization-serde")]
mod algorithm_serde {
    use ring::digest::{self, Algorithm};
    use serde::de::Error;
    use serde::{Deserialize, Deserializer, Serialize, Serializer};

    pub fn serialize<S: Serializer>(
        algorithm: &'static Algorithm,
        se: S,
    ) -> Result<S::Ok, S::Error> {
        // The `Debug` implementation of `Algorithm` prints its ID.
        format!("{:?}", algorithm).serialize(se)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<&'static Algorithm, D::Error> {
        let alg_str: String = Deserialize::deserialize(de)?;
        match &*alg_str {
            "SHA1" => Ok(&digest::SHA1),
            "SHA256" => Ok(&digest::SHA256),
            "SHA384" => Ok(&digest::SHA384),
            "SHA512" => Ok(&digest::SHA512),
            "SHA512_256" => Ok(&digest::SHA512_256),
            _ => Err(D::Error::custom("unknown hash algorithm")),
        }
    }

    mod test {
        use super::*;
        use ring::digest::{
            SHA1 as sha1, SHA256 as sha256, SHA384 as sha384, SHA512 as sha512,
            SHA512_256 as sha512_256,
        };

        static SHA1: &Algorithm = &sha1;
        static SHA256: &Algorithm = &sha256;
        static SHA384: &Algorithm = &sha384;
        static SHA512: &Algorithm = &sha512;
        static SHA512_256: &Algorithm = &sha512_256;

        #[test]
        fn test_serialize_known_algorithms() {
            extern crate serde_json;

            for alg in [SHA1, SHA256, SHA384, SHA512, SHA512_256].iter() {
                let mut serializer = serde_json::Serializer::with_formatter(
                    vec![],
                    serde_json::ser::PrettyFormatter::new(),
                );

                let _ = serialize(alg, &mut serializer).expect(&format!("{:?}", alg));
                let alg_ = deserialize(&mut serde_json::Deserializer::from_slice(
                    &serializer.into_inner()[..],
                )).expect(&format!("{:?}", alg));

                assert_eq!(*alg, alg_);
            }
        }

        #[test]
        #[should_panic(expected = "unknown hash algorithm")]
        fn test_serialize_unknown_algorithm() {
            extern crate serde_json;
            {
                let alg_str = "\"BLAKE2b\"";
                let mut deserializer = serde_json::Deserializer::from_str(alg_str);
                let _ = deserialize(&mut deserializer).expect(&format!("{:?}", alg_str));
            }
        }
    }
}

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

impl<T: Eq> Eq for Proof<T> {}

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

impl<T: Ord> Ord for Proof<T> {
    fn cmp(&self, other: &Proof<T>) -> Ordering {
        self.root_hash
            .cmp(&other.root_hash)
            .then(self.value.cmp(&other.value))
            .then_with(|| self.lemma.cmp(&other.lemma))
    }
}

impl<T: Hash> Hash for Proof<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.root_hash.hash(state);
        self.lemma.hash(state);
        self.value.hash(state);
    }
}

impl<T> Proof<T> {
    /// Constructs a new `Proof`
    pub fn new(algorithm: &'static Algorithm, root_hash: Vec<u8>, lemma: Lemma, value: T) -> Self {
        Proof {
            algorithm,
            root_hash,
            lemma,
            value,
        }
    }

    /// Checks whether this inclusion proof is well-formed,
    /// and whether its root hash matches the given `root_hash`.
    pub fn validate(&self, root_hash: &[u8]) -> bool {
        if self.root_hash != root_hash || self.lemma.node_hash != root_hash {
            return false;
        }

        self.lemma.validate(self.algorithm)
    }
}

/// A `Lemma` holds the hash of a node, the hash of its sibling node,
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
/// must be equal to this `node_hash`.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Lemma {
    pub node_hash: Vec<u8>,
    pub sibling_hash: Option<Positioned<Vec<u8>>>,
    pub sub_lemma: Option<Box<Lemma>>,
}

impl Lemma {
    /// Attempts to generate a proof that the a value with hash `needle` is a member of the given `tree`.
    pub fn new<T>(tree: &Tree<T>, needle: &[u8]) -> Option<Lemma> {
        match *tree {
            Tree::Empty { .. } => None,

            Tree::Leaf { ref hash, .. } => Lemma::new_leaf_proof(hash, needle),

            Tree::Node {
                ref hash,
                ref left,
                ref right,
            } => Lemma::new_tree_proof(hash, needle, left, right),
        }
    }

    fn new_leaf_proof(hash: &[u8], needle: &[u8]) -> Option<Lemma> {
        if *hash == *needle {
            Some(Lemma {
                node_hash: hash.into(),
                sibling_hash: None,
                sub_lemma: None,
            })
        } else {
            None
        }
    }

    fn new_tree_proof<T>(
        hash: &[u8],
        needle: &[u8],
        left: &Tree<T>,
        right: &Tree<T>,
    ) -> Option<Lemma> {
        Lemma::new(left, needle)
            .map(|lemma| {
                let right_hash = right.hash().clone();
                let sub_lemma = Some(Positioned::Right(right_hash));
                (lemma, sub_lemma)
            })
            .or_else(|| {
                let sub_lemma = Lemma::new(right, needle);
                sub_lemma.map(|lemma| {
                    let left_hash = left.hash().clone();
                    let sub_lemma = Some(Positioned::Left(left_hash));
                    (lemma, sub_lemma)
                })
            })
            .map(|(sub_lemma, sibling_hash)| Lemma {
                node_hash: hash.into(),
                sibling_hash,
                sub_lemma: Some(Box::new(sub_lemma)),
            })
    }

    fn validate(&self, algorithm: &'static Algorithm) -> bool {
        match self.sub_lemma {
            None => self.sibling_hash.is_none(),

            Some(ref sub) => match self.sibling_hash {
                None => false,

                Some(Positioned::Left(ref hash)) => {
                    let combined = algorithm.hash_nodes(hash, &sub.node_hash);
                    let hashes_match = combined.as_ref() == self.node_hash.as_slice();
                    hashes_match && sub.validate(algorithm)
                }

                Some(Positioned::Right(ref hash)) => {
                    let combined = algorithm.hash_nodes(&sub.node_hash, hash);
                    let hashes_match = combined.as_ref() == self.node_hash.as_slice();
                    hashes_match && sub.validate(algorithm)
                }
            },
        }
    }
}

/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
#[cfg_attr(
    feature = "serialization-serde",
    derive(Serialize, Deserialize)
)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Positioned<T> {
    /// The value was found in the left branch
    Left(T),

    /// The value was found in the right branch
    Right(T),
}
<|endoftext|>


<commit_before>
<commit_msg>added stub for query execution<commit_after>pub fn execute_query(q: &str) -> {
    unimplemented!();
}<|endoftext|>


<commit_before>use vecmath::*;

use shape::*;
use vec3d::*;
use light::*;
use color::*;

use std;

pub struct Scene {
    shapes: Vec<Box<Shape + Sync>>,
    light: Light,
    camera_pos: Vec3d,
    camera_dir: Vec3d,
    camera_up: Vec3d,
    max_reflection: i32,
}

impl Scene {
    pub fn new(light: Light, camera_pos: Vec3d, camera_dir: Vec3d, camera_up: Vec3d) -> Scene {
        Scene {
            shapes: Vec::new(),
            light: light,
            camera_pos: camera_pos,
            camera_dir: camera_dir,
            camera_up: camera_up,
            max_reflection: 4,
        }
    }

    pub fn add_shape(&mut self, s: Box<Shape + Sync>) {
        self.shapes.push(s);
    }

    pub fn step(&mut self) {
        //self.light.translate(&[1.0, 0.0, 0.0]);
    }

    pub fn mv_camera_fwd(&mut self) {
        self.camera_pos = vec3_add(self.camera_pos, self.camera_dir);
    }

    pub fn mv_camera_back(&mut self) {
        self.camera_pos = vec3_sub(self.camera_pos, self.camera_dir);
    }

    pub fn rot_camera(&mut self, x_rot: f64, y_rot: f64) {
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, x_rot);
        self.camera_dir = vec3_normalized(self.camera_dir);
    }

    /// Returns an iterator that scans a full frame at given resolution
    pub fn draw_iter(&self, h: usize, v: usize) -> DrawIter {
        DrawIter::new(&self, h, v)
    }

    /// draw_iter converted to (u8, u8, u8)
    pub fn draw_iter_u8(&self,
                        h: usize,
                        v: usize)
                        -> std::iter::Map<DrawIter, fn(Color) -> (u8, u8, u8)> {
        self.draw_iter(h, v).map(Color::col_to_u8)
    }

    /// Returns an iterator for a line at given resolution
    pub fn line_iter(&self, h: usize, v: usize, l: usize) -> LineIter {
        LineIter::new(&self, h, v, l)
    }

    /// line_iter converted to (u8, u8, u8)
    pub fn line_iter_u8(&self,
                        h: usize,
                        v: usize,
                        l: usize)
                        -> std::iter::Map<LineIter, fn(Color) -> (u8, u8, u8)> {
        self.line_iter(h, v, l).map(Color::col_to_u8)
    }

    // Recursively trace lines
    fn trace(&self, point: &Vec3d, dir: &Vec3d, step: i32) -> Color {
        if step < self.max_reflection {
            let intersect_res = self.closest_q(point, dir);
            if let Some(intersect) = intersect_res {
                let feeler_d = vec3_sub(*self.light.get_pos(), intersect.point);
                let dist_light = vec3_len(feeler_d);
                let feeler_d_unit = vec3_normalized(feeler_d);
                let direct_light =
                    self.is_direct_light(&intersect.point, &feeler_d_unit, dist_light);

                let local = phong(point, &intersect, &self.light, direct_light);

                let tmp = vec3_normalized_sub(intersect.point, *point);
                let reflection_dir =
                    vec3_normalized_sub(tmp,
                                        vec3_scale(intersect.normal,
                                                   2.0 * vec3_dot(tmp, intersect.normal)));

                let reflected = self.trace(&intersect.point, &reflection_dir, step + 1);

                return Color::add(&local,
                                  &(Color::scale(&reflected, intersect.material.reflectivity)));
            } else {
                return BLACK;
            }
        }
        BLACK
    }

    // Is there anything on the path to the light
    fn is_direct_light(&self, point: &Vec3d, dir: &Vec3d, dl: f64) -> bool {
        let unitd = vec3_normalized(*dir);
        !self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .any(|dist_opt| dist_opt.map(|i| i < dl).unwrap_or(false))
    }

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let unitd = vec3_normalized(*dir);

        let closest = self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .zip(&self.shapes)
            .fold(None, |min, (dist_op, shape)| {
                match (dist_op, min) {
                    (Some(dist_val), Some((dist_min, _))) if dist_val < dist_min => {
                        Some((dist_val, shape))
                    }
                    (Some(dist_val), None) => Some((dist_val, shape)),
                    _ => min,
                }
            });

        // get intersection point info
        if let Some((_, shape)) = closest {
            shape.intersect(&point, &dir)
        } else {
            None
        }
    }
}

/// Iterator that iterates over a full frame
pub struct DrawIter<'a> {
    h_res: usize,
    v_res: usize,
    x: usize,
    y: usize,
    left: Vec3d,
    right_step: Vec3d,
    down_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> DrawIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize) -> DrawIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);
        DrawIter {
            h_res: h,
            v_res: v,
            x: 0,
            y: 0,
            left: left,
            point: point,
            right_step: right_step,
            down_step: down_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for DrawIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.y >= self.v_res {
            return None;
        }

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        self.x += 1;
        if self.x >= self.h_res {
            self.x = 0;
            self.y += 1;
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.down_step);
        }

        Some(c)
    }
}

/// Iterator that iterates over a single line
pub struct LineIter<'a> {
    h_res: usize,
    x: usize,
    right_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> LineIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize, l: usize) -> LineIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let mut point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);

        point = vec3_add(point, vec3_scale(down_step, l as f64));
        LineIter {
            h_res: h,
            x: 0,
            point: point,
            right_step: right_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for LineIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.x >= self.h_res {
            return None;
        }
        self.x += 1;

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        Some(c)
    }
}

// Calculate color with Phong model
fn phong(view_point: &Vec3d,
         intersection: &Intersection,
         light: &Light,
         direct_light: bool)
         -> Color {

    let point_material = intersection.material;
    let light_pos = light.get_pos();
    let light_color = light.get_color();
    let mut d = vec3_dot(vec3_normalized_sub(*light_pos, intersection.point),
                         intersection.normal);

    if d < 0.0 {
        d = 0.0;
    }

    let r_diffuse = if direct_light {
        light_color.0 * point_material.diffuse_color.0 * d
    } else {
        0.0
    };
    let g_diffuse = if direct_light {
        light_color.1 * point_material.diffuse_color.1 * d
    } else {
        0.0
    };
    let b_diffuse = if direct_light {
        light_color.2 * point_material.diffuse_color.2 * d
    } else {
        0.0
    };

    let r_ambient = point_material.ambient_color.0;
    let g_ambient = point_material.ambient_color.1;
    let b_ambient = point_material.ambient_color.2;

    let v = vec3_normalized_sub(*view_point, intersection.point);
    let lt = vec3_normalized_sub(*light_pos, intersection.point);
    let r = vec3_normalized_sub(vec3_scale(intersection.normal,
                                           2.0 * vec3_dot(intersection.normal, lt)),
                                lt);

    let mut s = vec3_dot(r, v).powf(point_material.shininess);
    if s < 0.0 {
        s = 0.0;
    }

    let r_specular = if direct_light {
        light_color.0 * point_material.specular_color.0 * s
    } else {
        0.0
    };
    let g_specular = if direct_light {
        light_color.1 * point_material.specular_color.1 * s
    } else {
        0.0
    };
    let b_specular = if direct_light {
        light_color.2 * point_material.specular_color.2 * s
    } else {
        0.0
    };

    let mut r_sum = r_ambient + r_diffuse + r_specular;
    let mut g_sum = g_ambient + g_diffuse + g_specular;
    let mut b_sum = b_ambient + b_diffuse + b_specular;

    if r_sum > 1.0 {
        r_sum = 1.0;
    }

    if g_sum > 1.0 {
        g_sum = 1.0;
    }

    if b_sum > 1.0 {
        b_sum = 1.0;
    }

    Color(r_sum, g_sum, b_sum)
}
<commit_msg>Minor style change in trace()<commit_after>use vecmath::*;

use shape::*;
use vec3d::*;
use light::*;
use color::*;

use std;

pub struct Scene {
    shapes: Vec<Box<Shape + Sync>>,
    light: Light,
    camera_pos: Vec3d,
    camera_dir: Vec3d,
    camera_up: Vec3d,
    max_reflection: i32,
}

impl Scene {
    pub fn new(light: Light, camera_pos: Vec3d, camera_dir: Vec3d, camera_up: Vec3d) -> Scene {
        Scene {
            shapes: Vec::new(),
            light: light,
            camera_pos: camera_pos,
            camera_dir: camera_dir,
            camera_up: camera_up,
            max_reflection: 4,
        }
    }

    pub fn add_shape(&mut self, s: Box<Shape + Sync>) {
        self.shapes.push(s);
    }

    pub fn step(&mut self) {
        //self.light.translate(&[1.0, 0.0, 0.0]);
    }

    pub fn mv_camera_fwd(&mut self) {
        self.camera_pos = vec3_add(self.camera_pos, self.camera_dir);
    }

    pub fn mv_camera_back(&mut self) {
        self.camera_pos = vec3_sub(self.camera_pos, self.camera_dir);
    }

    pub fn rot_camera(&mut self, x_rot: f64, y_rot: f64) {
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, x_rot);
        self.camera_dir = vec3_normalized(self.camera_dir);
    }

    /// Returns an iterator that scans a full frame at given resolution
    pub fn draw_iter(&self, h: usize, v: usize) -> DrawIter {
        DrawIter::new(&self, h, v)
    }

    /// draw_iter converted to (u8, u8, u8)
    pub fn draw_iter_u8(&self,
                        h: usize,
                        v: usize)
                        -> std::iter::Map<DrawIter, fn(Color) -> (u8, u8, u8)> {
        self.draw_iter(h, v).map(Color::col_to_u8)
    }

    /// Returns an iterator for a line at given resolution
    pub fn line_iter(&self, h: usize, v: usize, l: usize) -> LineIter {
        LineIter::new(&self, h, v, l)
    }

    /// line_iter converted to (u8, u8, u8)
    pub fn line_iter_u8(&self,
                        h: usize,
                        v: usize,
                        l: usize)
                        -> std::iter::Map<LineIter, fn(Color) -> (u8, u8, u8)> {
        self.line_iter(h, v, l).map(Color::col_to_u8)
    }

    // Recursively trace lines
    fn trace(&self, point: &Vec3d, dir: &Vec3d, depth: i32) -> Color {
        if depth >= self.max_reflection {
            return BLACK;
        }

        let intersect_res = self.closest_q(point, dir);
        if let Some(intersect) = intersect_res {
            let feeler_d = vec3_sub(*self.light.get_pos(), intersect.point);
            let dist_light = vec3_len(feeler_d);
            let feeler_d_unit = vec3_normalized(feeler_d);
            let direct_light =
                self.is_direct_light(&intersect.point, &feeler_d_unit, dist_light);

            let local = phong(point, &intersect, &self.light, direct_light);

            let tmp = vec3_normalized_sub(intersect.point, *point);
            let reflection_dir =
                vec3_normalized_sub(tmp,
                                    vec3_scale(intersect.normal,
                                               2.0 * vec3_dot(tmp, intersect.normal)));

            let reflected = self.trace(&intersect.point, &reflection_dir, depth + 1);

            Color::add(&local, &(Color::scale(&reflected, intersect.material.reflectivity)))
        } else {
            BLACK
        }
    }

    // Is there anything on the path to the light
    fn is_direct_light(&self, point: &Vec3d, dir: &Vec3d, dl: f64) -> bool {
        let unitd = vec3_normalized(*dir);
        !self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .any(|dist_opt| dist_opt.map(|i| i < dl).unwrap_or(false))
    }

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let unitd = vec3_normalized(*dir);

        let closest = self.shapes
            .iter()
            .map(|&ref x| x.intersect_dist(point, &unitd))
            .zip(&self.shapes)
            .fold(None, |min, (dist_op, shape)| {
                match (dist_op, min) {
                    (Some(dist_val), Some((dist_min, _))) if dist_val < dist_min => {
                        Some((dist_val, shape))
                    }
                    (Some(dist_val), None) => Some((dist_val, shape)),
                    _ => min,
                }
            });

        // get intersection point info
        if let Some((_, shape)) = closest {
            shape.intersect(&point, &dir)
        } else {
            None
        }
    }
}

/// Iterator that iterates over a full frame
pub struct DrawIter<'a> {
    h_res: usize,
    v_res: usize,
    x: usize,
    y: usize,
    left: Vec3d,
    right_step: Vec3d,
    down_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> DrawIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize) -> DrawIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);
        DrawIter {
            h_res: h,
            v_res: v,
            x: 0,
            y: 0,
            left: left,
            point: point,
            right_step: right_step,
            down_step: down_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for DrawIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.y >= self.v_res {
            return None;
        }

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        self.x += 1;
        if self.x >= self.h_res {
            self.x = 0;
            self.y += 1;
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.left);
            self.point = vec3_add(self.point, self.down_step);
        }

        Some(c)
    }
}

/// Iterator that iterates over a single line
pub struct LineIter<'a> {
    h_res: usize,
    x: usize,
    right_step: Vec3d,
    point: Vec3d,
    scene: &'a Scene,
}

impl<'a> LineIter<'a> {
    fn new(scene: &Scene, h: usize, v: usize, l: usize) -> LineIter {
        let left = vec3_normalized(vec3_cross(scene.camera_dir, scene.camera_up));
        let up = vec3_normalized(vec3_cross(left, scene.camera_dir));
        let mut point = vec3_add(vec3_add(left, up), scene.camera_dir);
        let right_step = vec3_scale(left, -2.0 / h as f64);
        let down_step = vec3_scale(up, -2.0 / v as f64);

        point = vec3_add(point, vec3_scale(down_step, l as f64));
        LineIter {
            h_res: h,
            x: 0,
            point: point,
            right_step: right_step,
            scene: scene,
        }
    }
}

impl<'a> Iterator for LineIter<'a> {
    type Item = Color;

    fn next(&mut self) -> Option<Self::Item> {
        if self.x >= self.h_res {
            return None;
        }
        self.x += 1;

        self.point = vec3_add(self.point, self.right_step);

        let c = self.scene.trace(&self.scene.camera_pos, &vec3_normalized(self.point), 0);

        Some(c)
    }
}

// Calculate color with Phong model
fn phong(view_point: &Vec3d,
         intersection: &Intersection,
         light: &Light,
         direct_light: bool)
         -> Color {

    let point_material = intersection.material;
    let light_pos = light.get_pos();
    let light_color = light.get_color();
    let mut d = vec3_dot(vec3_normalized_sub(*light_pos, intersection.point),
                         intersection.normal);

    if d < 0.0 {
        d = 0.0;
    }

    let r_diffuse = if direct_light {
        light_color.0 * point_material.diffuse_color.0 * d
    } else {
        0.0
    };
    let g_diffuse = if direct_light {
        light_color.1 * point_material.diffuse_color.1 * d
    } else {
        0.0
    };
    let b_diffuse = if direct_light {
        light_color.2 * point_material.diffuse_color.2 * d
    } else {
        0.0
    };

    let r_ambient = point_material.ambient_color.0;
    let g_ambient = point_material.ambient_color.1;
    let b_ambient = point_material.ambient_color.2;

    let v = vec3_normalized_sub(*view_point, intersection.point);
    let lt = vec3_normalized_sub(*light_pos, intersection.point);
    let r = vec3_normalized_sub(vec3_scale(intersection.normal,
                                           2.0 * vec3_dot(intersection.normal, lt)),
                                lt);

    let mut s = vec3_dot(r, v).powf(point_material.shininess);
    if s < 0.0 {
        s = 0.0;
    }

    let r_specular = if direct_light {
        light_color.0 * point_material.specular_color.0 * s
    } else {
        0.0
    };
    let g_specular = if direct_light {
        light_color.1 * point_material.specular_color.1 * s
    } else {
        0.0
    };
    let b_specular = if direct_light {
        light_color.2 * point_material.specular_color.2 * s
    } else {
        0.0
    };

    let mut r_sum = r_ambient + r_diffuse + r_specular;
    let mut g_sum = g_ambient + g_diffuse + g_specular;
    let mut b_sum = b_ambient + b_diffuse + b_specular;

    if r_sum > 1.0 {
        r_sum = 1.0;
    }

    if g_sum > 1.0 {
        g_sum = 1.0;
    }

    if b_sum > 1.0 {
        b_sum = 1.0;
    }

    Color(r_sum, g_sum, b_sum)
}
<|endoftext|>


<commit_before>use blip_buf::BlipBuf;
use cpal;
use std;

macro_rules! try_opt {
     ( $expr:expr ) => {
         match $expr {
             Some(v) => v,
             None => return None,
         }
     }
}

pub struct Sound {
    waveram: [u8; 16],
    channel3_on: bool,
    channel3_len: u8,
    channel3_vol: u8,
    channel3_freq: u16,
    channel3_counter: Counter,
    voice: Option<cpal::Voice>,
    blip: Option<BlipBuf>,
}

enum Counter {
    Stopped,
    Continuous,
    Timed(u8),
}

impl Sound {
    pub fn new() -> Sound {
        let voice = get_channel();
        if voice.is_none() {
            println!("Could not open audio device");
        }

        let blipbuf = voice.as_ref()
            .map(|v| {
                let mut bb = BlipBuf::new(v.format().samples_rate.0 / 10);
                bb.set_rates(0x400000 as f64, v.format().samples_rate.0 as f64);
                bb
            });

        Sound {
            waveram: [0; 16],
            channel3_on: false,
            channel3_len: 0,
            channel3_vol: 0,
            channel3_freq: 0,
            channel3_counter: Counter::Stopped,
            voice: voice,
            blip: blipbuf,
        }
    }

   pub fn rb(&self, a: u16) -> u8 {
        match a {
            0xFF1A => if self.channel3_on { 0x80 } else { 0 },
            0xFF1B => self.channel3_len,
            0xFF1C => self.channel3_vol << 5,
            0xFF1D => 0,
            0xFF1E => 0,
            0xFF30 ... 0xFF3F => self.waveram[a as usize - 0xFF30],
            _ => 0,
        }
    }

    pub fn wb(&mut self, a: u16, v: u8) {
        match a {
            0xFF1A => self.channel3_on = v & 0x80 == 0x80,
            0xFF1B => self.channel3_len = v,
            0xFF1C => self.channel3_vol = (v >> 5) & 0x3,
            0xFF1D => self.channel3_freq = self.channel3_freq & 0xFF00 | v as u16,
            0xFF1E => {
                self.channel3_freq = self.channel3_freq & 0x00FF | (((v & 0x7) as u16) << 8);
                match v & 0b_1100_0000 {
                    0b_1000_0000 => self.channel3_counter = Counter::Continuous,
                    0b_1100_0000 => self.channel3_counter = Counter::Timed(self.channel3_len),
                    _ => (),
                }
            }
            0xFF30 ... 0xFF3F => self.waveram[a as usize - 0xFF30] = v,
            _ => (),
        }
    }

    pub fn do_cycle(&mut self, _cycles: u32)
    {
        // To be implemented
    }
}

fn get_channel() -> Option<cpal::Voice> {
    let endpoint = try_opt!(cpal::get_default_endpoint());
    let format = try_opt!(endpoint.get_supported_formats_list().ok().and_then(|mut v| v.next()));
    let channel = try_opt!(cpal::Voice::new(&endpoint, &format).ok());
    Some(channel)
}

fn play_blipbuf(channel: &mut cpal::Voice, blip: &mut BlipBuf) {
    let channels_len = channel.format().channels.len();

    while blip.samples_avail() > 0 {
        let buf = &mut [0; 1024];
        let count = blip.read_samples(buf, false);
        let blipbuf = &buf[0..count];
        let mut done = 0;
        let mut lastdone = count;

        while lastdone != done && done < count {
            lastdone = done;
            let channelbuf = &blipbuf[done..];
            match channel.append_data(channelbuf.len()) {
                cpal::UnknownTypeBuffer::U16(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        let value = *value as u16 + std::i16::MAX as u16;
                        for out in sample.iter_mut() { *out = value; }
                        done += 1;
                    }
                }
                cpal::UnknownTypeBuffer::I16(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        for out in sample.iter_mut() { *out = *value; }
                        done += 1;
                    }
                }
                cpal::UnknownTypeBuffer::F32(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        let value = *value as f32 / std::i16::MAX as f32;
                        for out in sample.iter_mut() { *out = value; }
                        done += 1;
                    }
                }
            }
            channel.play();
        }
    }
}
<commit_msg>Ensure a default endpoint exists<commit_after>use blip_buf::BlipBuf;
use cpal;
use std;

macro_rules! try_opt {
     ( $expr:expr ) => {
         match $expr {
             Some(v) => v,
             None => return None,
         }
     }
}

pub struct Sound {
    waveram: [u8; 16],
    channel3_on: bool,
    channel3_len: u8,
    channel3_vol: u8,
    channel3_freq: u16,
    channel3_counter: Counter,
    voice: Option<cpal::Voice>,
    blip: Option<BlipBuf>,
}

enum Counter {
    Stopped,
    Continuous,
    Timed(u8),
}

impl Sound {
    pub fn new() -> Sound {
        let voice = get_channel();
        if voice.is_none() {
            println!("Could not open audio device");
        }

        let blipbuf = voice.as_ref()
            .map(|v| {
                let mut bb = BlipBuf::new(v.format().samples_rate.0 / 10);
                bb.set_rates(0x400000 as f64, v.format().samples_rate.0 as f64);
                bb
            });

        Sound {
            waveram: [0; 16],
            channel3_on: false,
            channel3_len: 0,
            channel3_vol: 0,
            channel3_freq: 0,
            channel3_counter: Counter::Stopped,
            voice: voice,
            blip: blipbuf,
        }
    }

   pub fn rb(&self, a: u16) -> u8 {
        match a {
            0xFF1A => if self.channel3_on { 0x80 } else { 0 },
            0xFF1B => self.channel3_len,
            0xFF1C => self.channel3_vol << 5,
            0xFF1D => 0,
            0xFF1E => 0,
            0xFF30 ... 0xFF3F => self.waveram[a as usize - 0xFF30],
            _ => 0,
        }
    }

    pub fn wb(&mut self, a: u16, v: u8) {
        match a {
            0xFF1A => self.channel3_on = v & 0x80 == 0x80,
            0xFF1B => self.channel3_len = v,
            0xFF1C => self.channel3_vol = (v >> 5) & 0x3,
            0xFF1D => self.channel3_freq = self.channel3_freq & 0xFF00 | v as u16,
            0xFF1E => {
                self.channel3_freq = self.channel3_freq & 0x00FF | (((v & 0x7) as u16) << 8);
                match v & 0b_1100_0000 {
                    0b_1000_0000 => self.channel3_counter = Counter::Continuous,
                    0b_1100_0000 => self.channel3_counter = Counter::Timed(self.channel3_len),
                    _ => (),
                }
            }
            0xFF30 ... 0xFF3F => self.waveram[a as usize - 0xFF30] = v,
            _ => (),
        }
    }

    pub fn do_cycle(&mut self, _cycles: u32)
    {
        // To be implemented
    }
}

fn get_channel() -> Option<cpal::Voice> {
    if cpal::get_endpoints_list().count() == 0 { return None; }
    let endpoint = try_opt!(cpal::get_default_endpoint());
    let format = try_opt!(endpoint.get_supported_formats_list().ok().and_then(|mut v| v.next()));
    let channel = try_opt!(cpal::Voice::new(&endpoint, &format).ok());
    Some(channel)
}

fn play_blipbuf(channel: &mut cpal::Voice, blip: &mut BlipBuf) {
    let channels_len = channel.format().channels.len();

    while blip.samples_avail() > 0 {
        let buf = &mut [0; 1024];
        let count = blip.read_samples(buf, false);
        let blipbuf = &buf[0..count];
        let mut done = 0;
        let mut lastdone = count;

        while lastdone != done && done < count {
            lastdone = done;
            let channelbuf = &blipbuf[done..];
            match channel.append_data(channelbuf.len()) {
                cpal::UnknownTypeBuffer::U16(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        let value = *value as u16 + std::i16::MAX as u16;
                        for out in sample.iter_mut() { *out = value; }
                        done += 1;
                    }
                }
                cpal::UnknownTypeBuffer::I16(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        for out in sample.iter_mut() { *out = *value; }
                        done += 1;
                    }
                }
                cpal::UnknownTypeBuffer::F32(mut buffer) => {
                    for (sample, value) in buffer.chunks_mut(channels_len).zip(channelbuf) {
                        let value = *value as f32 / std::i16::MAX as f32;
                        for out in sample.iter_mut() { *out = value; }
                        done += 1;
                    }
                }
            }
            channel.play();
        }
    }
}
<|endoftext|>


<commit_before>use std::path;
use std::path::Path;
use std::fs;
use std::fs::File;
use std::io::BufReader;

use std::io::Read;

use crypto::digest::Digest;
use crypto::sha2::Sha256;

pub fn store_file(store_path: &Path, source_file: &Path) -> String {
	let tmp_path = store_path.join("tmp");

	fs::copy(&source_file, &tmp_path);

	let hash = hash(&source_file);

	let final_path = store_path.join(&hash);

	fs::rename(&tmp_path, &final_path);

	hash
}

pub fn extract_file(store_path: &Path, hash: &String, data_path: &Path, filename: &String, timestamp: u64) {
	let file_in_store = store_path.join(hash);
	let file_in_wd = Path::new(filename);
	let tmp_path = data_path.join("tmp");

	println!("Extract from {} to {} ", file_in_store.to_str().unwrap(), file_in_wd.to_str().unwrap());

	fs::copy(&file_in_store, &tmp_path);
	fs::rename(&tmp_path, &file_in_wd);
}

fn hash(file: &Path) -> String {
	let mut f = File::open(&file).unwrap();
	let mut reader = BufReader::new(f);
	let mut buffer = [0; 512];

	let mut hasher = Sha256::new();

	loop {
		let bytesRead = reader.read(&mut buffer).unwrap();
		if bytesRead == 512 {
			hasher.input(&buffer);
		} else {
			let v : Vec<u8> = buffer.iter().cloned().collect();
			let (x, y) = v.split_at(bytesRead);
			hasher.input(x);
		}
		if bytesRead == 0 { break; }
	}

	let hex = hasher.result_str();
//	println!("Hash: {:?}", hex);
	hex
}
<commit_msg>Set timestamp when updating files<commit_after>use std::path;
use std::path::Path;
use std::fs;
use std::fs::File;
use std::io::BufReader;
use filetime::FileTime;
use filetime;

use std::io::Read;

use crypto::digest::Digest;
use crypto::sha2::Sha256;

pub fn store_file(store_path: &Path, source_file: &Path) -> String {
	let tmp_path = store_path.join("tmp");

	fs::copy(&source_file, &tmp_path);

	let hash = hash(&source_file);

	let final_path = store_path.join(&hash);

	fs::rename(&tmp_path, &final_path);

	hash
}

pub fn extract_file(store_path: &Path, hash: &String, data_path: &Path, filename: &String, timestamp: u64) {
	let file_in_store = store_path.join(hash);
	let file_in_wd = Path::new(filename);
	let tmp_path = data_path.join("tmp");

	println!("Extract from {} to {} ", file_in_store.to_str().unwrap(), file_in_wd.to_str().unwrap());

	fs::copy(&file_in_store, &tmp_path);
	fs::rename(&tmp_path, &file_in_wd);

	let seconds_since_1970 = FileTime::from_seconds_since_1970(timestamp, 0);
	filetime::set_file_times(&file_in_wd, seconds_since_1970, seconds_since_1970);
}

fn hash(file: &Path) -> String {
	let mut f = File::open(&file).unwrap();
	let mut reader = BufReader::new(f);
	let mut buffer = [0; 512];

	let mut hasher = Sha256::new();

	loop {
		let bytesRead = reader.read(&mut buffer).unwrap();
		if bytesRead == 512 {
			hasher.input(&buffer);
		} else {
			let v : Vec<u8> = buffer.iter().cloned().collect();
			let (x, y) = v.split_at(bytesRead);
			hasher.input(x);
		}
		if bytesRead == 0 { break; }
	}

	let hex = hasher.result_str();
//	println!("Hash: {:?}", hex);
	hex
}
<|endoftext|>


<commit_before>use repo::Workspace;

use std::str;
use std::process::{Command, ExitStatus};
use std::sync::Mutex;

fn benchmark(workdir: &str) {}

fn build(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("build")
        .arg("--release")
        .status()
        .expect("Failed to execute 'cargo build'!")
}

pub fn taste_commit(wsl: &Mutex<Workspace>, id: &String) {
    println!("Tasting commit {}", id);
    let ws = wsl.lock().unwrap();
    ws.checkout_commit(id);

    // Update dependencies
    if !update(&ws.path).success() {
        println!("Failed to update crates for {}", id);
        return;
    }

    // Try to build the commit
    if !build(&ws.path).success() {
        println!("Failed to build {}", id);
        return;
    }

    // Run benchmarks and collect results
    benchmark(&ws.path);
}

fn update(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("update")
        .status()
        .expect("Failed to execute 'cargo update'!")
}
<commit_msg>Invoke `cargo bench` (no result collection yet)<commit_after>use repo::Workspace;

use std::str;
use std::process::{Command, ExitStatus};
use std::sync::Mutex;

fn benchmark(workdir: &str) {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("bench")
        .arg("--release")
        .status()
        .expect("Failed to execute 'cargo bench'!")
}

fn build(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("build")
        .arg("--release")
        .status()
        .expect("Failed to execute 'cargo build'!")
}

pub fn taste_commit(wsl: &Mutex<Workspace>, id: &String) {
    println!("Tasting commit {}", id);
    let ws = wsl.lock().unwrap();
    ws.checkout_commit(id);

    // Update dependencies
    if !update(&ws.path).success() {
        println!("Failed to update crates for {}", id);
        return;
    }

    // Try to build the commit
    if !build(&ws.path).success() {
        println!("Failed to build {}", id);
        return;
    }

    // Run benchmarks and collect results
    benchmark(&ws.path);
}

fn update(workdir: &str) -> ExitStatus {
    Command::new("cargo")
        .current_dir(workdir)
        .arg("update")
        .status()
        .expect("Failed to execute 'cargo update'!")
}
<|endoftext|>


<commit_before>macro_rules! vnull {
  () => {
    $crate::value::Value::Null
  }
}

macro_rules! vbool {
  ($value:expr) => {
    $crate::value::Value::Boolean($value)
  }
}

macro_rules! vnum {
  ($value:expr) => {
    $crate::value::Value::Number(f64::from($value))
  }
}

macro_rules! vstring {
  ($value:expr) => {
    $crate::value::Value::String(String::from($value))
  }
}

macro_rules! vobject {
  ($($key:expr => $value:expr),*) => {
    {
      let mut _map = ::linear_map::LinearMap::new();
      $(
        _map.insert(String::from($key), $value);
      )*
      $crate::value::Value::Object(_map)
    }
  }
}

macro_rules! varray {
  ($($value:expr),*) => {
    {
      let mut _vec = Vec::new();
      $(
        _vec.push($value);
      )*
      $crate::value::Value::Array(_vec)
    }
  }
}

macro_rules! point {
  ($($key:expr),*) => {
    {
      let mut _vec = Vec::new();
      $(
        _vec.push(String::from($key));
      )*
      _vec
    }
  };
}

macro_rules! qvalue {
  () => {
    $crate::query::Query::Value
  }
}

macro_rules! qobject {
  ($($key:expr => $value:expr),*) => {
    {
      let mut _map = ::linear_map::LinearMap::new();
      $(
        _map.insert(String::from($key), $value);
      )*
      $crate::query::Query::Object(_map)
    }
  }
}
<commit_msg>chore: remove semicolon<commit_after>macro_rules! vnull {
  () => {
    $crate::value::Value::Null
  }
}

macro_rules! vbool {
  ($value:expr) => {
    $crate::value::Value::Boolean($value)
  }
}

macro_rules! vnum {
  ($value:expr) => {
    $crate::value::Value::Number(f64::from($value))
  }
}

macro_rules! vstring {
  ($value:expr) => {
    $crate::value::Value::String(String::from($value))
  }
}

macro_rules! vobject {
  ($($key:expr => $value:expr),*) => {
    {
      let mut _map = ::linear_map::LinearMap::new();
      $(
        _map.insert(String::from($key), $value);
      )*
      $crate::value::Value::Object(_map)
    }
  }
}

macro_rules! varray {
  ($($value:expr),*) => {
    {
      let mut _vec = Vec::new();
      $(
        _vec.push($value);
      )*
      $crate::value::Value::Array(_vec)
    }
  }
}

macro_rules! point {
  ($($key:expr),*) => {
    {
      let mut _vec = Vec::new();
      $(
        _vec.push(String::from($key));
      )*
      _vec
    }
  }
}

macro_rules! qvalue {
  () => {
    $crate::query::Query::Value
  }
}

macro_rules! qobject {
  ($($key:expr => $value:expr),*) => {
    {
      let mut _map = ::linear_map::LinearMap::new();
      $(
        _map.insert(String::from($key), $value);
      )*
      $crate::query::Query::Object(_map)
    }
  }
}
<|endoftext|>