<commit_before>
use std::collections::hashmap::HashMap;
use uuid::Uuid;

use graphics::*;

use event::{
    Event,
    Behavior,
    State,
    Running,
};

use Sprite;

use action::{
    Action,
    ActionState,
};

/// A scene is used to manage sprite's life and run action with sprite
pub struct Scene<I: ImageSize> {
    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,
    running: HashMap<Uuid, Vec<(Behavior<Action>, State<Action, ActionState>, bool)>>,
}

impl<I: ImageSize> Scene<I> {
    /// Create a new scene
    pub fn new() -> Scene<I> {
        Scene {
            children: Vec::new(),
            children_index: HashMap::new(),
            running: HashMap::new(),
        }
    }

    /// Update action's state
    pub fn update(&mut self, e: &Event) {
        // regenerate the actions and their states
        let running = self.running.clone();
        self.running.clear();

        for (id, actions) in running.into_iter() {
            let mut new_actions = Vec::new();

            for (b, mut a, paused) in actions.into_iter() {
                if paused {
                    new_actions.push((b, a, paused));
                    continue;
                }

                let sprite = self.child_mut(id).unwrap();
                let (status, _) = a.event(e, |_, dt, action, s| {
                    let (state, status, remain) = {
                        let start_state;
                        let state = match *s {
                            None => { start_state = action.to_state(sprite); &start_state },
                            Some(ref state) => state,
                        };
                        state.update(sprite, dt)
                    };
                    *s = state;
                    (status, remain)
                });

                match status {
                    // the behavior is still running, add it for next update
                    Running => {
                        new_actions.push((b, a, paused));
                    },
                    _ => {},
                }
            }

            if new_actions.len() > 0 {
                self.running.insert(id, new_actions);
            }
        }
    }

    /// Render this scene
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        for child in self.children.iter() {
            child.draw(c, b);
        }
    }

    /// Register action with sprite
    pub fn run(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let actions = self.running.find_or_insert_with(sprite_id, |_| Vec::new());
        let state = State::new(action.clone());
        actions.push((action.clone(), state, false));
    }

    fn find(&self, sprite_id: Uuid, action: &Behavior<Action>) -> Option<uint> {
        let mut index = None;
        match self.running.find(&sprite_id) {
            Some(actions) => {
                for i in range(0, actions.len()) {
                    let (ref b, _, _) = actions[i];
                    if b == action {
                        index = Some(i);
                        break;
                    }
                }
            },
            _ => {},
        }
        index
    }

    /// Pause a running action of the sprite
    pub fn pause(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, _) = actions.remove(i).unwrap();
            actions.push((b, s, true));
        }
    }

    /// Resume a paused action of the sprite
    pub fn resume(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, _) = actions.remove(i).unwrap();
            actions.push((b, s, false));
        }
    }

    /// Toggle an action of the sprite
    pub fn toggle(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, paused) = actions.remove(i).unwrap();
            actions.push((b, s, !paused));
        }
    }

    /// Stop a running action of the sprite
    pub fn stop(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            let i = index.unwrap();
            self.running.get_mut(&sprite_id).remove(i);
        }
    }

    /// Stop all running actions of the sprite
    pub fn stop_all(&mut self, sprite_id: Uuid) {
        self.running.remove(&sprite_id);
    }

    /// Get all the running actions in the scene
    pub fn running(&self) -> uint {
        let mut total = 0;
        for (_, actions) in self.running.iter() {
            total += actions.len();
        }
        total
    }

    /// Add sprite to scene
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    fn stop_all_including_children(&mut self, sprite: &Sprite<I>) {
        self.stop_all(sprite.id());
        for child in sprite.children().iter() {
            self.stop_all_including_children(child);
        }
    }

    /// Remove the child by `id` from the scene's children or grandchild
    /// will stop all the actions run by this child
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        let removed = match self.children_index.pop(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        };

        if removed.is_some() {
            self.stop_all_including_children(removed.as_ref().unwrap());
        }

        removed
    }

    /// Find the child by `id` from the scene's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(self.children.get_mut(*i)) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }
}

<commit_msg>Fixed compiler warning<commit_after>
use std::collections::hashmap::HashMap;
use uuid::Uuid;

use graphics::*;

use event::{
    Event,
    Behavior,
    State,
    Running,
};

use Sprite;

use action::{
    Action,
    ActionState,
};

/// A scene is used to manage sprite's life and run action with sprite
pub struct Scene<I: ImageSize> {
    children: Vec<Sprite<I>>,
    children_index: HashMap<Uuid, uint>,
    running: HashMap<Uuid, Vec<(Behavior<Action>, State<Action, ActionState>, bool)>>,
}

impl<I: ImageSize> Scene<I> {
    /// Create a new scene
    pub fn new() -> Scene<I> {
        Scene {
            children: Vec::new(),
            children_index: HashMap::new(),
            running: HashMap::new(),
        }
    }

    /// Update action's state
    pub fn update(&mut self, e: &Event) {
        // regenerate the actions and their states
        let running = self.running.clone();
        self.running.clear();

        for (id, actions) in running.into_iter() {
            let mut new_actions = Vec::new();

            for (b, mut a, paused) in actions.into_iter() {
                if paused {
                    new_actions.push((b, a, paused));
                    continue;
                }

                let sprite = self.child_mut(id).unwrap();
                let (status, _) = a.event(e, |_, dt, action, s| {
                    let (state, status, remain) = {
                        let start_state;
                        let state = match *s {
                            None => { start_state = action.to_state(sprite); &start_state },
                            Some(ref state) => state,
                        };
                        state.update(sprite, dt)
                    };
                    *s = state;
                    (status, remain)
                });

                match status {
                    // the behavior is still running, add it for next update
                    Running => {
                        new_actions.push((b, a, paused));
                    },
                    _ => {},
                }
            }

            if new_actions.len() > 0 {
                self.running.insert(id, new_actions);
            }
        }
    }

    /// Render this scene
    pub fn draw<B: BackEnd<I>>(&self, c: &Context, b: &mut B) {
        for child in self.children.iter() {
            child.draw(c, b);
        }
    }

    /// Register action with sprite
    pub fn run(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        use std::collections::hashmap::{ Vacant, Occupied };
        let actions = match self.running.entry(sprite_id) {
            Vacant(entry) => entry.set(Vec::new()),
            Occupied(entry) => entry.into_mut()
        };
        let state = State::new(action.clone());
        actions.push((action.clone(), state, false));
    }

    fn find(&self, sprite_id: Uuid, action: &Behavior<Action>) -> Option<uint> {
        let mut index = None;
        match self.running.find(&sprite_id) {
            Some(actions) => {
                for i in range(0, actions.len()) {
                    let (ref b, _, _) = actions[i];
                    if b == action {
                        index = Some(i);
                        break;
                    }
                }
            },
            _ => {},
        }
        index
    }

