<commit_before>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use angle::{Rad, acos};
use approx::ApproxEq;
use matrix::Matrix;
use matrix::Matrix2;
use matrix::Matrix3;
use num::BaseFloat;
use point::{Point, Point2, Point3};
use quaternion::Quaternion;
use ray::Ray;
use vector::{Vector, Vector2, Vector3};

/// A trait for a generic rotation. A rotation is a transformation that
/// creates a circular motion, and preserves at least one point in the space.
pub trait Rotation<S: BaseFloat, V: Vector<S>, P: Point<S, V>>: PartialEq + ApproxEq<S> + Sized {
    /// Create the identity transform (causes no transformation).
    fn identity() -> Self;

    /// Create a rotation to a given direction with an 'up' vector
    fn look_at(dir: &V, up: &V) -> Self;

    /// Create a shortest rotation to transform vector 'a' into 'b'.
    /// Both given vectors are assumed to have unit length.
    fn between_vectors(a: &V, b: &V) -> Self;

    /// Rotate a vector using this rotation.
    fn rotate_vector(&self, vec: &V) -> V;

    /// Rotate a point using this rotation, by converting it to its
    /// representation as a vector.
    #[inline]
    fn rotate_point(&self, point: &P) -> P {
        P::from_vec(&self.rotate_vector(&point.to_vec()))
    }

    /// Rotate a ray using this rotation.
    #[inline]
    fn rotate_ray(&self, ray: &Ray<S, P, V>) -> Ray<S, P,V> {
        Ray::new(ray.origin.clone(), self.rotate_vector(&ray.direction))
    }

    /// Create a new rotation which combines both this rotation, and another.
    fn concat(&self, other: &Self) -> Self;

    /// Create a new rotation which "un-does" this rotation. That is,
    /// `r.concat(r.invert())` is the identity.
    fn invert(&self) -> Self;

    /// Modify this rotation in-place by combining it with another.
    #[inline]
    fn concat_self(&mut self, other: &Self) {
        *self = Self::concat(self, other);
    }

    /// Invert this rotation in-place.
    #[inline]
    fn invert_self(&mut self) {
        *self = self.invert();
    }
}

/// A two-dimensional rotation.
pub trait Rotation2<S: BaseFloat>: Rotation<S, Vector2<S>, Point2<S>>
                                 + Into<Matrix2<S>>
                                 + Into<Basis2<S>> {
    /// Create a rotation by a given angle. Thus is a redundant case of both
    /// from_axis_angle() and from_euler() for 2D space.
    fn from_angle(theta: Rad<S>) -> Self;
}

/// A three-dimensional rotation.
pub trait Rotation3<S: BaseFloat>: Rotation<S, Vector3<S>, Point3<S>>
                                 + Into<Matrix3<S>>
                                 + Into<Basis3<S>>
                                 + Into<Quaternion<S>> {
    /// Create a rotation using an angle around a given axis.
    fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Self;

    /// Create a rotation from a set of euler angles.
    ///
    /// # Parameters
    ///
    /// - `x`: the angular rotation around the `x` axis (pitch).
    /// - `y`: the angular rotation around the `y` axis (yaw).
    /// - `z`: the angular rotation around the `z` axis (roll).
    fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Self;

    /// Create a rotation from an angle around the `x` axis (pitch).
    #[inline]
    fn from_angle_x(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle( &Vector3::unit_x(), theta )
    }

    /// Create a rotation from an angle around the `y` axis (yaw).
    #[inline]
    fn from_angle_y(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle( &Vector3::unit_y(), theta )
    }

    /// Create a rotation from an angle around the `z` axis (roll).
    #[inline]
    fn from_angle_z(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle( &Vector3::unit_z(), theta )
    }
}

/// A two-dimensional rotation matrix.
///
/// The matrix is guaranteed to be orthogonal, so some operations can be
/// implemented more efficiently than the implementations for `math::Matrix2`. To
/// enforce orthogonality at the type level the operations have been restricted
/// to a subset of those implemented on `Matrix2`.
///
/// ## Example
///
/// Suppose we want to rotate a vector that lies in the x-y plane by some
/// angle. We can accomplish this quite easily with a two-dimensional rotation
/// matrix:
///
/// ```no_run
/// use cgmath::rad;
/// use cgmath::Vector2;
/// use cgmath::{Matrix, Matrix2};
/// use cgmath::{Rotation, Rotation2, Basis2};
/// use cgmath::ApproxEq;
/// use std::f64;
///
/// // For simplicity, we will rotate the unit x vector to the unit y vector --
/// // so the angle is 90 degrees, or π/2.
/// let unit_x: Vector2<f64> = Vector2::unit_x();
/// let rot: Basis2<f64> = Rotation2::from_angle(rad(0.5f64 * f64::consts::PI));
///
/// // Rotate the vector using the two-dimensional rotation matrix:
/// let unit_y = rot.rotate_vector(&unit_x);
///
/// // Since sin(π/2) may not be exactly zero due to rounding errors, we can
/// // use cgmath's approx_eq() feature to show that it is close enough.
/// assert!(unit_y.approx_eq(&Vector2::unit_y()));
///
/// // This is exactly equivalent to using the raw matrix itself:
/// let unit_y2: Matrix2<_> = rot.into();
/// let unit_y2 = unit_y2.mul_v(&unit_x);
/// assert_eq!(unit_y2, unit_y);
///
/// // Note that we can also concatenate rotations:
/// let rot_half: Basis2<f64> = Rotation2::from_angle(rad(0.25f64 * f64::consts::PI));
/// let unit_y3 = rot_half.concat(&rot_half).rotate_vector(&unit_x);
/// assert!(unit_y3.approx_eq(&unit_y2));
/// ```
#[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Basis2<S> {
    mat: Matrix2<S>
}

impl<S: BaseFloat> AsRef<Matrix2<S>> for Basis2<S> {
    #[inline]
    fn as_ref(&self) -> &Matrix2<S> {
        &self.mat
    }
}

impl<S: BaseFloat> From<Basis2<S>> for Matrix2<S> {
    #[inline]
    fn from(b: Basis2<S>) -> Matrix2<S> { b.mat }
}

impl<S: BaseFloat + 'static> Rotation<S, Vector2<S>, Point2<S>> for Basis2<S> {
    #[inline]
    fn identity() -> Basis2<S> { Basis2{ mat: Matrix2::identity() } }

    #[inline]
    fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Basis2<S> {
        Basis2 { mat: Matrix2::look_at(dir, up) }
    }

    #[inline]
    fn between_vectors(a: &Vector2<S>, b: &Vector2<S>) -> Basis2<S> {
        Rotation2::from_angle( acos(a.dot(b)) )
    }

    #[inline]
    fn rotate_vector(&self, vec: &Vector2<S>) -> Vector2<S> { self.mat.mul_v(vec) }

    #[inline]
    fn concat(&self, other: &Basis2<S>) -> Basis2<S> { Basis2 { mat: self.mat.mul_m(&other.mat) } }

    #[inline]
    fn concat_self(&mut self, other: &Basis2<S>) { self.mat.mul_self_m(&other.mat); }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert(&self) -> Basis2<S> { Basis2 { mat: self.mat.invert().unwrap() } }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert_self(&mut self) { self.mat.invert_self(); }
}

impl<S: BaseFloat> ApproxEq<S> for Basis2<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, epsilon)
    }
}

impl<S: BaseFloat + 'static> Rotation2<S> for Basis2<S> {
    fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Matrix2::from_angle(theta) } }
}

/// A three-dimensional rotation matrix.
///
/// The matrix is guaranteed to be orthogonal, so some operations, specifically
/// inversion, can be implemented more efficiently than the implementations for
/// `math::Matrix3`. To ensure orthogonality is maintained, the operations have
/// been restricted to a subeset of those implemented on `Matrix3`.
#[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Basis3<S> {
    mat: Matrix3<S>
}

impl<S: BaseFloat> Basis3<S> {
    /// Create a new rotation matrix from a quaternion.
    #[inline]
    pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
        Basis3 { mat: quaternion.clone().into() }
    }
}

impl<S> AsRef<Matrix3<S>> for Basis3<S> {
    #[inline]
    fn as_ref(&self) -> &Matrix3<S> {
        &self.mat
    }
}

impl<S: BaseFloat> From<Basis3<S>> for Matrix3<S> {
    #[inline]
    fn from(b: Basis3<S>) -> Matrix3<S> { b.mat }
}

impl<S: BaseFloat + 'static> From<Basis3<S>> for Quaternion<S> {
    #[inline]
    fn from(b: Basis3<S>) -> Quaternion<S> { b.mat.into() }
}