    /// Pause a running action of the sprite
    pub fn pause(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, _) = actions.remove(i).unwrap();
            actions.push((b, s, true));
        }
    }

    /// Resume a paused action of the sprite
    pub fn resume(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            println!("found");
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, _) = actions.remove(i).unwrap();
            actions.push((b, s, false));
        }
    }

    /// Toggle an action of the sprite
    pub fn toggle(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            let i = index.unwrap();
            let actions = self.running.get_mut(&sprite_id);
            let (b, s, paused) = actions.remove(i).unwrap();
            actions.push((b, s, !paused));
        }
    }

    /// Stop a running action of the sprite
    pub fn stop(&mut self, sprite_id: Uuid, action: &Behavior<Action>) {
        let index = self.find(sprite_id, action);
        if index.is_some() {
            let i = index.unwrap();
            self.running.get_mut(&sprite_id).remove(i);
        }
    }

    /// Stop all running actions of the sprite
    pub fn stop_all(&mut self, sprite_id: Uuid) {
        self.running.remove(&sprite_id);
    }

    /// Get all the running actions in the scene
    pub fn running(&self) -> uint {
        let mut total = 0;
        for (_, actions) in self.running.iter() {
            total += actions.len();
        }
        total
    }

    /// Add sprite to scene
    pub fn add_child(&mut self, sprite: Sprite<I>) -> Uuid {
        let id = sprite.id();
        self.children.push(sprite);
        self.children_index.insert(id, self.children.len() - 1);
        id
    }

    fn stop_all_including_children(&mut self, sprite: &Sprite<I>) {
        self.stop_all(sprite.id());
        for child in sprite.children().iter() {
            self.stop_all_including_children(child);
        }
    }

    /// Remove the child by `id` from the scene's children or grandchild
    /// will stop all the actions run by this child
    pub fn remove_child(&mut self, id: Uuid) -> Option<Sprite<I>> {
        let removed = match self.children_index.pop(&id) {
            Some(i) => {
                let removed = self.children.remove(i).unwrap();
                // Removing a element of vector will alter the index,
                // update the mapping from uuid to index.
                for index in range(i, self.children.len()) {
                    let uuid = self.children[index].id();
                    self.children_index.insert(uuid, index);
                }
                Some(removed)
            },
            None => {
                for child in self.children.iter_mut() {
                    match child.remove_child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        };

        if removed.is_some() {
            self.stop_all_including_children(removed.as_ref().unwrap());
        }

        removed
    }

    /// Find the child by `id` from the scene's children or grandchild
    pub fn child(&self, id: Uuid) -> Option<&Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(&self.children[*i]) },
            None => {
                for child in self.children.iter() {
                    match child.child(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }

    /// Find the child by `id` from this sprite's children or grandchild, mutability
    pub fn child_mut(&mut self, id: Uuid) -> Option<&mut Sprite<I>> {
        match self.children_index.find(&id) {
            Some(i) => { Some(self.children.get_mut(*i)) },
            None => {
                for child in self.children.iter_mut() {
                    match child.child_mut(id) {
                        Some(c) => {
                            return Some(c);
                        }
                        _ => {}
                    }
                }

                None
            }
        }
    }
}

<|endoftext|>


<commit_before>use std::f64::INFINITY;
use std::cmp::min;

use shapes::Object;
use point::Point;
use color::{Color, Black};

pub struct Spot {
  pos: Point,
  color: Color,
}

pub struct Scene {
  eye: Point,
  spots: ~[Spot],
  objects: ~[Object]
}

impl Scene {
  pub fn get_closest<'a>(&'a self, vector: &'a Point) -> (Option<&'a Object>, f64) {
    let mut min: f64 = INFINITY;
    let mut closest: Option<&'a Object> = None;

    for obj in self.objects.iter() {
      let k = obj.shape.hit(&(self.eye - obj.pos), vector);
      if k > 0. && k < min {
        min = k;
        closest = Some(obj);
      }
    }

    return (closest, min);
  }

  fn get_shadow(&self, cur: &Object, spot: &Spot, inter: &Point) -> bool {
    for obj in self.objects.iter() {
      if obj as *Object == cur as *Object {
        continue;
      }

      let k = obj.shape.hit(&(inter - obj.pos), &(spot.pos - *inter));
      if k > 0. && k < 1. {
        return true;
      }
    }

    false
  }

  pub fn get_color(&self, obj: &Object, vector: &Point, dist: f64) -> Color {
    let (mut r, mut g, mut b) = (0., 0., 0.);

    let inter = self.eye + vector * dist;

    for spot in self.spots.iter() {
      if self.get_shadow(obj, spot, &inter) {
        continue;
      }

      let light = spot.pos - inter;
      let perp = obj.shape.perp(&inter);
      let cos_a = perp.normalize().scalar_product(&light.normalize());

      if cos_a <= 0. {
        continue;
      }

      r += (obj.color.r as f64) * cos_a * (1. - obj.shininess) + (spot.color.r as f64) * cos_a * obj.shininess;
      g += (obj.color.g as f64) * cos_a * (1. - obj.shininess) + (spot.color.g as f64) * cos_a * obj.shininess;
      b += (obj.color.b as f64) * cos_a * (1. - obj.shininess) + (spot.color.b as f64) * cos_a * obj.shininess;
    }

    Color {
      r: (min(r, 255.) as u8),
      g: (min(g, 255.) as u8),
      b: (min(b, 255.) as u8)
    }
  }
}
<commit_msg>Fix NaN problem<commit_after>use std::f64::INFINITY;
use std::cmp::min;

use shapes::Object;
use point::Point;
use color::{Color, Black};

pub struct Spot {
  pos: Point,
  color: Color,
}

pub struct Scene {
  eye: Point,
  spots: ~[Spot],
  objects: ~[Object]
}

impl Scene {
  pub fn get_closest<'a>(&'a self, vector: &'a Point) -> (Option<&'a Object>, f64) {
    let mut min: f64 = INFINITY;
    let mut closest: Option<&'a Object> = None;

    for obj in self.objects.iter() {
      let k = obj.shape.hit(&(self.eye - obj.pos), vector);
      if k > 0. && k < min {
        min = k;
        closest = Some(obj);
      }
    }

    return (closest, min);
  }

  fn get_shadow(&self, cur: &Object, light: &Point, inter: &Point) -> bool {
    for obj in self.objects.iter() {
      if obj as *Object == cur as *Object {
        continue;
      }

      let k = obj.shape.hit(&(inter - obj.pos), light);
      if k > 0. && k < 1. {
        return true;
      }
    }

    false
  }

  pub fn get_color(&self, obj: &Object, vector: &Point, dist: f64) -> Color {
    let (mut r, mut g, mut b) = (0., 0., 0.);

    let inter = self.eye + vector * dist;

    for spot in self.spots.iter() {
      let light = spot.pos - inter;

      if self.get_shadow(obj, &light, &inter) {
        continue;
      }

      let perp = obj.shape.perp(&inter);
      let cos_a = perp.normalize().scalar_product(&light.normalize());

      if cos_a <= 0. || cos_a.is_nan() {
        continue;
      }

      r += (obj.color.r as f64) * cos_a * (1. - obj.shininess) + (spot.color.r as f64) * cos_a * obj.shininess;
      g += (obj.color.g as f64) * cos_a * (1. - obj.shininess) + (spot.color.g as f64) * cos_a * obj.shininess;
      b += (obj.color.b as f64) * cos_a * (1. - obj.shininess) + (spot.color.b as f64) * cos_a * obj.shininess;
    }

    Color {
      r: (min(r, 255.) as u8),
      g: (min(g, 255.) as u8),
      b: (min(b, 255.) as u8)
    }
  }
}
<|endoftext|>


<commit_before>use std::io::{BufReader, BufWriter, BufRead, Write};
use std::fs::File;

use serde_json;

use vecmath::*;

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

use color;
use color::Color;

use std;

#[derive(Serialize, Deserialize)]
pub struct Scene {
    shapes: Vec<Shape>,
    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 from_file(filename: &str) -> Result<Scene, String> {
        let file_in = File::open(filename).map_err(|e| format!("Can't open input file: {}", e))?;
        let reader = BufReader::new(&file_in);

        serde_json::from_reader(reader).map_err(|e| format!("JSON Parse error: {}", e))?
    }