impl<S: BaseFloat + 'static> Rotation<S, Vector3<S>, Point3<S>> for Basis3<S> {
    #[inline]
    fn identity() -> Basis3<S> { Basis3{ mat: Matrix3::identity() } }

    #[inline]
    fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::look_at(dir, up) }
    }

    #[inline]
    fn between_vectors(a: &Vector3<S>, b: &Vector3<S>) -> Basis3<S> {
        let q: Quaternion<S> = Rotation::between_vectors(a, b);
        q.into()
    }

    #[inline]
    fn rotate_vector(&self, vec: &Vector3<S>) -> Vector3<S> { self.mat.mul_v(vec) }

    #[inline]
    fn concat(&self, other: &Basis3<S>) -> Basis3<S> { Basis3 { mat: self.mat.mul_m(&other.mat) } }

    #[inline]
    fn concat_self(&mut self, other: &Basis3<S>) { self.mat.mul_self_m(&other.mat); }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert(&self) -> Basis3<S> { Basis3 { mat: self.mat.invert().unwrap() } }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert_self(&mut self) { self.mat.invert_self(); }
}

impl<S: BaseFloat> ApproxEq<S> for Basis3<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, epsilon)
    }
}

impl<S: BaseFloat + 'static> Rotation3<S> for Basis3<S> {
    fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_axis_angle(axis, angle) }
    }

    fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_euler(x, y ,z) }
    }

    fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_x(theta) }
    }

    fn from_angle_y(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_y(theta) }
    }

    fn from_angle_z(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_z(theta) }
    }
}
<commit_msg>Fix formatting<commit_after>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use angle::{Rad, acos};
use approx::ApproxEq;
use matrix::Matrix;
use matrix::Matrix2;
use matrix::Matrix3;
use num::BaseFloat;
use point::{Point, Point2, Point3};
use quaternion::Quaternion;
use ray::Ray;
use vector::{Vector, Vector2, Vector3};

/// A trait for a generic rotation. A rotation is a transformation that
/// creates a circular motion, and preserves at least one point in the space.
pub trait Rotation<S: BaseFloat, V: Vector<S>, P: Point<S, V>>: PartialEq + ApproxEq<S> + Sized {
    /// Create the identity transform (causes no transformation).
    fn identity() -> Self;

    /// Create a rotation to a given direction with an 'up' vector
    fn look_at(dir: &V, up: &V) -> Self;

    /// Create a shortest rotation to transform vector 'a' into 'b'.
    /// Both given vectors are assumed to have unit length.
    fn between_vectors(a: &V, b: &V) -> Self;

    /// Rotate a vector using this rotation.
    fn rotate_vector(&self, vec: &V) -> V;

    /// Rotate a point using this rotation, by converting it to its
    /// representation as a vector.
    #[inline]
    fn rotate_point(&self, point: &P) -> P {
        P::from_vec(&self.rotate_vector(&point.to_vec()))
    }

    /// Rotate a ray using this rotation.
    #[inline]
    fn rotate_ray(&self, ray: &Ray<S, P, V>) -> Ray<S, P,V> {
        Ray::new(ray.origin.clone(), self.rotate_vector(&ray.direction))
    }

    /// Create a new rotation which combines both this rotation, and another.
    fn concat(&self, other: &Self) -> Self;

    /// Create a new rotation which "un-does" this rotation. That is,
    /// `r.concat(r.invert())` is the identity.
    fn invert(&self) -> Self;

    /// Modify this rotation in-place by combining it with another.
    #[inline]
    fn concat_self(&mut self, other: &Self) {
        *self = Self::concat(self, other);
    }

    /// Invert this rotation in-place.
    #[inline]
    fn invert_self(&mut self) {
        *self = self.invert();
    }
}

/// A two-dimensional rotation.
pub trait Rotation2<S: BaseFloat>: Rotation<S, Vector2<S>, Point2<S>>
                                 + Into<Matrix2<S>>
                                 + Into<Basis2<S>> {
    /// Create a rotation by a given angle. Thus is a redundant case of both
    /// from_axis_angle() and from_euler() for 2D space.
    fn from_angle(theta: Rad<S>) -> Self;
}

/// A three-dimensional rotation.
pub trait Rotation3<S: BaseFloat>: Rotation<S, Vector3<S>, Point3<S>>
                                 + Into<Matrix3<S>>
                                 + Into<Basis3<S>>
                                 + Into<Quaternion<S>> {
    /// Create a rotation using an angle around a given axis.
    fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Self;

    /// Create a rotation from a set of euler angles.
    ///
    /// # Parameters
    ///
    /// - `x`: the angular rotation around the `x` axis (pitch).
    /// - `y`: the angular rotation around the `y` axis (yaw).
    /// - `z`: the angular rotation around the `z` axis (roll).
    fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Self;

    /// Create a rotation from an angle around the `x` axis (pitch).
    #[inline]
    fn from_angle_x(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle(&Vector3::unit_x(), theta)
    }

    /// Create a rotation from an angle around the `y` axis (yaw).
    #[inline]
    fn from_angle_y(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle(&Vector3::unit_y(), theta)
    }

    /// Create a rotation from an angle around the `z` axis (roll).
    #[inline]
    fn from_angle_z(theta: Rad<S>) -> Self {
        Rotation3::from_axis_angle(&Vector3::unit_z(), theta)
    }
}

/// A two-dimensional rotation matrix.
///
/// The matrix is guaranteed to be orthogonal, so some operations can be
/// implemented more efficiently than the implementations for `math::Matrix2`. To
/// enforce orthogonality at the type level the operations have been restricted
/// to a subset of those implemented on `Matrix2`.
///
/// ## Example
///
/// Suppose we want to rotate a vector that lies in the x-y plane by some
/// angle. We can accomplish this quite easily with a two-dimensional rotation
/// matrix:
///
/// ```no_run
/// use cgmath::rad;
/// use cgmath::Vector2;
/// use cgmath::{Matrix, Matrix2};
/// use cgmath::{Rotation, Rotation2, Basis2};
/// use cgmath::ApproxEq;
/// use std::f64;
///
/// // For simplicity, we will rotate the unit x vector to the unit y vector --
/// // so the angle is 90 degrees, or π/2.
/// let unit_x: Vector2<f64> = Vector2::unit_x();
/// let rot: Basis2<f64> = Rotation2::from_angle(rad(0.5f64 * f64::consts::PI));
///
/// // Rotate the vector using the two-dimensional rotation matrix:
/// let unit_y = rot.rotate_vector(&unit_x);
///
/// // Since sin(π/2) may not be exactly zero due to rounding errors, we can
/// // use cgmath's approx_eq() feature to show that it is close enough.
/// assert!(unit_y.approx_eq(&Vector2::unit_y()));
///
/// // This is exactly equivalent to using the raw matrix itself:
/// let unit_y2: Matrix2<_> = rot.into();
/// let unit_y2 = unit_y2.mul_v(&unit_x);
/// assert_eq!(unit_y2, unit_y);
///
/// // Note that we can also concatenate rotations:
/// let rot_half: Basis2<f64> = Rotation2::from_angle(rad(0.25f64 * f64::consts::PI));
/// let unit_y3 = rot_half.concat(&rot_half).rotate_vector(&unit_x);
/// assert!(unit_y3.approx_eq(&unit_y2));
/// ```
#[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Basis2<S> {
    mat: Matrix2<S>
}

impl<S: BaseFloat> AsRef<Matrix2<S>> for Basis2<S> {
    #[inline]
    fn as_ref(&self) -> &Matrix2<S> {
        &self.mat
    }
}

impl<S: BaseFloat> From<Basis2<S>> for Matrix2<S> {
    #[inline]
    fn from(b: Basis2<S>) -> Matrix2<S> { b.mat }
}

impl<S: BaseFloat + 'static> Rotation<S, Vector2<S>, Point2<S>> for Basis2<S> {
    #[inline]
    fn identity() -> Basis2<S> { Basis2{ mat: Matrix2::identity() } }

    #[inline]
    fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Basis2<S> {
        Basis2 { mat: Matrix2::look_at(dir, up) }
    }

    #[inline]
    fn between_vectors(a: &Vector2<S>, b: &Vector2<S>) -> Basis2<S> {
        Rotation2::from_angle(acos(a.dot(b)) )
    }

    #[inline]
    fn rotate_vector(&self, vec: &Vector2<S>) -> Vector2<S> { self.mat.mul_v(vec) }

    #[inline]
    fn concat(&self, other: &Basis2<S>) -> Basis2<S> { Basis2 { mat: self.mat.mul_m(&other.mat) } }

    #[inline]
    fn concat_self(&mut self, other: &Basis2<S>) { self.mat.mul_self_m(&other.mat); }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert(&self) -> Basis2<S> { Basis2 { mat: self.mat.invert().unwrap() } }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert_self(&mut self) { self.mat.invert_self(); }
}

impl<S: BaseFloat> ApproxEq<S> for Basis2<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, epsilon)
    }
}

impl<S: BaseFloat + 'static> Rotation2<S> for Basis2<S> {
    fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Matrix2::from_angle(theta) } }
}

/// A three-dimensional rotation matrix.
///
/// The matrix is guaranteed to be orthogonal, so some operations, specifically
/// inversion, can be implemented more efficiently than the implementations for
/// `math::Matrix3`. To ensure orthogonality is maintained, the operations have
/// been restricted to a subeset of those implemented on `Matrix3`.
#[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Basis3<S> {
    mat: Matrix3<S>
}

impl<S: BaseFloat> Basis3<S> {
    /// Create a new rotation matrix from a quaternion.
    #[inline]
    pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
        Basis3 { mat: quaternion.clone().into() }
    }
}

impl<S> AsRef<Matrix3<S>> for Basis3<S> {
    #[inline]
    fn as_ref(&self) -> &Matrix3<S> {
        &self.mat
    }
}

impl<S: BaseFloat> From<Basis3<S>> for Matrix3<S> {
    #[inline]
    fn from(b: Basis3<S>) -> Matrix3<S> { b.mat }
}

impl<S: BaseFloat + 'static> From<Basis3<S>> for Quaternion<S> {
    #[inline]
    fn from(b: Basis3<S>) -> Quaternion<S> { b.mat.into() }
}

impl<S: BaseFloat + 'static> Rotation<S, Vector3<S>, Point3<S>> for Basis3<S> {
    #[inline]
    fn identity() -> Basis3<S> { Basis3{ mat: Matrix3::identity() } }

    #[inline]
    fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::look_at(dir, up) }
    }

    #[inline]
    fn between_vectors(a: &Vector3<S>, b: &Vector3<S>) -> Basis3<S> {
        let q: Quaternion<S> = Rotation::between_vectors(a, b);
        q.into()
    }

    #[inline]
    fn rotate_vector(&self, vec: &Vector3<S>) -> Vector3<S> { self.mat.mul_v(vec) }

    #[inline]
    fn concat(&self, other: &Basis3<S>) -> Basis3<S> { Basis3 { mat: self.mat.mul_m(&other.mat) } }

    #[inline]
    fn concat_self(&mut self, other: &Basis3<S>) { self.mat.mul_self_m(&other.mat); }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert(&self) -> Basis3<S> { Basis3 { mat: self.mat.invert().unwrap() } }

    // TODO: we know the matrix is orthogonal, so this could be re-written
    // to be faster
    #[inline]
    fn invert_self(&mut self) { self.mat.invert_self(); }
}

impl<S: BaseFloat> ApproxEq<S> for Basis3<S> {
    #[inline]
    fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, epsilon)
    }
}

impl<S: BaseFloat + 'static> Rotation3<S> for Basis3<S> {
    fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_axis_angle(axis, angle) }
    }

    fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_euler(x, y ,z) }
    }

    fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_x(theta) }
    }

    fn from_angle_y(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_y(theta) }
    }

    fn from_angle_z(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Matrix3::from_angle_z(theta) }
    }
}
<|endoftext|>


<commit_before>// Txtrevise
// Command line text editing tool
// Version 1.0.0 (equivalent to Python impl. 1.1)
// Copyright (c) 2015 Sam Saint-Pettersen
// Released under the MIT License.

extern crate regex;
use std::env;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use regex::Regex;

// Display error and then usage information.
fn display_error(err: &str) {
    println!("Error: {}.", err);
    display_usage();
}

/// Display usage information.
fn display_usage() {
    println!("\nTxtrevise v 1.0.0 (rust)");
    println!("Command line text editing tool");
    println!("Copyright (c) 2015 Sam Saint-Pettersen");
    println!("\nReleased under the MIT License");
    println!("Usage: txtrevise.py [-h] (-q) -f <file> -l <line #> -m <word(s)>");
    println!("-r <word(s)>");
    println!("\n-f: File to edit");
    println!("-l: Line number to edit text on (starts at 1)");
    println!("-m: Word(s) to match");
    println!("-r: Replacement word(s) for matched word(s)");
    println!("-q: Quiet mode. Only output to console for errors");
    println!("-h: This help information");
}

/// Process file.
fn process_file(filename: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) {
    let mut line_num: usize = 0;
    let mut index: usize = 0;
    let mut all_lines: Vec<String> = Vec::new();

    // Read each line in file sequentially, store selected line no.
    let f = File::open(filename).unwrap();
    let file = BufReader::new(&f);
    for line in file.lines() {
        all_lines.push(line.unwrap());
        if line_num == line_no - 1 { // - 1, because lines start at 0.
            index = line_num;
        }
        line_num += 1;
    }
    all_lines[index] = match_replace(&all_lines[index], line_no, matches, repl, verbose);
    all_lines.push(String::new());

    let mut w = File::create(filename).unwrap();
    let _ = w.write_all(all_lines.join("\n").as_bytes());
}

/// Match and replace word(s).
fn match_replace(line: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) -> String {
    let new_line: String;
    let re = Regex::new(matches).unwrap();

    // If word(s) are matched, return edited line with replacment word(s).
    if re.is_match(matches) {
        if verbose {
            println!("\nMatched at Line {}: {}", line_no, line);
        }
        new_line = re.replace_all(line, repl);
        if verbose {
            println!("Replaced with: {}", new_line);
        }
    }
    // Otherwise, return same line as before
    else {
        if verbose {
            println!("\nNo matches at Line {}", line_no);
        }
        new_line = line.to_string();
    }
    new_line
}

/// Entry method.
fn main() {
    let args: Vec<_> = env::args().collect();
    let mut i: usize = 0;
    let mut filename = String::new();
    let mut matches = String::new();
    let mut repl = String::new();
    let mut verbose: bool = true;
    let mut line_no: usize = 1;
    if args.len() > 1 {
        for a in args {
            if a == "-h" {
                display_usage();
            }
            if a == "-f" {
                filename = format!("{:?}", env::args().nth(i + 1));
                filename = filename[6..filename.len() - 2].to_string();
            }
            if a == "-l" {
                let mut l = format!("{:?}", env::args().nth(i + 1));
                l = l[6..l.len() - 2].to_string();
                let ol = l.parse::<usize>().ok();
                line_no = match ol {
                    Some(line_no) => line_no,
                    None => {
                        display_error("Line number must be an integer");
                        return;
                    }
                };
                if line_no == 0 {
                    display_error("Line number must be greater than 0");
                    return;
                }
            }
            if a == "-m" {
                matches = format!("{:?}", env::args().nth(i + 1));
                matches = matches[6..matches.len() - 2].to_string();
            }
            if a == "-r" {
                repl = format!("{:?}", env::args().nth(i + 1));
                repl = repl[6..repl.len() - 2].to_string();
            }
            if a == "-q" {
                verbose = false;
            }
            i = i + 1;
        }
    }
    else {
        display_error("No options specified");
    }

    // With necessary arguments, process file.
    if env::args().len() > 2 && filename.len() > 0 {
        process_file(&filename, line_no, &matches, &repl, verbose);
    }
}
<commit_msg>no matches! fixed.<commit_after>// Txtrevise
// Command line text editing tool
// Version 1.0.0 (equivalent to Python impl. 1.1)
// Copyright (c) 2015 Sam Saint-Pettersen
// Released under the MIT License.

extern crate regex;
use std::env;
use std::io::{BufRead, BufReader, Write};
use std::fs::File;
use regex::Regex;

// Display error and then usage information.
fn display_error(err: &str) {
    println!("Error: {}.", err);
    display_usage();
}

/// Display usage information.
fn display_usage() {
    println!("\nTxtrevise v 1.0.0 (rust)");
    println!("Command line text editing tool");
    println!("Copyright (c) 2015 Sam Saint-Pettersen");
    println!("\nReleased under the MIT License");
    println!("Usage: txtrevise.py [-h] (-q) -f <file> -l <line #> -m <word(s)>");
    println!("-r <word(s)>");
    println!("\n-f: File to edit");
    println!("-l: Line number to edit text on (starts at 1)");
    println!("-m: Word(s) to match");
    println!("-r: Replacement word(s) for matched word(s)");
    println!("-q: Quiet mode. Only output to console for errors");
    println!("-h: This help information");
}

/// Process file.
fn process_file(filename: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) {
    let mut line_num: usize = 0;
    let mut index: usize = 0;
    let mut all_lines: Vec<String> = Vec::new();

    // Read each line in file sequentially, store selected line no.
    let f = File::open(filename).unwrap();
    let file = BufReader::new(&f);
    for line in file.lines() {
        all_lines.push(line.unwrap());
        if line_num == line_no - 1 { // - 1, because lines start at 0.
            index = line_num;
        }
        line_num += 1;
    }
    all_lines[index] = match_replace(&all_lines[index], line_no, matches, repl, verbose);
    all_lines.push(String::new());

    let mut w = File::create(filename).unwrap();
    let _ = w.write_all(all_lines.join("\n").as_bytes());
}

/// Match and replace word(s).
fn match_replace(line: &str, line_no: usize, matches: &str, repl: &str, verbose: bool) -> String {
    let new_line: String;
    let re = Regex::new(matches).unwrap();

    // If word(s) are matched, return edited line with replacment word(s).
    if re.is_match(line) {
        if verbose {
            println!("\nMatched at Line {}: {}", line_no, line);
        }
        new_line = re.replace_all(line, repl);
        if verbose {
            println!("Replaced with: {}", new_line);
        }
    }
    // Otherwise, return same line as before
    else {
        if verbose {
            println!("\nNo matches at Line {}", line_no);
        }
        new_line = line.to_string();
    }
    new_line
}