    pub fn add_shape(&mut self, s: Shape) {
        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_roty(self.camera_dir, x_rot);

        // project camera_dir to X plane
        let mut x_proj = self.camera_dir;
        x_proj[1] = 0.0;
        x_proj = vec3_normalized(x_proj);

        let angle = if x_proj[0] < 0.0 {
            -vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        } else {
            vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        };

        self.camera_dir = vec3_roty(self.camera_dir, -angle);
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, angle);

        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 color::BLACK;
        }

        if let Some(intersect) = self.closest_q(point, dir) {
            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_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 {
            color::BLACK
        }
    }

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

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let find_min_opt = |min, (idx, op_val)|
            match (min, op_val) {
                (Some((_, min_val)), Some(val)) if val < min_val => Some((idx, val)),
                (None, Some(val)) => Some((idx, val)),
                _ => min,
        };

        let closest = self.shapes
            .iter()
            .map(|x| x.intersect_dist(point, dir))
            .enumerate()
            .fold(None, find_min_opt);

        // get intersection point info
        if let Some((idx, _)) = closest {
            self.shapes[idx].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_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>Parse bugfix<commit_after>use std::io::{BufReader, BufWriter, BufRead, Write};
use std::fs::File;

use serde_json;

use vecmath::*;

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

use color;
use color::Color;

use std;

#[derive(Serialize, Deserialize)]
pub struct Scene {
    shapes: Vec<Shape>,
    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 from_file(filename: &str) -> Result<Scene, String> {
        let file_in = File::open(filename).map_err(|e| format!("Can't open input file: {}", e))?;
        let reader = BufReader::new(&file_in);

        let s: Scene = serde_json::from_reader(reader).map_err(|e| format!("JSON Parse error: {}", e))?;
        Ok(s)
    }

    pub fn add_shape(&mut self, s: Shape) {
        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_roty(self.camera_dir, x_rot);

        // project camera_dir to X plane
        let mut x_proj = self.camera_dir;
        x_proj[1] = 0.0;
        x_proj = vec3_normalized(x_proj);

        let angle = if x_proj[0] < 0.0 {
            -vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        } else {
            vec3_dot([0.0, 0.0, 1.0], x_proj).acos()
        };

        self.camera_dir = vec3_roty(self.camera_dir, -angle);
        self.camera_dir = vec3_rotx(self.camera_dir, y_rot);
        self.camera_dir = vec3_roty(self.camera_dir, angle);

        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 color::BLACK;
        }

        if let Some(intersect) = self.closest_q(point, dir) {
            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_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 {
            color::BLACK
        }
    }

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

    // Checks against all objects and returns closest intersection
    fn closest_q(&self, point: &Vec3d, dir: &Vec3d) -> Option<Intersection> {
        let find_min_opt = |min, (idx, op_val)|
            match (min, op_val) {
                (Some((_, min_val)), Some(val)) if val < min_val => Some((idx, val)),
                (None, Some(val)) => Some((idx, val)),
                _ => min,
        };

        let closest = self.shapes
            .iter()
            .map(|x| x.intersect_dist(point, dir))
            .enumerate()
            .fold(None, find_min_opt);

        // get intersection point info
        if let Some((idx, _)) = closest {
            self.shapes[idx].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_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>pub use self::keys::Keys;
pub use self::mouse::Mouse;
pub use self::window::Window;

/// Tracked state related to the focused window.
pub mod window {
    use geom;
    use window;
    use math::Vector2;

    /// State of the window in focus.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct Window {
        /// ID of the window currently in focus.
        pub id: Option<window::Id>,
        /// The width of the focused window agnostic of DPI.
        ///
        /// This is equal to the pixel width divided by the hidpi_factor.
        pub width: f64,
        /// The height of the focused window agnostic of DPI.
        ///
        /// This is equal to the pixel height divided by the hidpi_factor.
        pub height: f64,
        /// The high "dots-per-inch" multiplier that describes the density of the screens pixels.
        pub hidpi_factor: f64,
    }

    impl Window {
        /// Initialise the window state.
        pub fn new() -> Self {
            Window {
                id: None,
                width: 0.0,
                height: 0.0,
                hidpi_factor: 1.0,
            }
        }

        /// Get the range along the *x* axis occupied by the window.
        pub fn x_range(&self) -> geom::Range<f64> {
            let half_w = self.width * 0.5;
            geom::Range { start: -half_w, end: half_w }
        }

        /// Get the range along the *y* axis occupied by the window.
        pub fn y_range(&self) -> geom::Range<f64> {
            let half_h = self.height * 0.5;
            geom::Range { start: -half_h, end: half_h }
        }

        /// Get the x coordinate for the left edge of the window.
        pub fn rect(&self) -> geom::Rect<f64> {
            let x = self.x_range();
            let y = self.y_range();
            geom::Rect { x, y }
        }

        /// Return the `width` and `height` as a `Vector2`.
        pub fn size(&self) -> Vector2<f64> {
            Vector2 { x: self.width, y: self.height }
        }
    }
}

/// Tracked state related to the keyboard.
pub mod keys {
    use event::{Key, ModifiersState};
    use std::collections::HashSet;
    use std::ops::Deref;

    /// The state of the keyboard.
    #[derive(Clone, Debug, Default)]
    pub struct Keys {
        /// The state of the modifier keys as last indicated by winit.
        pub mods: ModifiersState,
        /// The state of all keys as tracked via the nannou App event handling.
        pub down: Down,
    }

    /// The set of keys that are currently pressed.
    #[derive(Clone, Debug, Default)]
    pub struct Down {
        pub(crate) keys: HashSet<Key>,
    }

    impl Deref for Down {
        type Target = HashSet<Key>;
        fn deref(&self) -> &Self::Target {
            &self.keys
        }
    }
}

/// Tracked state related to the mouse.
pub mod mouse {
    use math::Point2;
    use std;
    use window;

    #[doc(inline)]
    pub use event::MouseButton as Button;

    /// The max total number of buttons on a mouse.
    pub const NUM_BUTTONS: usize = 9;

    /// The state of the `Mouse` at a single moment in time.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct Mouse {
        /// The ID of the last window currently in focus.
        pub window: Option<window::Id>,
        /// *x* position relative to the middle of `window`.
        pub x: f64,
        /// *y* position relative to the middle of `window`.
        pub y: f64,
        /// A map describing the state of each mouse button.
        pub buttons: ButtonMap,
    }

    /// Whether the button is up or down.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub enum ButtonPosition {
        /// The button is up (i.e. pressed).
        Up,
        /// The button is down and was originally pressed down at the given `Point2`.
        Down(Point2<f64>),
    }

    /// Stores the state of all mouse buttons.
    ///
    /// If the mouse button is down, it stores the position of the mouse when the button was pressed
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct ButtonMap {
        buttons: [ButtonPosition; NUM_BUTTONS],
    }

    /// An iterator yielding all pressed buttons.
    #[derive(Clone)]
    pub struct PressedButtons<'a> {
        buttons: std::iter::Enumerate<std::slice::Iter<'a, ButtonPosition>>,
    }

    impl Mouse {
        /// Construct a new default `Mouse`.
        pub fn new() -> Self {
            Mouse {
                window: None,
                buttons: ButtonMap::new(),
                x: 0.0,
                y: 0.0,
            }
        }

        /// The position of the mouse relative to the middle of the window in focus..
        pub fn position(&self) -> Point2<f64> {
            Point2 { x: self.x, y: self.y }
        }
    }

    impl ButtonPosition {
        /// If the mouse button is down, return a new one with position relative to the given `xy`.
        pub fn relative_to(self, xy: Point2<f64>) -> Self {
            match self {
                ButtonPosition::Down(pos) => {
                    let rel_p = pos - xy;
                    ButtonPosition::Down(Point2 { x: rel_p.x, y: rel_p.y })
                }
                button_pos => button_pos,
            }
        }

        /// Is the `ButtonPosition` down.
        pub fn is_down(&self) -> bool {
            match *self {
                ButtonPosition::Down(_) => true,
                _ => false,
            }
        }

        /// Is the `ButtonPosition` up.
        pub fn is_up(&self) -> bool {
            match *self {
                ButtonPosition::Up => true,
                _ => false,
            }
        }

        /// Returns the position at which the button was pressed.
        pub fn if_down(&self) -> Option<Point2<f64>> {
            match *self {
                ButtonPosition::Down(xy) => Some((xy)),
                _ => None,
            }
        }
    }

    impl ButtonMap {
        /// Returns a new button map with all states set to `None`
        pub fn new() -> Self {
            ButtonMap { buttons: [ButtonPosition::Up; NUM_BUTTONS] }
        }

        /// Returns a copy of the ButtonMap relative to the given `Point`
        pub fn relative_to(self, xy: Point2<f64>) -> Self {
            self.buttons.iter().enumerate().fold(
                ButtonMap::new(),
                |mut map,
                 (idx, button_pos)| {
                    map.buttons[idx] = button_pos.relative_to(xy);
                    map
                },
            )
        }

        /// The state of the left mouse button.
        pub fn left(&self) -> &ButtonPosition {
            &self[Button::Left]
        }

        /// The state of the middle mouse button.
        pub fn middle(&self) -> &ButtonPosition {
            &self[Button::Middle]
        }

        /// The state of the right mouse button.
        pub fn right(&self) -> &ButtonPosition {
            &self[Button::Right]
        }

        /// Sets the `Button` in the `Down` position.
        pub fn press(&mut self, button: Button, xy: Point2<f64>) {
            self.buttons[button_to_idx(button)] = ButtonPosition::Down(xy);
        }

        /// Set's the `Button` in the `Up` position.
        pub fn release(&mut self, button: Button) {
            self.buttons[button_to_idx(button)] = ButtonPosition::Up;
        }

        /// An iterator yielding all pressed mouse buttons along with the location at which they
        /// were originally pressed.
        pub fn pressed(&self) -> PressedButtons {
            PressedButtons { buttons: self.buttons.iter().enumerate() }
        }
    }

    impl std::ops::Index<Button> for ButtonMap {
        type Output = ButtonPosition;
        fn index(&self, button: Button) -> &Self::Output {
            &self.buttons[button_to_idx(button)]
        }
    }

    impl<'a> Iterator for PressedButtons<'a> {
        type Item = (Button, Point2<f64>);
        fn next(&mut self) -> Option<Self::Item> {
            while let Some((idx, button_pos)) = self.buttons.next() {
                if let ButtonPosition::Down(xy) = *button_pos {
                    return Some((idx_to_button(idx), xy));
                }
            }
            None
        }
    }

    fn idx_to_button(i: usize) -> Button {
        match i {
            n @ 0...5 => Button::Other(n as u8),
            6 => Button::Left,
            7 => Button::Right,
            8 => Button::Middle,
            _ => Button::Other(std::u8::MAX),
        }
    }

    fn button_to_idx(button: Button) -> usize {
        match button {
            Button::Other(n) => n as usize,
            Button::Left => 6,
            Button::Right => 7,
            Button::Middle => 8,
        }
    }
}
<commit_msg>Add `state::Window::Id` method to simplify getting focused window id<commit_after>pub use self::keys::Keys;
pub use self::mouse::Mouse;
pub use self::window::Window;

/// Tracked state related to the focused window.
pub mod window {
    use geom;
    use window;
    use math::Vector2;

    /// State of the window in focus.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct Window {
        /// ID of the window currently in focus.
        pub id: Option<window::Id>,
        /// The width of the focused window agnostic of DPI.
        ///
        /// This is equal to the pixel width divided by the hidpi_factor.
        pub width: f64,
        /// The height of the focused window agnostic of DPI.
        ///
        /// This is equal to the pixel height divided by the hidpi_factor.
        pub height: f64,
        /// The high "dots-per-inch" multiplier that describes the density of the screens pixels.
        pub hidpi_factor: f64,
    }

    impl Window {
        /// Initialise the window state.
        pub fn new() -> Self {
            Window {
                id: None,
                width: 0.0,
                height: 0.0,
                hidpi_factor: 1.0,
            }
        }

        /// Get the range along the *x* axis occupied by the window.
        pub fn x_range(&self) -> geom::Range<f64> {
            let half_w = self.width * 0.5;
            geom::Range { start: -half_w, end: half_w }
        }

        /// Get the range along the *y* axis occupied by the window.
        pub fn y_range(&self) -> geom::Range<f64> {
            let half_h = self.height * 0.5;
            geom::Range { start: -half_h, end: half_h }
        }

        /// Get the x coordinate for the left edge of the window.
        pub fn rect(&self) -> geom::Rect<f64> {
            let x = self.x_range();
            let y = self.y_range();
            geom::Rect { x, y }
        }

        /// Expects that there will be a `window::Id` (the common case) and **panic!**s otherwise.
        pub fn id(&self) -> window::Id {
            self.id.unwrap()
        }

        /// Return the `width` and `height` as a `Vector2`.
        pub fn size(&self) -> Vector2<f64> {
            Vector2 { x: self.width, y: self.height }
        }
    }
}

/// Tracked state related to the keyboard.
pub mod keys {
    use event::{Key, ModifiersState};
    use std::collections::HashSet;
    use std::ops::Deref;