/// Entry method.
fn main() {
    let args: Vec<_> = env::args().collect();
    let mut i: usize = 0;
    let mut filename = String::new();
    let mut matches = String::new();
    let mut repl = String::new();
    let mut verbose: bool = true;
    let mut line_no: usize = 1;
    if args.len() > 1 {
        for a in args {
            if a == "-h" {
                display_usage();
            }
            if a == "-f" {
                filename = format!("{:?}", env::args().nth(i + 1));
                filename = filename[6..filename.len() - 2].to_string();
            }
            if a == "-l" {
                let mut l = format!("{:?}", env::args().nth(i + 1));
                l = l[6..l.len() - 2].to_string();
                let ol = l.parse::<usize>().ok();
                line_no = match ol {
                    Some(line_no) => line_no,
                    None => {
                        display_error("Line number must be an integer");
                        return;
                    }
                };
                if line_no == 0 {
                    display_error("Line number must be greater than 0");
                    return;
                }
            }
            if a == "-m" {
                matches = format!("{:?}", env::args().nth(i + 1));
                matches = matches[6..matches.len() - 2].to_string();
            }
            if a == "-r" {
                repl = format!("{:?}", env::args().nth(i + 1));
                repl = repl[6..repl.len() - 2].to_string();
            }
            if a == "-q" {
                verbose = false;
            }
            i = i + 1;
        }
    }
    else {
        display_error("No options specified");
    }

    // With necessary arguments, process file.
    if env::args().len() > 2 && filename.len() > 0 {
        process_file(&filename, line_no, &matches, &repl, verbose);
    }
}
<|endoftext|>


<commit_before>use na::{DefaultAllocator};

use aliases::TVec;
use traits::{Number, Alloc, Dimension};

/// Checks that all the vector components are `true`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(false, glm::all(&vec));
///
/// let vec = glm::vec2(true, true);
/// assert_eq!(true, glm::all(&vec));
/// ```
///
/// # See also:
///
/// * [`any`](fn.any.html)
/// * [`not`](fn.not.html)
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
    where DefaultAllocator: Alloc<bool, D> {
    v.iter().all(|x| *x)
}

/// Checks that at least one of the vector components is `true`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(true, glm::any(&vec));
///
/// let vec = glm::vec2(true, true);
/// assert_eq!(true, glm::any(&vec));
///
/// let vec = glm::vec2(false, false);
/// assert_eq!(false, glm::any(&vec));
/// ```
///
/// # See also:
///
/// * [`all`](fn.all.html)
/// * [`not`](fn.not.html)
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
    where DefaultAllocator: Alloc<bool, D> {
    v.iter().any(|x| *x)
}

/// Component-wise equality comparison.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x == y)
}

/// Component-wise `>` comparison.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x > y)
}

/// Component-wise `>=` comparison.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x >= y)
}

/// Component-wise `<` comparison.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x < y)
}

/// Component-wise `>=` comparison.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x <= y)
}

/// Component-wise not `!`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(glm::vec2(false, true), glm::not(&vec));
/// ```
///
/// See also:
///
/// * [`all`](fn.all.html)
/// * [`any`](fn.any.html)
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<bool, D> {
    v.map(|x| !x)
}

/// Component-wise not-equality `!=`.
///
/// See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x != y)
}
<commit_msg>Correctly flag "See also" headers.<commit_after>use na::{DefaultAllocator};

use aliases::TVec;
use traits::{Number, Alloc, Dimension};

/// Checks that all the vector components are `true`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(false, glm::all(&vec));
///
/// let vec = glm::vec2(true, true);
/// assert_eq!(true, glm::all(&vec));
/// ```
///
/// # See also:
///
/// * [`any`](fn.any.html)
/// * [`not`](fn.not.html)
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
    where DefaultAllocator: Alloc<bool, D> {
    v.iter().all(|x| *x)
}

/// Checks that at least one of the vector components is `true`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(true, glm::any(&vec));
///
/// let vec = glm::vec2(true, true);
/// assert_eq!(true, glm::any(&vec));
///
/// let vec = glm::vec2(false, false);
/// assert_eq!(false, glm::any(&vec));
/// ```
///
/// # See also:
///
/// * [`all`](fn.all.html)
/// * [`not`](fn.not.html)
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
    where DefaultAllocator: Alloc<bool, D> {
    v.iter().any(|x| *x)
}

/// Component-wise equality comparison.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x == y)
}

/// Component-wise `>` comparison.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x > y)
}

/// Component-wise `>=` comparison.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x >= y)
}

/// Component-wise `<` comparison.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x < y)
}

/// Component-wise `>=` comparison.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x <= y)
}

/// Component-wise not `!`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec2(true, false);
/// assert_eq!(glm::vec2(false, true), glm::not(&vec));
/// ```
///
/// # See also:
///
/// * [`all`](fn.all.html)
/// * [`any`](fn.any.html)
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<bool, D> {
    v.map(|x| !x)
}

/// Component-wise not-equality `!=`.
///
/// # See also:
///
/// * [`equal`](fn.equal.html)
/// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal`](fn.not_equal.html)
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
    where DefaultAllocator: Alloc<N, D> {
    x.zip_map(y, |x, y| x != y)
}
<|endoftext|>


<commit_before>static side: i8 = 8;
static queens: i8 = 8;

fn place(mut board: [i8,..side*side], ix:i8) -> Option<[i8,..side*side]> {
    if board[ix] == 0 {
        return None
    };
    board[ix] = -1;
    let i1 = ix/side;
    let j1 = ix % side;
    for k in range(1,side) {
        let mut loc :i8 = i1 * side + k;
        board[loc] = 0;
        loc = k * side + j1;
        board[loc] = 0;
        loc = (i1-k) * side + (j1-k);
        if loc / side == i1 -k && loc % side == j1 - k && loc != ix && loc >= 0 { board[loc] = 0 };
        loc = loc + 2 * k;
        if loc / side == i1 - k && loc % side == j1 + k && loc != ix && loc >= 0 { board[loc] = 0};
        loc = loc + 2 * side * k;
        if loc / side == i1 + k && loc % side == j1 + k && loc != ix && loc < side*side { board[loc] = 0};
        loc = loc - 2 * k;
        if loc / side == i1 + k && loc % side == j1 - k && loc != ix && loc < side*side { board[loc] = 0};
    }
    Some(board)
}

fn tryplace(b : [i8,..side*side],ix:i8, nq: i8, mut score: u32) -> u32 {
    if nq == queens { return score + 1 }
    for ind in range(ix, side*side) {
        score = match place(b, ind) {
            Some(b2) => tryplace(b2, ind+1, nq+1, score),
            None => score
        };
    }
    return score
}

fn main() {
    let b : [i8, ..side*side] = [1,..side*side];
    let score = tryplace(b, 0, 0, 0);
    println!("{}", score)
}
<commit_msg>Fix N_Queens<commit_after>static side: i8 = 8;
static queens: i8 = 8;

fn place(mut board: [i8,..side*side], ix:i8) -> Option<[i8,..side*side]> {
    if board[ix as uint] == 0 {
        return None
    };
    board[ix as uint] = -1;
    let i1 = ix / side;
    let j1 = ix % side;
    for k in range(1, side) {
        let mut loc: i8 = i1 * side + k;
        board[loc as uint] = 0;
        loc = k * side + j1;
        board[loc as uint] = 0;
        loc = (i1-k) * side + (j1-k);
        if loc / side == i1 -k && loc % side == j1 - k && loc != ix && loc >= 0 { board[loc as uint] = 0 };
        loc = loc + 2 * k;
        if loc / side == i1 - k && loc % side == j1 + k && loc != ix && loc >= 0 { board[loc as uint] = 0};
        loc = loc + 2 * side * k;
        if loc / side == i1 + k && loc % side == j1 + k && loc != ix && loc < side*side { board[loc as uint] = 0};
        loc = loc - 2 * k;
        if loc / side == i1 + k && loc % side == j1 - k && loc != ix && loc < side*side { board[loc as uint] = 0};
    }
    Some(board)
}

fn tryplace(b : [i8,..side*side],ix:i8, nq: i8, mut score: u32) -> u32 {
    if nq == queens { return score + 1 }
    for ind in range(ix, side*side) {
        score = match place(b, ind) {
            Some(b2) => tryplace(b2, ind+1, nq+1, score),
            None => score
        };
    }
    return score
}

fn main() {
    let b : [i8, ..side*side] = [1,..side*side];
    let score = tryplace(b, 0, 0, 0);
    println!("{}", score)
}
<|endoftext|>


<commit_before>use std::ascii::AsciiExt;
use std::collections::BTreeMap;
use std::str::FromStr;
use toml::Value;