    /// The state of the keyboard.
    #[derive(Clone, Debug, Default)]
    pub struct Keys {
        /// The state of the modifier keys as last indicated by winit.
        pub mods: ModifiersState,
        /// The state of all keys as tracked via the nannou App event handling.
        pub down: Down,
    }

    /// The set of keys that are currently pressed.
    #[derive(Clone, Debug, Default)]
    pub struct Down {
        pub(crate) keys: HashSet<Key>,
    }

    impl Deref for Down {
        type Target = HashSet<Key>;
        fn deref(&self) -> &Self::Target {
            &self.keys
        }
    }
}

/// Tracked state related to the mouse.
pub mod mouse {
    use math::Point2;
    use std;
    use window;

    #[doc(inline)]
    pub use event::MouseButton as Button;

    /// The max total number of buttons on a mouse.
    pub const NUM_BUTTONS: usize = 9;

    /// The state of the `Mouse` at a single moment in time.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct Mouse {
        /// The ID of the last window currently in focus.
        pub window: Option<window::Id>,
        /// *x* position relative to the middle of `window`.
        pub x: f64,
        /// *y* position relative to the middle of `window`.
        pub y: f64,
        /// A map describing the state of each mouse button.
        pub buttons: ButtonMap,
    }

    /// Whether the button is up or down.
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub enum ButtonPosition {
        /// The button is up (i.e. pressed).
        Up,
        /// The button is down and was originally pressed down at the given `Point2`.
        Down(Point2<f64>),
    }

    /// Stores the state of all mouse buttons.
    ///
    /// If the mouse button is down, it stores the position of the mouse when the button was pressed
    #[derive(Copy, Clone, Debug, PartialEq)]
    pub struct ButtonMap {
        buttons: [ButtonPosition; NUM_BUTTONS],
    }

    /// An iterator yielding all pressed buttons.
    #[derive(Clone)]
    pub struct PressedButtons<'a> {
        buttons: std::iter::Enumerate<std::slice::Iter<'a, ButtonPosition>>,
    }

    impl Mouse {
        /// Construct a new default `Mouse`.
        pub fn new() -> Self {
            Mouse {
                window: None,
                buttons: ButtonMap::new(),
                x: 0.0,
                y: 0.0,
            }
        }

        /// The position of the mouse relative to the middle of the window in focus..
        pub fn position(&self) -> Point2<f64> {
            Point2 { x: self.x, y: self.y }
        }
    }

    impl ButtonPosition {
        /// If the mouse button is down, return a new one with position relative to the given `xy`.
        pub fn relative_to(self, xy: Point2<f64>) -> Self {
            match self {
                ButtonPosition::Down(pos) => {
                    let rel_p = pos - xy;
                    ButtonPosition::Down(Point2 { x: rel_p.x, y: rel_p.y })
                }
                button_pos => button_pos,
            }
        }

        /// Is the `ButtonPosition` down.
        pub fn is_down(&self) -> bool {
            match *self {
                ButtonPosition::Down(_) => true,
                _ => false,
            }
        }

        /// Is the `ButtonPosition` up.
        pub fn is_up(&self) -> bool {
            match *self {
                ButtonPosition::Up => true,
                _ => false,
            }
        }

        /// Returns the position at which the button was pressed.
        pub fn if_down(&self) -> Option<Point2<f64>> {
            match *self {
                ButtonPosition::Down(xy) => Some((xy)),
                _ => None,
            }
        }
    }

    impl ButtonMap {
        /// Returns a new button map with all states set to `None`
        pub fn new() -> Self {
            ButtonMap { buttons: [ButtonPosition::Up; NUM_BUTTONS] }
        }

        /// Returns a copy of the ButtonMap relative to the given `Point`
        pub fn relative_to(self, xy: Point2<f64>) -> Self {
            self.buttons.iter().enumerate().fold(
                ButtonMap::new(),
                |mut map,
                 (idx, button_pos)| {
                    map.buttons[idx] = button_pos.relative_to(xy);
                    map
                },
            )
        }

        /// The state of the left mouse button.
        pub fn left(&self) -> &ButtonPosition {
            &self[Button::Left]
        }

        /// The state of the middle mouse button.
        pub fn middle(&self) -> &ButtonPosition {
            &self[Button::Middle]
        }

        /// The state of the right mouse button.
        pub fn right(&self) -> &ButtonPosition {
            &self[Button::Right]
        }

        /// Sets the `Button` in the `Down` position.
        pub fn press(&mut self, button: Button, xy: Point2<f64>) {
            self.buttons[button_to_idx(button)] = ButtonPosition::Down(xy);
        }

        /// Set's the `Button` in the `Up` position.
        pub fn release(&mut self, button: Button) {
            self.buttons[button_to_idx(button)] = ButtonPosition::Up;
        }

        /// An iterator yielding all pressed mouse buttons along with the location at which they
        /// were originally pressed.
        pub fn pressed(&self) -> PressedButtons {
            PressedButtons { buttons: self.buttons.iter().enumerate() }
        }
    }

    impl std::ops::Index<Button> for ButtonMap {
        type Output = ButtonPosition;
        fn index(&self, button: Button) -> &Self::Output {
            &self.buttons[button_to_idx(button)]
        }
    }

    impl<'a> Iterator for PressedButtons<'a> {
        type Item = (Button, Point2<f64>);
        fn next(&mut self) -> Option<Self::Item> {
            while let Some((idx, button_pos)) = self.buttons.next() {
                if let ButtonPosition::Down(xy) = *button_pos {
                    return Some((idx_to_button(idx), xy));
                }
            }
            None
        }
    }

    fn idx_to_button(i: usize) -> Button {
        match i {
            n @ 0...5 => Button::Other(n as u8),
            6 => Button::Left,
            7 => Button::Right,
            8 => Button::Middle,
            _ => Button::Other(std::u8::MAX),
        }
    }

    fn button_to_idx(button: Button) -> usize {
        match button {
            Button::Other(n) => n as usize,
            Button::Left => 6,
            Button::Right => 7,
            Button::Middle => 8,
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "uu_tr"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 * (c) kwantam <kwantam@gmail.com>
 *     20150428 created `expand` module to eliminate most allocs during setup
 * (c) Sergey "Shnatsel" Davidoff <shnatsel@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate bit_set;
extern crate getopts;
extern crate fnv;

#[macro_use]
extern crate uucore;

use bit_set::BitSet;
use getopts::Options;
use std::io::{stdin, stdout, BufRead, BufWriter, Write};
use fnv::FnvHashMap;

use expand::ExpandSet;

mod expand;

static NAME: &'static str = "tr";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
const BUFFER_LEN: usize = 1024;

fn delete(set: ExpandSet, complement: bool) {
    let mut bset = BitSet::new();
    let stdin = stdin();
    let mut locked_stdin = stdin.lock();
    let mut buffered_stdout = BufWriter::new(stdout());
    let mut buf = String::with_capacity(BUFFER_LEN + 4);
    let mut char_output_buffer: [u8; 4] = [0;4];

    for c in set {
        bset.insert(c as usize);
    }

    let is_allowed = |c : char| {
        if complement {
            bset.contains(c as usize)
        } else {
            !bset.contains(c as usize)
        }
    };

    while let Ok(length) = locked_stdin.read_line(&mut buf) {
        if length == 0 { break }
        { // isolation to make borrow checker happy
            let filtered = buf.chars().filter(|c| is_allowed(*c));
            for c in filtered {
                let char_as_bytes = c.encode_utf8(&mut char_output_buffer);
                buffered_stdout.write_all(char_as_bytes.as_bytes()).unwrap();
            }
        }
        buf.clear();
    }
}

fn tr<'a>(set1: ExpandSet<'a>, mut set2: ExpandSet<'a>) {
    let mut map = FnvHashMap::default();
    let stdin = stdin();
    let mut locked_stdin = stdin.lock();
    let mut buffered_stdout = BufWriter::new(stdout());
    let mut buf = String::with_capacity(BUFFER_LEN + 4);
    let mut output_buf = String::with_capacity(BUFFER_LEN + 4);

    let mut s2_prev = '_';
    for i in set1 {
        s2_prev = set2.next().unwrap_or(s2_prev);

        map.insert(i as usize, s2_prev);
    }

    while let Ok(length) = locked_stdin.read_line(&mut buf) {
        if length == 0 { break }

        { // isolation to make borrow checker happy
            let output_stream = buf.chars().map(|c| *map.get(&(c as usize)).unwrap_or(&c));
            output_buf.extend(output_stream);
            buffered_stdout.write_all(output_buf.as_bytes()).unwrap();
        }

        buf.clear();
        output_buf.clear();
    }
}

fn usage(opts: &Options) {
    println!("{} {}", NAME, VERSION);
    println!("");
    println!("Usage:");
    println!("  {} [OPTIONS] SET1 [SET2]", NAME);
    println!("");
    println!("{}", opts.usage("Translate or delete characters."));
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = Options::new();

    opts.optflag("c", "complement", "use the complement of SET1");
    opts.optflag("C", "", "same as -c");
    opts.optflag("d", "delete", "delete characters in SET1");
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(err) => {
            show_error!("{}", err);
            return 1;
        }
    };

    if matches.opt_present("help") {
        usage(&opts);
        return 0;
    }

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.free.is_empty() {
        usage(&opts);
        return 1;
    }

    let dflag = matches.opt_present("d");
    let cflag = matches.opts_present(&["c".to_owned(), "C".to_owned()]);
    let sets = matches.free;

    if cflag && !dflag {
        show_error!("-c is only supported with -d");
        return 1;
    }

    if dflag {
        let set1 = ExpandSet::new(sets[0].as_ref());
        delete(set1, cflag);
    } else {
        let set1 = ExpandSet::new(sets[0].as_ref());
        let set2 = ExpandSet::new(sets[1].as_ref());
        tr(set1, set2);
    }

    0
}
<commit_msg>tr: generaze translation<commit_after>#![crate_name = "uu_tr"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 * (c) kwantam <kwantam@gmail.com>
 *     20150428 created `expand` module to eliminate most allocs during setup
 * (c) Sergey "Shnatsel" Davidoff <shnatsel@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate bit_set;