use super::identables::Identables;
use super::functions::Functions;
use super::members::Members;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum GStatus {
    Manual,     //already generated
    Generate,
    Comment,
    Ignore,
}

impl GStatus {
    pub fn ignored(&self) -> bool {
        self == &GStatus::Ignore
    }
    pub fn need_generate(&self) -> bool {
        self == &GStatus::Generate
    }
    pub fn normal(&self) -> bool {
        self == &GStatus::Generate || self == &GStatus::Manual
    }
}

impl Default for GStatus {
    fn default() -> GStatus { GStatus::Ignore }
}

impl FromStr for GStatus {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "manual" => Ok(GStatus::Manual),
            "generate" => Ok(GStatus::Generate),
            "comment" => Ok(GStatus::Comment),
            "ignore" => Ok(GStatus::Ignore),
            _ => Err("Wrong object status".into())
        }
    }
}

/// Info about GObject descendant
#[derive(Clone, Debug)]
pub struct GObject {
    pub name: String,
    pub functions: Functions,
    pub members: Members,
    pub status: GStatus,
    pub module_name: Option<String>,
    pub cfg_condition: Option<String>,
}

impl Default for GObject {
    fn default() -> GObject {
        GObject {
            name: "Default".into(),
            functions: Functions::new(),
            members: Members::new(),
            status: Default::default(),
            module_name: None,
            cfg_condition: None,
        }
    }
}

//TODO: ?change to HashMap<String, GStatus>
pub type GObjects =  BTreeMap<String, GObject>;

pub fn parse_toml(toml_objects: &Value) -> GObjects {
    let mut objects = GObjects::new();
    for toml_object in toml_objects.as_slice().unwrap() {
        let gobject = parse_object(toml_object);
        objects.insert(gobject.name.clone(), gobject);
    }
    objects
}

fn parse_object(toml_object: &Value) -> GObject {
    let name: String = toml_object.lookup("name").expect("Object name not defined")
        .as_str().unwrap().into();

    let status = match toml_object.lookup("status") {
        Some(value) => GStatus::from_str(value.as_str().unwrap()).unwrap_or(Default::default()),
        None => Default::default(),
    };

    let functions = Functions::parse(toml_object.lookup("function"), &name);
    let members = Members::parse(toml_object.lookup("member"), &name);
    let module_name = toml_object.lookup("module_name")
        .and_then(|v| v.as_str())
        .map(|s| s.to_owned());
    let cfg_condition = toml_object.lookup("cfg_condition")
        .and_then(|v| v.as_str())
        .map(|s| s.to_owned());

    GObject {
        name: name,
        functions: functions,
        members: members,
        status: status,
        module_name: module_name,
        cfg_condition: cfg_condition,
    }
}

pub fn parse_status_shorthands(objects: &mut GObjects, toml: &Value) {
    use self::GStatus::*;
    for &status in [Manual, Generate, Comment, Ignore].iter() {
        parse_status_shorthand(objects, status, toml);
    }
}

fn parse_status_shorthand(objects: &mut GObjects, status: GStatus, toml: &Value) {
    let name = format!("options.{:?}", status).to_ascii_lowercase();
    toml.lookup(&name).map(|a| a.as_slice().unwrap())
        .map(|a| for name_ in a.iter().map(|s| s.as_str().unwrap()) {
        match objects.get(name_) {
            None => {
                objects.insert(name_.into(), GObject {
                    name: name_.into(),
                    status: status,
                    .. Default::default()
                });
            },
            Some(_) => panic!("Bad name in {}: {} already defined", name, name_),
        }
    });
}
<commit_msg>Allow overriding objects' versions in the config<commit_after>use std::ascii::AsciiExt;
use std::collections::BTreeMap;
use std::str::FromStr;
use toml::Value;

use super::identables::Identables;
use super::functions::Functions;
use super::members::Members;
use version::Version;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum GStatus {
    Manual,     //already generated
    Generate,
    Comment,
    Ignore,
}

impl GStatus {
    pub fn ignored(&self) -> bool {
        self == &GStatus::Ignore
    }
    pub fn need_generate(&self) -> bool {
        self == &GStatus::Generate
    }
    pub fn normal(&self) -> bool {
        self == &GStatus::Generate || self == &GStatus::Manual
    }
}

impl Default for GStatus {
    fn default() -> GStatus { GStatus::Ignore }
}

impl FromStr for GStatus {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "manual" => Ok(GStatus::Manual),
            "generate" => Ok(GStatus::Generate),
            "comment" => Ok(GStatus::Comment),
            "ignore" => Ok(GStatus::Ignore),
            _ => Err("Wrong object status".into())
        }
    }
}

/// Info about GObject descendant
#[derive(Clone, Debug)]
pub struct GObject {
    pub name: String,
    pub functions: Functions,
    pub members: Members,
    pub status: GStatus,
    pub module_name: Option<String>,
    pub version: Option<Version>,
    pub cfg_condition: Option<String>,
}

impl Default for GObject {
    fn default() -> GObject {
        GObject {
            name: "Default".into(),
            functions: Functions::new(),
            members: Members::new(),
            status: Default::default(),
            module_name: None,
            version: None,
            cfg_condition: None,
        }
    }
}

//TODO: ?change to HashMap<String, GStatus>
pub type GObjects =  BTreeMap<String, GObject>;

pub fn parse_toml(toml_objects: &Value) -> GObjects {
    let mut objects = GObjects::new();
    for toml_object in toml_objects.as_slice().unwrap() {
        let gobject = parse_object(toml_object);
        objects.insert(gobject.name.clone(), gobject);
    }
    objects
}

fn parse_object(toml_object: &Value) -> GObject {
    let name: String = toml_object.lookup("name").expect("Object name not defined")
        .as_str().unwrap().into();

    let status = match toml_object.lookup("status") {
        Some(value) => GStatus::from_str(value.as_str().unwrap()).unwrap_or(Default::default()),
        None => Default::default(),
    };

    let functions = Functions::parse(toml_object.lookup("function"), &name);
    let members = Members::parse(toml_object.lookup("member"), &name);
    let module_name = toml_object.lookup("module_name")
        .and_then(|v| v.as_str())
        .map(|s| s.to_owned());
    let version = toml_object.lookup("version")
        .and_then(|v| v.as_str())
        .and_then(|s| s.parse().ok());
    let cfg_condition = toml_object.lookup("cfg_condition")
        .and_then(|v| v.as_str())
        .map(|s| s.to_owned());

    GObject {
        name: name,
        functions: functions,
        members: members,
        status: status,
        module_name: module_name,
        version: version,
        cfg_condition: cfg_condition,
    }
}

pub fn parse_status_shorthands(objects: &mut GObjects, toml: &Value) {
    use self::GStatus::*;
    for &status in [Manual, Generate, Comment, Ignore].iter() {
        parse_status_shorthand(objects, status, toml);
    }
}

fn parse_status_shorthand(objects: &mut GObjects, status: GStatus, toml: &Value) {
    let name = format!("options.{:?}", status).to_ascii_lowercase();
    toml.lookup(&name).map(|a| a.as_slice().unwrap())
        .map(|a| for name_ in a.iter().map(|s| s.as_str().unwrap()) {
        match objects.get(name_) {
            None => {
                objects.insert(name_.into(), GObject {
                    name: name_.into(),
                    status: status,
                    .. Default::default()
                });
            },
            Some(_) => panic!("Bad name in {}: {} already defined", name, name_),
        }
    });
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod rust_crypto;

use std::io;
use std::os;
use std::vec;

use extra::getopts::*;

use rust_crypto::scrypt;

fn print_usage() {
    println("Usage: rust-crypt-util <algorithm> [options]");
    println("-h, --help\tUsage");
    println("");
    println("Algorithms:");
    println(" * Scrypt (scrypt)");
    println("");
    println("Scrypt options:");
    println("--logn\t\tThe Log N parameter");
    println("-r\t\tThe R parameter");
    println("-p\t\tThe P parameter");
    println("--dklen\t\tThe DkLen parameter");
    println("--rawsalt\tThe salt parameter is supplied on STDIN");
    println("--rawpassword\tThe password parameter is supplied on STDIN");
    println("--rawoutput\tThe resulting value should be output directly to STDOUT");
}

fn run_scrypt(matches: &Matches) {
    if !matches.opt_present("logn") || !matches.opt_present("r") || !matches.opt_present("p") ||
       !matches.opt_present("dklen") {
        print_usage();
        return;
    }
    let logn = from_str::<u8>(matches.opt_str("logn").unwrap()).unwrap();
    let r = from_str::<u32>(matches.opt_str("r").unwrap()).unwrap();
    let p = from_str::<u32>(matches.opt_str("p").unwrap()).unwrap();
    let dklen = from_str::<uint>(matches.opt_str("dklen").unwrap()).unwrap();

    if !matches.opt_present("rawsalt") || !matches.opt_present("rawpassword") ||
       !matches.opt_present("rawoutput") {
        println("Required options missing.");
        return;
    }

    let salt_len = io::stdin().read_be_u32();
    let salt = io::stdin().read_bytes(salt_len as uint);
    let pass_len = io::stdin().read_be_u32();
    let pass = io::stdin().read_bytes(pass_len as uint);

    let params = scrypt::ScryptParams::new(logn, r, p);
    let mut output = vec::from_elem(dklen, 0u8);
    scrypt::scrypt(pass, salt, &params, output);

    io::stdout().write(output);
}

fn main() {
    let args = os::args();

    let opts = ~[
        // General parameters:
        optflag("h"),
        optflag("help"),

        // Scrypt parameters:
        optopt("logn"),
        optopt("r"),
        optopt("p"),
        optopt("dklen"),
        optflag("rawsalt"),
        optflag("rawpassword"),
        optflag("rawoutput"),
    ];

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_usage();
        return;
    }

    if matches.free.is_empty() {
        print_usage();
        return;
    }
    let algorithm_name: &str = matches.free[0];

    match algorithm_name {
        "scrypt" => run_scrypt(&matches),
        _ => {
            print_usage();
            return;
        }
    }
}
<commit_msg>Use explicitly named imports since glob imports are considered experimental.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod rust_crypto;

use std::io;
use std::os;
use std::vec;

use extra::getopts::{optopt, optflag, getopts, Matches};

use rust_crypto::scrypt;

fn print_usage() {
    println("Usage: rust-crypt-util <algorithm> [options]");
    println("-h, --help\tUsage");
    println("");
    println("Algorithms:");
    println(" * Scrypt (scrypt)");
    println("");
    println("Scrypt options:");
    println("--logn\t\tThe Log N parameter");
    println("-r\t\tThe R parameter");
    println("-p\t\tThe P parameter");
    println("--dklen\t\tThe DkLen parameter");
    println("--rawsalt\tThe salt parameter is supplied on STDIN");
    println("--rawpassword\tThe password parameter is supplied on STDIN");
    println("--rawoutput\tThe resulting value should be output directly to STDOUT");
}

fn run_scrypt(matches: &Matches) {
    if !matches.opt_present("logn") || !matches.opt_present("r") || !matches.opt_present("p") ||
       !matches.opt_present("dklen") {
        print_usage();
        return;
    }
    let logn = from_str::<u8>(matches.opt_str("logn").unwrap()).unwrap();
    let r = from_str::<u32>(matches.opt_str("r").unwrap()).unwrap();
    let p = from_str::<u32>(matches.opt_str("p").unwrap()).unwrap();
    let dklen = from_str::<uint>(matches.opt_str("dklen").unwrap()).unwrap();

    if !matches.opt_present("rawsalt") || !matches.opt_present("rawpassword") ||
       !matches.opt_present("rawoutput") {
        println("Required options missing.");
        return;
    }

    let salt_len = io::stdin().read_be_u32();
    let salt = io::stdin().read_bytes(salt_len as uint);
    let pass_len = io::stdin().read_be_u32();
    let pass = io::stdin().read_bytes(pass_len as uint);

    let params = scrypt::ScryptParams::new(logn, r, p);
    let mut output = vec::from_elem(dklen, 0u8);
    scrypt::scrypt(pass, salt, &params, output);

    io::stdout().write(output);
}

fn main() {
    let args = os::args();

    let opts = ~[
        // General parameters:
        optflag("h"),
        optflag("help"),

        // Scrypt parameters:
        optopt("logn"),
        optopt("r"),
        optopt("p"),
        optopt("dklen"),
        optflag("rawsalt"),
        optflag("rawpassword"),
        optflag("rawoutput"),
    ];

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_usage();
        return;
    }

    if matches.free.is_empty() {
        print_usage();
        return;
    }
    let algorithm_name: &str = matches.free[0];

    match algorithm_name {
        "scrypt" => run_scrypt(&matches),
        _ => {
            print_usage();
            return;
        }
    }
}
<|endoftext|>


<commit_before>pub mod md5;
pub mod sha1;

pub trait Hasher
{
    /**
     * Reset the hasher's state.
     */
    fn reset(&mut self);

    /**
     * Provide input data.
     */
    fn update(&mut self, data: &[u8]);

    /**
     * Retrieve digest result. The output must be large enough to contains result
     * size (from output_size method).
     */
    fn output(&self, out: &mut [u8]);

    /**
     * Get the output size in bits.
     */
    fn output_size_bits(&self) -> uint;

    /**
     * Get the block size in bits.
     */
    fn block_size_bits(&self) -> uint;

    /**
     * Get the output size in bytes.
     */
    fn output_size(&self) -> uint
    {
        (self.output_size_bits() + 7) / 8
    }

    /**
     * Get the block size in bytes.
     */
    fn block_size(&self) -> uint
    {
        (self.block_size_bits() + 7) / 8
    }

    fn digest(&self) -> ~[u8]
    {
        let size = self.output_size();
        let mut buf = Vec::from_elem(size, 0u8);

        self.output(buf.as_mut_slice());

        buf.as_slice().to_owned()
    }
}
<commit_msg>Add `Hashable` trait and implement it for &[u8]<commit_after>pub mod md5;
pub mod sha1;

pub trait Hasher
{
    /**
     * Reset the hasher's state.
     */
    fn reset(&mut self);

    /**
     * Provide input data.
     */
    fn update(&mut self, data: &[u8]);

    /**
     * Retrieve digest result. The output must be large enough to contains result
     * size (from output_size method).
     */
    fn output(&self, out: &mut [u8]);

    /**
     * Get the output size in bits.
     */
    fn output_size_bits(&self) -> uint;

    /**
     * Get the block size in bits.
     */
    fn block_size_bits(&self) -> uint;

    /**
     * Get the output size in bytes.
     */
    fn output_size(&self) -> uint
    {
        (self.output_size_bits() + 7) / 8
    }

    /**
     * Get the block size in bytes.
     */
    fn block_size(&self) -> uint
    {
        (self.block_size_bits() + 7) / 8
    }

    fn digest(&self) -> ~[u8]
    {
        let size = self.output_size();
        let mut buf = Vec::from_elem(size, 0u8);

        self.output(buf.as_mut_slice());

        buf.as_slice().to_owned()
    }
}

pub trait Hashable {
    /**
     * Feed the value to the hasher passed in parameter.
     */
     fn feed<H: Hasher>(&self, h: &mut H);

    /**
     * Hash the value to ~[u8].
     *
     * Reset the hasher passed in parameter, because we want
     * an empty hasher to get only the value's hash.
     */
    fn to_hash<H: Hasher>(&self, h: &mut H) -> ~[u8]
    {
        h.reset();
        self.feed(h);
        h.digest()
    }
}

impl<'a> Hashable for &'a [u8] {
    fn feed<H: Hasher>(&self, h: &mut H)
    {
        h.update(*self)
    }
}
<|endoftext|>


<commit_before>use crate::error;
use std::io;

pub trait LZBuffer {
    fn len(&self) -> usize;
    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8;
    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8>;
    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()>;
    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()>;
    // Flush the buffer to the output
    fn finish(self) -> io::Result<()>;
}

// An accumulating buffer for LZ sequences
pub struct LZAccumBuffer<'a, W>
where
    W: 'a + io::Write,
{
    stream: &'a mut W, // Output sink
    buf: Vec<u8>,      // Buffer
    len: usize,        // Total number of bytes sent through the buffer
}

impl<'a, W> LZAccumBuffer<'a, W>
where
    W: io::Write,
{
    pub fn from_stream(stream: &'a mut W) -> Self {
        Self {
            stream,
            buf: Vec::new(),
            len: 0,
        }
    }

    // Append bytes
    pub fn append_bytes(&mut self, buf: &[u8]) {
        self.buf.extend_from_slice(buf);
        self.len += buf.len();
    }

    // Reset the internal dictionary
    pub fn reset(&mut self) -> io::Result<()> {
        self.stream.write_all(self.buf.as_slice())?;
        self.buf.clear();
        // TODO: clear the length ?
        Ok(())
    }
}

impl<'a, W> LZBuffer for LZAccumBuffer<'a, W>
where
    W: io::Write,
{
    fn len(&self) -> usize {
        self.len
    }

    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8 {
        let buf_len = self.buf.len();
        if buf_len == 0 {
            lit
        } else {
            self.buf[buf_len - 1]
        }
    }

    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8> {
        let buf_len = self.buf.len();
        if dist > buf_len {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond output size {}",
                dist, buf_len
            )));
        }

        Ok(self.buf[buf_len - dist])
    }

    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()> {
        self.buf.push(lit);
        self.len += 1;
        Ok(())
    }

    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()> {
        debug!("LZ {{ len: {}, dist: {} }}", len, dist);
        let buf_len = self.buf.len();
        if dist > buf_len {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond output size {}",
                dist, buf_len
            )));
        }

        let mut offset = buf_len - dist;
        for _ in 0..len {
            let x = self.buf[offset];
            self.buf.push(x);
            offset += 1;
        }
        self.len += len;
        Ok(())
    }

    // Flush the buffer to the output
    fn finish(self) -> io::Result<()> {
        self.stream.write_all(self.buf.as_slice())?;
        self.stream.flush()?;
        Ok(())
    }
}