extern crate getopts;
extern crate fnv;

#[macro_use]
extern crate uucore;

use bit_set::BitSet;
use getopts::Options;
use std::io::{stdin, stdout, BufRead, BufWriter, Write};
use fnv::FnvHashMap;

use expand::ExpandSet;

mod expand;

static NAME: &'static str = "tr";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
const BUFFER_LEN: usize = 1024;

trait SymbolTranslator {
    fn translate(&self, c: &char, prev_c: &char) -> Option<char>;
}

struct DeleteOperation {
    bset: BitSet,
    complement: bool,
}

impl DeleteOperation {
    fn new(set: ExpandSet, complement: bool) -> DeleteOperation {
        DeleteOperation {
            bset: set.map(|c| c as usize).collect(),
            complement: complement
        }
    }
}

impl SymbolTranslator for DeleteOperation {
    fn translate(&self, c: &char, _prev_c: &char) -> Option<char> {
        let uc = *c as usize;
        if self.complement == self.bset.contains(uc) {
            Some(*c)
        } else {
            None
        }
    }
}

struct TranslateOperation {
    translate_map: FnvHashMap<usize, char>,
}

impl TranslateOperation {
    fn new(set1: ExpandSet, set2: &mut ExpandSet) -> TranslateOperation {
        let mut map = FnvHashMap::default();
        let mut s2_prev = '_';
        for i in set1 {
            s2_prev = set2.next().unwrap_or(s2_prev);

            map.insert(i as usize, s2_prev);
        }
        TranslateOperation {
            translate_map: map,
        }
    }
}

impl SymbolTranslator for TranslateOperation {
    fn translate(&self, c: &char, _prev_c: &char) -> Option<char> {
        Some(*self.translate_map.get(&(*c as usize)).unwrap_or(c))
    }
}

fn translate_input<T: SymbolTranslator>(input: &mut BufRead, output: &mut Write, translator: T) {
    let mut buf = String::with_capacity(BUFFER_LEN + 4);
    let mut output_buf = String::with_capacity(BUFFER_LEN + 4);
    // let mut char_output_buffer: [u8; 4] = [0;4];

    while let Ok(length) = input.read_line(&mut buf) {
        let mut prev_c = 0 as char;
        if length == 0 { break }
        { // isolation to make borrow checker happy
            let filtered = buf.chars().filter_map(|c| {
                let res = translator.translate(&c, &prev_c);
                if res.is_some() {
                    prev_c = c;
                }
                res
            });

            output_buf.extend(filtered);
            output.write_all(output_buf.as_bytes()).unwrap();
        }
        buf.clear();
        output_buf.clear();
    }
}

fn usage(opts: &Options) {
    println!("{} {}", NAME, VERSION);
    println!("");
    println!("Usage:");
    println!("  {} [OPTIONS] SET1 [SET2]", NAME);
    println!("");
    println!("{}", opts.usage("Translate or delete characters."));
}

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = Options::new();

    opts.optflag("c", "complement", "use the complement of SET1");
    opts.optflag("C", "", "same as -c");
    opts.optflag("d", "delete", "delete characters in SET1");
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("s", "squeeze", "");
    opts.optflag("V", "version", "output version information and exit");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(err) => {
            show_error!("{}", err);
            return 1;
        }
    };

    if matches.opt_present("help") {
        usage(&opts);
        return 0;
    }

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return 0;
    }

    if matches.free.is_empty() {
        usage(&opts);
        return 1;
    }

    let dflag = matches.opt_present("d");
    let cflag = matches.opts_present(&["c".to_owned(), "C".to_owned()]);
    let sets = matches.free;

    if cflag && !dflag {
        show_error!("-c is only supported with -d");
        return 1;
    }

    let stdin = stdin();
    let mut locked_stdin = stdin.lock();
    let stdout = stdout();
    let locked_stdout = stdout.lock();
    let mut buffered_stdout = BufWriter::new(locked_stdout);

    if dflag {
        let set1 = ExpandSet::new(sets[0].as_ref());
        let delete_op = DeleteOperation::new(set1, cflag);
        translate_input(&mut locked_stdin, &mut buffered_stdout, delete_op);
    } else {
        let set1 = ExpandSet::new(sets[0].as_ref());
        let mut set2 = ExpandSet::new(sets[1].as_ref());
        let op = TranslateOperation::new(set1, &mut set2);
        translate_input(&mut locked_stdin, &mut buffered_stdout, op)
    }

    0
}
<|endoftext|>


<commit_before>//! Basic types and their methods for linear algebra

use ndarray::LinalgScalar;
use num_complex::Complex;
use num_traits::*;
use rand::Rng;
use rand::distributions::*;
use std::fmt::Debug;
use std::iter::Sum;

use super::lapack_traits::LapackScalar;

pub use num_complex::Complex32 as c32;
pub use num_complex::Complex64 as c64;

/// General Scalar trait. This generalizes complex and real number.
///
/// You can use the following operations with `A: Scalar`:
///
/// - [abs](trait.Absolute.html#method.abs)
/// - [squared](trait.Absolute.html#tymethod.squared)
/// - [sqrt](trait.SquareRoot.html#tymethod.sqrt)
/// - [exp](trait.Exponential.html#tymethod.exp)
/// - [conj](trait.Conjugate.html#tymethod.conj)
/// - [randn](trait.RandNormal.html#tymethod.randn)
///
pub trait Scalar
    : LapackScalar
    + LinalgScalar
    + AssociatedReal
    + AssociatedComplex
    + Absolute
    + SquareRoot
    + Exponential
    + Conjugate
    + RandNormal
    + Debug {
    fn from_f64(f64) -> Self;
}

impl Scalar for f32 {
    fn from_f64(f: f64) -> Self {
        f as f32
    }
}

impl Scalar for f64 {
    fn from_f64(f: f64) -> Self {
        f
    }
}

impl Scalar for c32 {
    fn from_f64(f: f64) -> Self {
        Self::new(f as f32, 0.0)
    }
}

impl Scalar for c64 {
    fn from_f64(f: f64) -> Self {
        Self::new(f, 0.0)
    }
}

pub trait RealScalar: Scalar + Float + Sum {}
impl RealScalar for f32 {}
impl RealScalar for f64 {}

/// Convert `f64` into `Scalar`
///
/// ```rust
/// use ndarray_linalg::*;
/// fn mult<A: Scalar>(a: A) -> A {
///     // a * 2.0  // Error!
///     a * into_scalar(2.0)
/// }
/// ```
pub fn into_scalar<T: Scalar>(f: f64) -> T {
    T::from_f64(f)
}

/// Define associating real float type
pub trait AssociatedReal: Sized {
    type Real: RealScalar;
    fn inject(Self::Real) -> Self;
    fn add_real(self, Self::Real) -> Self;
    fn sub_real(self, Self::Real) -> Self;
    fn mul_real(self, Self::Real) -> Self;
    fn div_real(self, Self::Real) -> Self;
}

/// Define associating complex type
pub trait AssociatedComplex: Sized {
    type Complex;
    fn inject(Self) -> Self::Complex;
    fn add_complex(self, Self::Complex) -> Self::Complex;
    fn sub_complex(self, Self::Complex) -> Self::Complex;
    fn mul_complex(self, Self::Complex) -> Self::Complex;
}

/// Define `abs()` more generally
pub trait Absolute: AssociatedReal {
    fn squared(&self) -> Self::Real;
    fn abs(&self) -> Self::Real {
        self.squared().sqrt()
    }
}

/// Define `sqrt()` more generally
pub trait SquareRoot {
    fn sqrt(&self) -> Self;
}

/// Define `exp()` more generally
pub trait Exponential {
    fn exp(&self) -> Self;
}

/// Complex conjugate value
pub trait Conjugate: Copy {
    fn conj(self) -> Self;
}

/// Scalars which can be initialized from Gaussian random number
pub trait RandNormal {
    fn randn<R: Rng>(&mut R) -> Self;
}