// A circular buffer for LZ sequences
pub struct LZCircularBuffer<'a, W>
where
    W: 'a + io::Write,
{
    stream: &'a mut W, // Output sink
    buf: Vec<u8>,      // Circular buffer
    dict_size: usize,  // Length of the buffer
    cursor: usize,     // Current position
    len: usize,        // Total number of bytes sent through the buffer
}

impl<'a, W> LZCircularBuffer<'a, W>
where
    W: io::Write,
{
    pub fn from_stream(stream: &'a mut W, dict_size: usize) -> Self {
        info!("Dict size in LZ buffer: {}", dict_size);
        Self {
            stream,
            buf: Vec::new(),
            dict_size,
            cursor: 0,
            len: 0,
        }
    }

    fn get(&self, index: usize) -> u8 {
        *self.buf.get(index).unwrap_or(&0)
    }

    fn get_mut(&mut self, index: usize) -> &mut u8 {
        if self.buf.len() < index + 1 {
            self.buf.resize(index + 1, 0);
        }
        self.buf.get_mut(index).unwrap()
    }
}

impl<'a, W> LZBuffer for LZCircularBuffer<'a, W>
where
    W: io::Write,
{
    fn len(&self) -> usize {
        self.len
    }

    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8 {
        if self.len == 0 {
            lit
        } else {
            self.get((self.dict_size + self.cursor - 1) % self.dict_size)
        }
    }

    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8> {
        if dist > self.dict_size {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond dictionary size {}",
                dist, self.dict_size
            )));
        }
        if dist > self.len {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond output size {}",
                dist, self.len
            )));
        }

        let offset = (self.dict_size + self.cursor - dist) % self.dict_size;
        Ok(self.get(offset))
    }

    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()> {
        *self.get_mut(self.cursor) = lit;
        self.cursor += 1;
        self.len += 1;

        // Flush the circular buffer to the output
        if self.cursor == self.dict_size {
            self.stream.write_all(self.buf.as_slice())?;
            self.cursor = 0;
        }

        Ok(())
    }

    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()> {
        debug!("LZ {{ len: {}, dist: {} }}", len, dist);
        if dist > self.dict_size {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond dictionary size {}",
                dist, self.dict_size
            )));
        }
        if dist > self.len {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond output size {}",
                dist, self.len
            )));
        }

        let mut offset = (self.dict_size + self.cursor - dist) % self.dict_size;
        for _ in 0..len {
            let x = self.get(offset);
            self.append_literal(x)?;
            offset += 1;
            if offset == self.dict_size {
                offset = 0
            }
        }
        Ok(())
    }

    // Flush the buffer to the output
    fn finish(self) -> io::Result<()> {
        if self.cursor > 0 {
            self.stream.write_all(&self.buf[0..self.cursor])?;
            self.stream.flush()?;
        }
        Ok(())
    }
}
<commit_msg>Rename LZBuffer::get_mut -> set.<commit_after>use crate::error;
use std::io;

pub trait LZBuffer {
    fn len(&self) -> usize;
    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8;
    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8>;
    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()>;
    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()>;
    // Flush the buffer to the output
    fn finish(self) -> io::Result<()>;
}

// An accumulating buffer for LZ sequences
pub struct LZAccumBuffer<'a, W>
where
    W: 'a + io::Write,
{
    stream: &'a mut W, // Output sink
    buf: Vec<u8>,      // Buffer
    len: usize,        // Total number of bytes sent through the buffer
}

impl<'a, W> LZAccumBuffer<'a, W>
where
    W: io::Write,
{
    pub fn from_stream(stream: &'a mut W) -> Self {
        Self {
            stream,
            buf: Vec::new(),
            len: 0,
        }
    }

    // Append bytes
    pub fn append_bytes(&mut self, buf: &[u8]) {
        self.buf.extend_from_slice(buf);
        self.len += buf.len();
    }

    // Reset the internal dictionary
    pub fn reset(&mut self) -> io::Result<()> {
        self.stream.write_all(self.buf.as_slice())?;
        self.buf.clear();
        // TODO: clear the length ?
        Ok(())
    }
}

impl<'a, W> LZBuffer for LZAccumBuffer<'a, W>
where
    W: io::Write,
{
    fn len(&self) -> usize {
        self.len
    }

    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8 {
        let buf_len = self.buf.len();
        if buf_len == 0 {
            lit
        } else {
            self.buf[buf_len - 1]
        }
    }

    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8> {
        let buf_len = self.buf.len();
        if dist > buf_len {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond output size {}",
                dist, buf_len
            )));
        }

        Ok(self.buf[buf_len - dist])
    }

    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()> {
        self.buf.push(lit);
        self.len += 1;
        Ok(())
    }

    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()> {
        debug!("LZ {{ len: {}, dist: {} }}", len, dist);
        let buf_len = self.buf.len();
        if dist > buf_len {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond output size {}",
                dist, buf_len
            )));
        }

        let mut offset = buf_len - dist;
        for _ in 0..len {
            let x = self.buf[offset];
            self.buf.push(x);
            offset += 1;
        }
        self.len += len;
        Ok(())
    }

    // Flush the buffer to the output
    fn finish(self) -> io::Result<()> {
        self.stream.write_all(self.buf.as_slice())?;
        self.stream.flush()?;
        Ok(())
    }
}

// A circular buffer for LZ sequences
pub struct LZCircularBuffer<'a, W>
where
    W: 'a + io::Write,
{
    stream: &'a mut W, // Output sink
    buf: Vec<u8>,      // Circular buffer
    dict_size: usize,  // Length of the buffer
    cursor: usize,     // Current position
    len: usize,        // Total number of bytes sent through the buffer
}

impl<'a, W> LZCircularBuffer<'a, W>
where
    W: io::Write,
{
    pub fn from_stream(stream: &'a mut W, dict_size: usize) -> Self {
        info!("Dict size in LZ buffer: {}", dict_size);
        Self {
            stream,
            buf: Vec::new(),
            dict_size,
            cursor: 0,
            len: 0,
        }
    }

    fn get(&self, index: usize) -> u8 {
        *self.buf.get(index).unwrap_or(&0)
    }

    fn set(&mut self, index: usize, value: u8) {
        if self.buf.len() < index + 1 {
            self.buf.resize(index + 1, 0);
        }
        self.buf[index] = value;
    }
}

impl<'a, W> LZBuffer for LZCircularBuffer<'a, W>
where
    W: io::Write,
{
    fn len(&self) -> usize {
        self.len
    }

    // Retrieve the last byte or return a default
    fn last_or(&self, lit: u8) -> u8 {
        if self.len == 0 {
            lit
        } else {
            self.get((self.dict_size + self.cursor - 1) % self.dict_size)
        }
    }

    // Retrieve the n-th last byte
    fn last_n(&self, dist: usize) -> error::Result<u8> {
        if dist > self.dict_size {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond dictionary size {}",
                dist, self.dict_size
            )));
        }
        if dist > self.len {
            return Err(error::Error::LZMAError(format!(
                "Match distance {} is beyond output size {}",
                dist, self.len
            )));
        }

        let offset = (self.dict_size + self.cursor - dist) % self.dict_size;
        Ok(self.get(offset))
    }

    // Append a literal
    fn append_literal(&mut self, lit: u8) -> io::Result<()> {
        self.set(self.cursor, lit);
        self.cursor += 1;
        self.len += 1;

        // Flush the circular buffer to the output
        if self.cursor == self.dict_size {
            self.stream.write_all(self.buf.as_slice())?;
            self.cursor = 0;
        }

        Ok(())
    }

    // Fetch an LZ sequence (length, distance) from inside the buffer
    fn append_lz(&mut self, len: usize, dist: usize) -> error::Result<()> {
        debug!("LZ {{ len: {}, dist: {} }}", len, dist);
        if dist > self.dict_size {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond dictionary size {}",
                dist, self.dict_size
            )));
        }
        if dist > self.len {
            return Err(error::Error::LZMAError(format!(
                "LZ distance {} is beyond output size {}",
                dist, self.len
            )));
        }

        let mut offset = (self.dict_size + self.cursor - dist) % self.dict_size;
        for _ in 0..len {
            let x = self.get(offset);
            self.append_literal(x)?;
            offset += 1;
            if offset == self.dict_size {
                offset = 0
            }
        }
        Ok(())
    }

    // Flush the buffer to the output
    fn finish(self) -> io::Result<()> {
        if self.cursor > 0 {
            self.stream.write_all(&self.buf[0..self.cursor])?;
            self.stream.flush()?;
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
 * The datas extracted from a sound file.
 *
 * Samples extracted from a file,
 *
 * SoundDatas are made to be share between several Sound and play in the same time.
 *
 * # Example
 * ```
 * extern mod ears;
 * use ears::{Sound, SoundData};
 *
 * fn main() -> () {
 *   // Create a SoundData
 *   let snd_data = @SoundData::new(~"path/to/my/sound.wav").unwrap();
 *
 *   // Create two Sound with the same SoundData
 *   let snd1 = Sound::new_with_data(snd_data).unwrap();
 *   let snd2 = Sound::new)with_data(snd_data).unwrap();
 *
 *   // Play the sounds
 *   snd1.play();
 *   snd2.play();
 *
 *   // Wait until snd2 is playing
 *   while snd2.is_playing() {}
 * }
 * ```
 */

use sndfile::{SndFile, SndInfo, Read};
use std::{vec, mem};
use openal::{ffi, al};
use std::libc::c_void;
use internal::OpenAlData;
use audio_tags::{Tags, AudioTags, get_sound_tags};

/// Structure containing the data extracted from the sound file.
pub struct SoundData {
    /// The SoundTags who contains all the information of the sound
    priv sound_tags     : Tags,
    /// The sndfile samples information
    priv snd_info       : SndInfo,
    /// The total samples count of the Sound
    priv nb_sample      : i64,
    /// The OpenAl internal identifier for the buffer
    priv al_buffer      : u32
}

impl SoundData {
    /**
     * Create a new SoundData.
     *
     * The SoundData contains all the information extracted from the file : samples and tags.
     * It's an easy way to share the same samples between man Sounds objects.
     *
     * # Arguments
     * * `path` - The path of the file to load
     *
     * # Return
     * An Option with Some(SoundData) if the SoundData is create, or None if an error has occured.
     */
    pub fn new(path : &str) -> Option<SoundData> {
        check_openal_context!(None);

        let mut file;

        match SndFile::new(path, Read) {
            Ok(file_) => file = file_,
            Err(err) => { println!("{}", err); return None; }
        };

        let infos = file.get_sndinfo();

        let nb_sample = infos.channels as i64 * infos.frames;

        let mut samples = vec::from_elem(nb_sample as uint, 0i16);
        file.read_i16(samples, nb_sample as i64);

        let mut buffer_id = 0;
        let len = mem::size_of::<i16>() * (samples.len());

        // Retrieve format informations
        let format =  match al::get_channels_format(infos.channels) {
            Some(fmt) => fmt,
            None => { println!("Internal error : unrecognized format."); return None; }
        };

        al::alGenBuffers(1, &mut buffer_id);
        al::alBufferData(buffer_id, format, samples.as_ptr() as *c_void, len as i32, infos.samplerate);

        match al::openal_has_error() {
            Some(err)   => { println!("{}", err); return None; },
            None        => {}
        };

        let sound_data = SoundData {
            sound_tags  : get_sound_tags(&file),
            snd_info    : infos,
            nb_sample   : nb_sample,
            al_buffer   : buffer_id
        };
        file.close();

        Some(sound_data)
    }

    /**
     * Get the sound file infos.
     *
     * # Return
     * The struct SndInfo.
     */
    #[doc(hidden)]
    pub fn get_sndinfo<'r>(&'r self) -> &'r SndInfo {
        &self.snd_info
    }

    /**
     * Get the OpenAL identifier of the samples buffer.
     *
     * # Return
     * The OpenAL internal identifier for the samples buffer of the sound.
     */
    #[doc(hidden)]
    pub fn get_buffer(&self) -> u32 {
        self.al_buffer
    }
}

impl AudioTags for SoundData {
    /**
     * Get the tags of a Sound.
     *
     * # Return
     * A borrowed pointer to the internal struct SoundTags
     */
    fn get_tags(&self) -> Tags {
        self.sound_tags.clone()
    }
}

impl Drop for SoundData {
    /**
     * Destroy all the resources attached to the SoundData.
     */
    fn drop(&mut self) -> () {
        unsafe {
            ffi::alDeleteBuffers(1, &mut self.al_buffer);
        }
    }
}

#[cfg(test)]
mod test {
    #[allow(unused_variable)]
    use sound_data::SoundData;

    #[test]
    fn sounddata_create_OK() -> () {
        #[allow(unused_variable)];
        let snd_data = SoundData::new("shot.wav").unwrap();

    }

    #[test]
    #[should_fail]
    fn sounddata_create_FAIL() -> () {
        #[allow(unused_variable)];
        let snd_data = SoundData::new("toto.wav").unwrap();
    }
}
<commit_msg>remove warning visible_private_types.<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
 * The datas extracted from a sound file.
 *
 * Samples extracted from a file,
 *
 * SoundDatas are made to be share between several Sound and play in the same time.
 *
 * # Example
 * ```
 * extern mod ears;
 * use ears::{Sound, SoundData};
 *
 * fn main() -> () {
 *   // Create a SoundData
 *   let snd_data = @SoundData::new(~"path/to/my/sound.wav").unwrap();
 *
 *   // Create two Sound with the same SoundData
 *   let snd1 = Sound::new_with_data(snd_data).unwrap();
 *   let snd2 = Sound::new)with_data(snd_data).unwrap();
 *
 *   // Play the sounds
 *   snd1.play();
 *   snd2.play();
 *
 *   // Wait until snd2 is playing
 *   while snd2.is_playing() {}
 * }
 * ```
 */

#[allow(visible_private_types)];

use sndfile::{SndFile, SndInfo, Read};
use std::{vec, mem};
use openal::{ffi, al};
use std::libc::c_void;
use internal::OpenAlData;
use audio_tags::{Tags, AudioTags, get_sound_tags};

/// Structure containing the data extracted from the sound file.
pub struct SoundData {
    /// The SoundTags who contains all the information of the sound
    priv sound_tags     : Tags,
    /// The sndfile samples information
    priv snd_info       : SndInfo,
    /// The total samples count of the Sound
    priv nb_sample      : i64,
    /// The OpenAl internal identifier for the buffer
    priv al_buffer      : u32
}

impl SoundData {
    /**
     * Create a new SoundData.
     *
     * The SoundData contains all the information extracted from the file : samples and tags.
     * It's an easy way to share the same samples between man Sounds objects.
     *
     * # Arguments
     * * `path` - The path of the file to load
     *
     * # Return
     * An Option with Some(SoundData) if the SoundData is create, or None if an error has occured.
     */
    pub fn new(path : &str) -> Option<SoundData> {
        check_openal_context!(None);

        let mut file;

        match SndFile::new(path, Read) {
            Ok(file_) => file = file_,
            Err(err) => { println!("{}", err); return None; }
        };

        let infos = file.get_sndinfo();

        let nb_sample = infos.channels as i64 * infos.frames;

        let mut samples = vec::from_elem(nb_sample as uint, 0i16);
        file.read_i16(samples, nb_sample as i64);

        let mut buffer_id = 0;
        let len = mem::size_of::<i16>() * (samples.len());

        // Retrieve format informations
        let format =  match al::get_channels_format(infos.channels) {
            Some(fmt) => fmt,
            None => { println!("Internal error : unrecognized format."); return None; }
        };

        al::alGenBuffers(1, &mut buffer_id);
        al::alBufferData(buffer_id, format, samples.as_ptr() as *c_void, len as i32, infos.samplerate);

        match al::openal_has_error() {
            Some(err)   => { println!("{}", err); return None; },
            None        => {}
        };

        let sound_data = SoundData {
            sound_tags  : get_sound_tags(&file),
            snd_info    : infos,
            nb_sample   : nb_sample,
            al_buffer   : buffer_id
        };
        file.close();

        Some(sound_data)
    }

    /**
     * Get the sound file infos.
     *
     * # Return
     * The struct SndInfo.
     */
    #[doc(hidden)]
    pub fn get_sndinfo<'r>(&'r self) -> &'r SndInfo {
        &self.snd_info
    }

    /**
     * Get the OpenAL identifier of the samples buffer.
     *
     * # Return
     * The OpenAL internal identifier for the samples buffer of the sound.
     */
    #[doc(hidden)]
    pub fn get_buffer(&self) -> u32 {
        self.al_buffer
    }
}

impl AudioTags for SoundData {
    /**
     * Get the tags of a Sound.
     *
     * # Return
     * A borrowed pointer to the internal struct SoundTags
     */
    fn get_tags(&self) -> Tags {
        self.sound_tags.clone()
    }
}

impl Drop for SoundData {
    /**
     * Destroy all the resources attached to the SoundData.
     */
    fn drop(&mut self) -> () {
        unsafe {
            ffi::alDeleteBuffers(1, &mut self.al_buffer);
        }
    }
}

#[cfg(test)]
mod test {
    #[allow(unused_variable)]
    use sound_data::SoundData;

    #[test]
    fn sounddata_create_OK() -> () {
        #[allow(unused_variable)];
        let snd_data = SoundData::new("shot.wav").unwrap();

    }

    #[test]
    #[should_fail]
    fn sounddata_create_FAIL() -> () {
        #[allow(unused_variable)];
        let snd_data = SoundData::new("toto.wav").unwrap();
    }
}
<|endoftext|>