macro_rules! impl_traits {
    ($real:ty, $complex:ty) => {

impl AssociatedReal for $real {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { r }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedReal for $complex {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { Self::new(r, 0.0) }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedComplex for $real {
    type Complex = $complex;
    fn inject(r: Self) -> Self::Complex { Self::Complex::new(r, 0.0) }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl AssociatedComplex for $complex {
    type Complex = $complex;
    fn inject(c: Self) -> Self::Complex { c }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl Absolute for $real {
    fn squared(&self) -> Self::Real {
        *self * *self
    }
    fn abs(&self) -> Self::Real{
        Float::abs(*self)
    }
}

impl Absolute for $complex {
    fn squared(&self) -> Self::Real {
        self.norm_sqr()
    }
    fn abs(&self) -> Self::Real {
        self.norm()
    }
}

impl SquareRoot for $real {
    fn sqrt(&self) -> Self {
        Float::sqrt(*self)
    }
}

impl SquareRoot for $complex {
    fn sqrt(&self) -> Self {
        Complex::sqrt(self)
    }
}

impl Exponential for $real {
    fn exp(&self) -> Self {
        Float::exp(*self)
    }
}

impl Exponential for $complex {
    fn exp(&self) -> Self {
        Complex::exp(self)
    }
}

impl Conjugate for $real {
    fn conj(self) -> Self {
        self
    }
}

impl Conjugate for $complex {
    fn conj(self) -> Self {
        Complex::conj(&self)
    }
}

impl RandNormal for $real {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        dist.ind_sample(rng) as $real
    }
}

impl RandNormal for $complex {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        let re = dist.ind_sample(rng) as $real;
        let im = dist.ind_sample(rng) as $real;
        Self::new(re, im)
    }
}

}} // impl_traits!

impl_traits!(f64, c64);
impl_traits!(f32, c32);
<commit_msg>Add Neg for Scalar<commit_after>//! Basic types and their methods for linear algebra

use ndarray::LinalgScalar;
use num_complex::Complex;
use num_traits::*;
use rand::Rng;
use rand::distributions::*;
use std::fmt::Debug;
use std::iter::Sum;
use std::ops::Neg;

use super::lapack_traits::LapackScalar;

pub use num_complex::Complex32 as c32;
pub use num_complex::Complex64 as c64;

/// General Scalar trait. This generalizes complex and real number.
///
/// You can use the following operations with `A: Scalar`:
///
/// - [abs](trait.Absolute.html#method.abs)
/// - [squared](trait.Absolute.html#tymethod.squared)
/// - [sqrt](trait.SquareRoot.html#tymethod.sqrt)
/// - [exp](trait.Exponential.html#tymethod.exp)
/// - [conj](trait.Conjugate.html#tymethod.conj)
/// - [randn](trait.RandNormal.html#tymethod.randn)
///
pub trait Scalar
    : LapackScalar
    + LinalgScalar
    + AssociatedReal
    + AssociatedComplex
    + Absolute
    + SquareRoot
    + Exponential
    + Conjugate
    + RandNormal
    + Neg<Output = Self>
    + Debug {
    fn from_f64(f64) -> Self;
}

impl Scalar for f32 {
    fn from_f64(f: f64) -> Self {
        f as f32
    }
}

impl Scalar for f64 {
    fn from_f64(f: f64) -> Self {
        f
    }
}

impl Scalar for c32 {
    fn from_f64(f: f64) -> Self {
        Self::new(f as f32, 0.0)
    }
}

impl Scalar for c64 {
    fn from_f64(f: f64) -> Self {
        Self::new(f, 0.0)
    }
}

pub trait RealScalar: Scalar + Float + Sum {}
impl RealScalar for f32 {}
impl RealScalar for f64 {}

/// Convert `f64` into `Scalar`
///
/// ```rust
/// use ndarray_linalg::*;
/// fn mult<A: Scalar>(a: A) -> A {
///     // a * 2.0  // Error!
///     a * into_scalar(2.0)
/// }
/// ```
pub fn into_scalar<T: Scalar>(f: f64) -> T {
    T::from_f64(f)
}

/// Define associating real float type
pub trait AssociatedReal: Sized {
    type Real: RealScalar;
    fn inject(Self::Real) -> Self;
    fn add_real(self, Self::Real) -> Self;
    fn sub_real(self, Self::Real) -> Self;
    fn mul_real(self, Self::Real) -> Self;
    fn div_real(self, Self::Real) -> Self;
}

/// Define associating complex type
pub trait AssociatedComplex: Sized {
    type Complex;
    fn inject(Self) -> Self::Complex;
    fn add_complex(self, Self::Complex) -> Self::Complex;
    fn sub_complex(self, Self::Complex) -> Self::Complex;
    fn mul_complex(self, Self::Complex) -> Self::Complex;
}

/// Define `abs()` more generally
pub trait Absolute: AssociatedReal {
    fn squared(&self) -> Self::Real;
    fn abs(&self) -> Self::Real {
        self.squared().sqrt()
    }
}

/// Define `sqrt()` more generally
pub trait SquareRoot {
    fn sqrt(&self) -> Self;
}

/// Define `exp()` more generally
pub trait Exponential {
    fn exp(&self) -> Self;
}

/// Complex conjugate value
pub trait Conjugate: Copy {
    fn conj(self) -> Self;
}

/// Scalars which can be initialized from Gaussian random number
pub trait RandNormal {
    fn randn<R: Rng>(&mut R) -> Self;
}

macro_rules! impl_traits {
    ($real:ty, $complex:ty) => {

impl AssociatedReal for $real {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { r }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedReal for $complex {
    type Real = $real;
    fn inject(r: Self::Real) -> Self { Self::new(r, 0.0) }
    fn add_real(self, r: Self::Real) -> Self { self + r }
    fn sub_real(self, r: Self::Real) -> Self { self - r }
    fn mul_real(self, r: Self::Real) -> Self { self * r }
    fn div_real(self, r: Self::Real) -> Self { self / r }
}

impl AssociatedComplex for $real {
    type Complex = $complex;
    fn inject(r: Self) -> Self::Complex { Self::Complex::new(r, 0.0) }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl AssociatedComplex for $complex {
    type Complex = $complex;
    fn inject(c: Self) -> Self::Complex { c }
    fn add_complex(self, c: Self::Complex) -> Self::Complex { self + c }
    fn sub_complex(self, c: Self::Complex) -> Self::Complex { self - c }
    fn mul_complex(self, c: Self::Complex) -> Self::Complex { self * c }
}

impl Absolute for $real {
    fn squared(&self) -> Self::Real {
        *self * *self
    }
    fn abs(&self) -> Self::Real{
        Float::abs(*self)
    }
}

impl Absolute for $complex {
    fn squared(&self) -> Self::Real {
        self.norm_sqr()
    }
    fn abs(&self) -> Self::Real {
        self.norm()
    }
}

impl SquareRoot for $real {
    fn sqrt(&self) -> Self {
        Float::sqrt(*self)
    }
}

impl SquareRoot for $complex {
    fn sqrt(&self) -> Self {
        Complex::sqrt(self)
    }
}

impl Exponential for $real {
    fn exp(&self) -> Self {
        Float::exp(*self)
    }
}

impl Exponential for $complex {
    fn exp(&self) -> Self {
        Complex::exp(self)
    }
}

impl Conjugate for $real {
    fn conj(self) -> Self {
        self
    }
}

impl Conjugate for $complex {
    fn conj(self) -> Self {
        Complex::conj(&self)
    }
}

impl RandNormal for $real {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        dist.ind_sample(rng) as $real
    }
}

impl RandNormal for $complex {
    fn randn<R: Rng>(rng: &mut R) -> Self {
        let dist = Normal::new(0., 1.);
        let re = dist.ind_sample(rng) as $real;
        let im = dist.ind_sample(rng) as $real;
        Self::new(re, im)
    }
}

}} // impl_traits!

impl_traits!(f64, c64);
impl_traits!(f32, c32);
<|endoftext|>


<commit_before>extern mod extra;

use extra::json;
use extra::json::Json;
use extra::uuid::Uuid;
use std::rt::io::Decorator;
use std::rt::io::extensions::{WriterByteConversions, ReaderByteConversions};
use std::rt::io::mem::{MemWriter, MemReader};
use std::str;

pub type Oid = i32;

// Values from pg_type.h
static BOOLOID: Oid = 16;
static BYTEAOID: Oid = 17;
static INT8OID: Oid = 20;
static INT2OID: Oid = 21;
static INT4OID: Oid = 23;
static TEXTOID: Oid = 25;
static JSONOID: Oid = 114;
static FLOAT4OID: Oid = 700;
static FLOAT8OID: Oid = 701;
static VARCHAROID: Oid = 1043;
static UUIDOID: Oid = 2950;

pub enum Format {
    Text = 0,
    Binary = 1
}

pub fn result_format(ty: Oid) -> Format {
    match ty {
        BOOLOID |
        BYTEAOID |
        INT8OID |
        INT2OID |
        INT4OID |
        FLOAT4OID |
        FLOAT8OID |
        UUIDOID => Binary,
        _ => Text
    }
}

macro_rules! check_oid(
    ($($expected:ident)|+, $actual:ident) => (
        match $actual {
            $($expected)|+ => (),
            actual => fail!("Invalid Oid %?", actual)
        }
    )
)

pub trait FromSql {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Self;
}

macro_rules! from_conversions_impl(
    ($oid:ident, $t:ty, $f:ident) => (
        impl FromSql for Option<$t> {
            fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<$t> {
                check_oid!($oid, ty)
                do raw.map |buf| {
                    // TODO change to BufReader when implemented
                    let mut reader = MemReader::new(buf.to_owned());
                    reader.$f()
                }
            }
        }
    )
)

macro_rules! from_option_impl(
    ($t:ty) => (
        impl FromSql for $t {
            fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> $t {
                // FIXME when you can specify Self types properly
                let ret: Option<$t> = FromSql::from_sql(ty, raw);
                ret.unwrap()
            }
        }
    )
)

impl FromSql for Option<bool> {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<bool> {
        check_oid!(BOOLOID, ty)
        do raw.map |buf| {
            buf[0] != 0
        }
    }
}
from_option_impl!(bool)

from_conversions_impl!(INT2OID, i16, read_be_i16_)
from_option_impl!(i16)
from_conversions_impl!(INT4OID, i32, read_be_i32_)
from_option_impl!(i32)
from_conversions_impl!(INT8OID, i64, read_be_i64_)
from_option_impl!(i64)
from_conversions_impl!(FLOAT4OID, f32, read_be_f32_)
from_option_impl!(f32)
from_conversions_impl!(FLOAT8OID, f64, read_be_f64_)
from_option_impl!(f64)

impl FromSql for Option<~str> {
    fn from_sql(ty:Oid, raw: &Option<~[u8]>) -> Option<~str> {
        check_oid!(VARCHAROID | TEXTOID, ty)
        do raw.map |buf| {
            str::from_bytes(buf.as_slice())
        }
    }
}
from_option_impl!(~str)

impl FromSql for Option<~[u8]> {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<~[u8]> {
        check_oid!(BYTEAOID, ty)
        raw.clone()
    }
}
from_option_impl!(~[u8])

impl FromSql for Option<Json> {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<Json> {
        check_oid!(JSONOID, ty)
        do raw.map |buf| {
            json::from_str(str::from_bytes_slice(buf.as_slice())).unwrap()
        }
    }
}
from_option_impl!(Json)

impl FromSql for Option<Uuid> {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<Uuid> {
        check_oid!(UUIDOID, ty)
        do raw.map |buf| {
            Uuid::from_bytes(buf.as_slice()).unwrap()
        }
    }
}
from_option_impl!(Uuid)

pub trait ToSql {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>);
}

macro_rules! to_option_impl(
    ($($oid:ident)|+, $t:ty) => (
        impl ToSql for Option<$t> {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                match *self {
                    None => (Text, None),
                    Some(ref val) => val.to_sql(ty)
                }
            }
        }
    );
    (self, $($oid:ident)|+, $t:ty) => (
        impl<'self> ToSql for Option<$t> {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                match *self {
                    None => (Text, None),
                    Some(ref val) => val.to_sql(ty)
                }
            }
        }
    )
)

macro_rules! to_conversions_impl(
    ($($oid:ident)|+, $t:ty, $f:ident) => (
        impl ToSql for $t {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                let mut writer = MemWriter::new();
                writer.$f(*self);
                (Binary, Some(writer.inner()))
            }
        }
    )
)

impl ToSql for bool {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(BOOLOID, ty)
        (Binary, Some(~[*self as u8]))
    }
}
to_option_impl!(BOOLOID, bool)

to_conversions_impl!(INT2OID, i16, write_be_i16_)
to_option_impl!(INT2OID, i16)
to_conversions_impl!(INT4OID, i32, write_be_i32_)
to_option_impl!(INT4OID, i32)
to_conversions_impl!(INT8OID, i64, write_be_i64_)
to_option_impl!(INT8OID, i64)
to_conversions_impl!(FLOAT4OID, f32, write_be_f32_)
to_option_impl!(FLOAT4OID, f32)
to_conversions_impl!(FLOAT8OID, f64, write_be_f64_)
to_option_impl!(FLOAT8OID, f64)

impl<'self> ToSql for &'self str {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(VARCHAROID | TEXTOID, ty)
        (Text, Some(self.as_bytes().to_owned()))
    }
}

to_option_impl!(VARCHAROID | TEXTOID, ~str)
to_option_impl!(self, VARCHAROID | TEXTOID, &'self str)

impl<'self> ToSql for &'self [u8] {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(BYTEAOID, ty)
        (Binary, Some(self.to_owned()))
    }
}

to_option_impl!(BYTEAOID, ~[u8])
to_option_impl!(self, BYTEAOID, &'self [u8])

impl ToSql for Json {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(JSONOID, ty)
        (Text, Some(self.to_str().into_bytes()))
    }
}

to_option_impl!(JSONOID, Json)

impl ToSql for Uuid {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(UUIDOID, ty)
        (Binary, Some(self.to_bytes().to_owned()))
    }
}

to_option_impl!(UUIDOID, Uuid)
<commit_msg>Cleanup types.rs<commit_after>extern mod extra;

use extra::json;
use extra::json::Json;
use extra::uuid::Uuid;
use std::rt::io::Decorator;
use std::rt::io::extensions::{WriterByteConversions, ReaderByteConversions};
use std::rt::io::mem::{MemWriter, MemReader};
use std::str;

pub type Oid = i32;

// Values from pg_type.h
static BOOLOID: Oid = 16;
static BYTEAOID: Oid = 17;
static INT8OID: Oid = 20;
static INT2OID: Oid = 21;
static INT4OID: Oid = 23;
static TEXTOID: Oid = 25;
static JSONOID: Oid = 114;
static FLOAT4OID: Oid = 700;
static FLOAT8OID: Oid = 701;
static VARCHAROID: Oid = 1043;
static UUIDOID: Oid = 2950;

pub enum Format {
    Text = 0,
    Binary = 1
}

pub fn result_format(ty: Oid) -> Format {
    match ty {
        BOOLOID |
        BYTEAOID |
        INT8OID |
        INT2OID |
        INT4OID |
        FLOAT4OID |
        FLOAT8OID |
        UUIDOID => Binary,
        _ => Text
    }
}

macro_rules! check_oid(
    ($($expected:ident)|+, $actual:ident) => (
        match $actual {
            $($expected)|+ => (),
            actual => fail!("Invalid Oid %?", actual)
        }
    )
)

pub trait FromSql {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Self;
}

macro_rules! from_map_impl(
    ($($oid:ident)|+, $t:ty, $blk:expr) => (
        impl FromSql for Option<$t> {
            fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<$t> {
                check_oid!($($oid)|+, ty)
                raw.map($blk)
            }
        }
    )
)

macro_rules! from_conversions_impl(
    ($oid:ident, $t:ty, $f:ident) => (
        from_map_impl!($oid, $t, |buf| {
            // TODO change to BufReader when implemented
            let mut reader = MemReader::new(buf.to_owned());
            reader.$f()
        })
    )
)

macro_rules! from_option_impl(
    ($t:ty) => (
        impl FromSql for $t {
            fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> $t {
                // FIXME when you can specify Self types properly
                let ret: Option<$t> = FromSql::from_sql(ty, raw);
                ret.unwrap()
            }
        }
    )
)

from_map_impl!(BOOLOID, bool, |buf| { buf[0] != 0 })
from_option_impl!(bool)

from_conversions_impl!(INT2OID, i16, read_be_i16_)
from_option_impl!(i16)
from_conversions_impl!(INT4OID, i32, read_be_i32_)
from_option_impl!(i32)
from_conversions_impl!(INT8OID, i64, read_be_i64_)
from_option_impl!(i64)
from_conversions_impl!(FLOAT4OID, f32, read_be_f32_)
from_option_impl!(f32)
from_conversions_impl!(FLOAT8OID, f64, read_be_f64_)
from_option_impl!(f64)

from_map_impl!(VARCHAROID | TEXTOID, ~str, |buf| {
    str::from_bytes(buf.as_slice())
})
from_option_impl!(~str)

impl FromSql for Option<~[u8]> {
    fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<~[u8]> {
        check_oid!(BYTEAOID, ty)
        raw.clone()
    }
}
from_option_impl!(~[u8])

from_map_impl!(JSONOID, Json, |buf| {
    json::from_str(str::from_bytes_slice(buf.as_slice())).unwrap()
})
from_option_impl!(Json)

from_map_impl!(UUIDOID, Uuid, |buf| {
    Uuid::from_bytes(buf.as_slice()).unwrap()
})
from_option_impl!(Uuid)

pub trait ToSql {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>);
}

macro_rules! to_option_impl(
    ($($oid:ident)|+, $t:ty) => (
        impl ToSql for Option<$t> {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                match *self {
                    None => (Text, None),
                    Some(ref val) => val.to_sql(ty)
                }
            }
        }
    );
    (self, $($oid:ident)|+, $t:ty) => (
        impl<'self> ToSql for Option<$t> {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                match *self {
                    None => (Text, None),
                    Some(ref val) => val.to_sql(ty)
                }
            }
        }
    )
)

macro_rules! to_conversions_impl(
    ($($oid:ident)|+, $t:ty, $f:ident) => (
        impl ToSql for $t {
            fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
                check_oid!($($oid)|+, ty)

                let mut writer = MemWriter::new();
                writer.$f(*self);
                (Binary, Some(writer.inner()))
            }
        }
    )
)

impl ToSql for bool {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(BOOLOID, ty)
        (Binary, Some(~[*self as u8]))
    }
}
to_option_impl!(BOOLOID, bool)

to_conversions_impl!(INT2OID, i16, write_be_i16_)
to_option_impl!(INT2OID, i16)
to_conversions_impl!(INT4OID, i32, write_be_i32_)
to_option_impl!(INT4OID, i32)
to_conversions_impl!(INT8OID, i64, write_be_i64_)
to_option_impl!(INT8OID, i64)
to_conversions_impl!(FLOAT4OID, f32, write_be_f32_)
to_option_impl!(FLOAT4OID, f32)
to_conversions_impl!(FLOAT8OID, f64, write_be_f64_)
to_option_impl!(FLOAT8OID, f64)

impl<'self> ToSql for &'self str {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(VARCHAROID | TEXTOID, ty)
        (Text, Some(self.as_bytes().to_owned()))
    }
}

to_option_impl!(VARCHAROID | TEXTOID, ~str)
to_option_impl!(self, VARCHAROID | TEXTOID, &'self str)

impl<'self> ToSql for &'self [u8] {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(BYTEAOID, ty)
        (Binary, Some(self.to_owned()))
    }
}

to_option_impl!(BYTEAOID, ~[u8])
to_option_impl!(self, BYTEAOID, &'self [u8])

impl ToSql for Json {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(JSONOID, ty)
        (Text, Some(self.to_str().into_bytes()))
    }
}

to_option_impl!(JSONOID, Json)

impl ToSql for Uuid {
    fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
        check_oid!(UUIDOID, ty)
        (Binary, Some(self.to_bytes().to_owned()))
    }
}

to_option_impl!(UUIDOID, Uuid)
<|endoftext|>


<commit_before>use iso8601;
use xml::escape::escape_str_pcdata;

use std::borrow::Cow;

/// Escape a string for use as XML characters.
///
/// The resulting string is *not* suitable for use in XML attributes, but XML-RPC doesn't use those.
pub fn escape_xml(s: &str) -> Cow<str> {
    escape_str_pcdata(s)
}

pub fn format_datetime(date_time: &iso8601::DateTime) -> String {
    let iso8601::Time { hour, minute, second, .. } = date_time.time;

    match date_time.date {
        iso8601::Date::YMD { year, month, day } => {
            format!("{:04}{:02}{:02}T{:02}:{:02}:{:02}",
                year, month, day,
                hour, minute, second
            )
        }
        _ => { unimplemented!() }
    }
}

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

    #[test]
    fn formats_datetimes() {
        let date_time = iso8601::datetime("2016-05-02T06:01:05-0800").unwrap();

        assert_eq!(format_datetime(&date_time), "20160502T06:01:05");
    }
}
<commit_msg>Actually print the time zone<commit_after>use iso8601::{Date, Time, DateTime};
use xml::escape::escape_str_pcdata;

use std::borrow::Cow;

/// Escape a string for use as XML characters.
///
/// The resulting string is *not* suitable for use in XML attributes, but XML-RPC doesn't use those.
pub fn escape_xml(s: &str) -> Cow<str> {
    escape_str_pcdata(s)
}

pub fn format_datetime(date_time: &DateTime) -> String {
    let Time {
        hour, minute, second, millisecond, tz_offset_hours, tz_offset_minutes
    } = date_time.time;

    match date_time.date {
        Date::YMD { year, month, day } => {
            format!("{:04}{:02}{:02}T{:02}:{:02}:{:02}.{:.3}{:+03}:{:02}",
                year, month, day,
                hour, minute, second, millisecond,
                tz_offset_hours, tz_offset_minutes.abs()
            )
        }
        Date::Week { year, ww, d } => {
            format!("{:04}-W{:02}-{}", year, ww, d)
        }
        Date::Ordinal { year, ddd } => {
            format!("{:04}-{:03}", year, ddd)
        }
    }
}

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

    #[test]
    fn formats_datetimes() {
        let date_time = iso8601::datetime("2016-05-02T06:01:05-0830").unwrap();

        let formatted = format_datetime(&date_time);
        assert_eq!(formatted, "20160502T06:01:05.0-08:30");
        assert_eq!(iso8601::datetime(&formatted).unwrap(), date_time);
    }
}
<|endoftext|>


<commit_before>use std::str::FromStr;
use xml::{Element};
use xml::Xml::{ElementNode, CharacterNode};

pub fn parse_string_to_vector<T: FromStr>(string: &str) -> Vec<T> {
    string.trim()
        .split(" ")
        .map(|s| s.parse().ok().expect("Error parsing array in COLLADA file"))
        .collect()
}

pub fn get_array_content<T: FromStr>(element: &Element) -> Option<Vec<T>> {
    match element.children[0] {
        CharacterNode(ref contents) => Some(parse_string_to_vector(contents)),
        _ => None,
    }
}

pub fn has_attribute_with_value(e: &Element, name: &str, value: &str) -> bool {
    if let Some(s) = e.get_attribute(name, None) {
        s == value
    } else {
        false
    }
}

pub fn to_matrix_array(float_array: Vec<f32>) -> Vec<[[f32; 4]; 4]> {
    float_array.chunks(16).map(|chunk| {
        let mut matrix = [[0f32; 4]; 4];
        for (&chunk_value, matrix_value) in chunk.iter().zip(matrix.iter_mut().flat_map(|n| n.iter_mut())) {
            *matrix_value = chunk_value;
        }
        matrix
    }).collect()
}

///
/// Returns an iterator over all ElementNodes in an XML Element subtree with the given root,
/// using a pre-order tree traversal (root before children)
///
pub fn pre_order_iter<'a>(root: &'a Element) -> PreOrderIterator<'a> {
    PreOrderIterator { stack: vec![root] }
}

///
/// Returns an iterator over all ElementNodes in an XML Element subtree with the given root,
/// with their depth relative to the subtree root,
/// using a pre-order tree traversal (root before children)
///
pub fn pre_order_with_depth_iter<'a>(root: &'a Element) -> PreOrderWithDepthIterator<'a> {
    PreOrderWithDepthIterator { stack: vec![(root, 0)] }
}

pub struct PreOrderIterator<'a> {
    stack: Vec<&'a Element>
}

impl<'a> Iterator for PreOrderIterator<'a> {
    type Item = &'a Element;
    fn next(&mut self) -> Option<&'a Element> {
        let current_element = self.stack.pop();
        match current_element {
            Some(element) => {
                for child in element.children.iter().rev() {
                    if let ElementNode(ref e) = *child {
                        self.stack.push(e);
                    }
                }
            }
            None => ()
        }
        current_element
    }
}

pub struct PreOrderWithDepthIterator<'a> {
    stack: Vec<(&'a Element, usize)>
}

impl<'a> Iterator for PreOrderWithDepthIterator<'a> {
    type Item = (&'a Element, usize);
    fn next(&mut self) -> Option<(&'a Element, usize)> {
        match self.stack.pop() {
            Some((element, depth)) => {
                for child in element.children.iter().rev() {
                    if let ElementNode(ref e) = *child {
                        self.stack.push((e, depth + 1));
                    }
                }
                Some((element, depth))
            }
            None => None
        }
    }
}
<commit_msg>Fix newline issue in parse_string_to_vector<commit_after>use std::str::FromStr;
use xml::{Element};
use xml::Xml::{ElementNode, CharacterNode};

pub fn parse_string_to_vector<T: FromStr>(string: &str) -> Vec<T> {
    string.trim()
        .split(&[' ', '\n'][..])
        .map(|s| s.parse().ok().expect("Error parsing array in COLLADA file"))
        .collect()
}

pub fn get_array_content<T: FromStr>(element: &Element) -> Option<Vec<T>> {
    match element.children[0] {
        CharacterNode(ref contents) => Some(parse_string_to_vector(contents)),
        _ => None,
    }
}

pub fn has_attribute_with_value(e: &Element, name: &str, value: &str) -> bool {
    if let Some(s) = e.get_attribute(name, None) {
        s == value
    } else {
        false
    }
}

pub fn to_matrix_array(float_array: Vec<f32>) -> Vec<[[f32; 4]; 4]> {
    float_array.chunks(16).map(|chunk| {
        let mut matrix = [[0f32; 4]; 4];
        for (&chunk_value, matrix_value) in chunk.iter().zip(matrix.iter_mut().flat_map(|n| n.iter_mut())) {
            *matrix_value = chunk_value;
        }
        matrix
    }).collect()
}

///
/// Returns an iterator over all ElementNodes in an XML Element subtree with the given root,
/// using a pre-order tree traversal (root before children)
///
pub fn pre_order_iter<'a>(root: &'a Element) -> PreOrderIterator<'a> {
    PreOrderIterator { stack: vec![root] }
}

///
/// Returns an iterator over all ElementNodes in an XML Element subtree with the given root,
/// with their depth relative to the subtree root,
/// using a pre-order tree traversal (root before children)
///
pub fn pre_order_with_depth_iter<'a>(root: &'a Element) -> PreOrderWithDepthIterator<'a> {
    PreOrderWithDepthIterator { stack: vec![(root, 0)] }
}

pub struct PreOrderIterator<'a> {
    stack: Vec<&'a Element>
}

impl<'a> Iterator for PreOrderIterator<'a> {
    type Item = &'a Element;
    fn next(&mut self) -> Option<&'a Element> {
        let current_element = self.stack.pop();
        match current_element {
            Some(element) => {
                for child in element.children.iter().rev() {
                    if let ElementNode(ref e) = *child {
                        self.stack.push(e);
                    }
                }
            }
            None => ()
        }
        current_element
    }
}

pub struct PreOrderWithDepthIterator<'a> {
    stack: Vec<(&'a Element, usize)>
}

impl<'a> Iterator for PreOrderWithDepthIterator<'a> {
    type Item = (&'a Element, usize);
    fn next(&mut self) -> Option<(&'a Element, usize)> {
        match self.stack.pop() {
            Some((element, depth)) => {
                for child in element.children.iter().rev() {
                    if let ElementNode(ref e) = *child {
                        self.stack.push((e, depth + 1));
                    }
                }
                Some((element, depth))
            }
            None => None
        }
    }
}
<|endoftext|>