<commit_before>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS 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;
use matrix::Matrix;
use matrix::{Mat2, ToMat2};
use matrix::{Mat3, ToMat3};
use point::{Point2, Point3};
use quaternion::{Quat, ToQuat};
use ray::{Ray2, Ray3};
use vector::{Vector, Vec2, Vec3};

/// A two-dimensional rotation
pub trait Rotation2
<
    S
>
:   Eq
+   ApproxEq<S>
+   ToMat2<S>
+   ToRot2<S>
{
    fn rotate_point2(&self, point: &Point2<S>) -> Point2<S>;
    fn rotate_vec2(&self, vec: &Vec2<S>) -> Vec2<S>;
    fn rotate_ray2(&self, ray: &Ray2<S>) -> Ray2<S>;
    fn concat(&self, other: &Self) -> Self;
    fn concat_self(&mut self, other: &Self);
    fn invert(&self) -> Self;
    fn invert_self(&mut self);
}

/// A three-dimensional rotation
pub trait Rotation3
<
    S
>
:   Eq
+   ApproxEq<S>
+   ToMat3<S>
+   ToRot3<S>
+   ToQuat<S>
{
    fn rotate_point3(&self, point: &Point3<S>) -> Point3<S>;
    fn rotate_vec3(&self, vec: &Vec3<S>) -> Vec3<S>;
    fn rotate_ray3(&self, ray: &Ray3<S>) -> Ray3<S>;
    fn concat(&self, other: &Self) -> Self;
    fn concat_self(&mut self, other: &Self);
    fn invert(&self) -> Self;
    fn invert_self(&mut self);
}

/// 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::Mat2`. To
/// enforce orthogonality at the type level the operations have been restricted
/// to a subeset of those implemented on `Mat2`.
#[deriving(Eq, Clone)]
pub struct Rot2<S> {
    priv mat: Mat2<S>
}

impl<S: Float> Rot2<S> {
    #[inline]
    pub fn as_mat2<'a>(&'a self) -> &'a Mat2<S> { &'a self.mat }
}

pub trait ToRot2<S: Float> {
    fn to_rot2(&self) -> Rot2<S>;
}

impl<S: Float> ToRot2<S> for Rot2<S> {
    #[inline]
    fn to_rot2(&self) -> Rot2<S> { self.clone() }
}

impl<S: Float> ToMat2<S> for Rot2<S> {
    #[inline]
    fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
}

impl<S: Float> Rotation2<S> for Rot2<S> {
    #[inline]
    fn rotate_point2(&self, _point: &Point2<S>) -> Point2<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray2(&self, _ray: &Ray2<S>) -> Ray2<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn concat_self(&mut self, other: &Rot2<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) -> Rot2<S> { Rot2 { 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: Float> ApproxEq<S> for Rot2<S> {
    #[inline]
    fn approx_epsilon() -> S {
        // TODO: fix this after static methods are fixed in rustc
        fail!(~"Doesn't work!");
    }

    #[inline]
    fn approx_eq(&self, other: &Rot2<S>) -> bool {
        self.mat.approx_eq(&other.mat)
    }

    #[inline]
    fn approx_eq_eps(&self, other: &Rot2<S>, approx_epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, approx_epsilon)
    }
}

/// 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::Mat3`. To ensure orthogonality is maintained, the operations have
/// been restricted to a subeset of those implemented on `Mat3`.
#[deriving(Eq, Clone)]
pub struct Rot3<S> {
    priv mat: Mat3<S>
}

impl<S: Float> Rot3<S> {
    #[inline]
    pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::look_at(dir, up) }
    }

    /// Create a rotation matrix from a rotation around the `x` axis (pitch).
    pub fn from_angle_x(theta: Rad<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::from_angle_x(theta) }
    }

    /// Create a rotation matrix from a rotation around the `y` axis (yaw).
    pub fn from_angle_y(theta: Rad<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::from_angle_y(theta) }
    }

    /// Create a rotation matrix from a rotation around the `z` axis (roll).
    pub fn from_angle_z(theta: Rad<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::from_angle_z(theta) }
    }

    /// Create a rotation matrix 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).
    pub fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::from_euler(x, y ,z) }
    }

    /// Create a rotation matrix from a rotation around an arbitrary axis.
    pub fn from_axis_angle(axis: &Vec3<S>, angle: Rad<S>) -> Rot3<S> {
        Rot3 { mat: Mat3::from_axis_angle(axis, angle) }
    }

    #[inline]
    pub fn as_mat3<'a>(&'a self) -> &'a Mat3<S> { &'a self.mat }
}

pub trait ToRot3<S: Float> {
    fn to_rot3(&self) -> Rot3<S>;
}

impl<S: Float> ToRot3<S> for Rot3<S> {
    #[inline]
    fn to_rot3(&self) -> Rot3<S> { self.clone() }
}

impl<S: Float> ToMat3<S> for Rot3<S> {
    #[inline]
    fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
}

impl<S: Float> ToQuat<S> for Rot3<S> {
    #[inline]
    fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
}

impl<S: Float> Rotation3<S> for Rot3<S> {
    #[inline]
    fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn concat_self(&mut self, other: &Rot3<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) -> Rot3<S> { Rot3 { 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: Float> ApproxEq<S> for Rot3<S> {
    #[inline]
    fn approx_epsilon() -> S {
        // TODO: fix this after static methods are fixed in rustc
        fail!(~"Doesn't work!");
    }

    #[inline]
    fn approx_eq(&self, other: &Rot3<S>) -> bool {
        self.mat.approx_eq(&other.mat)
    }

    #[inline]
    fn approx_eq_eps(&self, other: &Rot3<S>, approx_epsilon: &S) -> bool {
        self.mat.approx_eq_eps(&other.mat, approx_epsilon)
    }
}

// Quaternion Rotation impls

impl<S: Float> ToRot3<S> for Quat<S> {
    #[inline]
    fn to_rot3(&self) -> Rot3<S> { Rot3 { mat: self.to_mat3() } }
}

impl<S: Float> ToQuat<S> for Quat<S> {
    #[inline]
    fn to_quat(&self) -> Quat<S> { self.clone() }
}

impl<S: Float> Rotation3<S> for Quat<S> {
    #[inline]
    fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }

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

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

    #[inline]
    fn invert(&self) -> Quat<S> { self.conjugate().div_s(self.magnitude2()) }

    #[inline]
    fn invert_self(&mut self) { *self = self.invert() }
}
<commit_msg>Rename Rot->Basis<commit_after>// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS 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;
use matrix::Matrix;
use matrix::{Mat2, ToMat2};
use matrix::{Mat3, ToMat3};
use point::{Point2, Point3};
use quaternion::{Quat, ToQuat};
use ray::{Ray2, Ray3};
use vector::{Vector, Vec2, Vec3};

/// A two-dimensional rotation
pub trait Rotation2
<
    S
>
:   Eq
+   ApproxEq<S>
+   ToMat2<S>
+   ToBasis2<S>
{
    fn rotate_point2(&self, point: &Point2<S>) -> Point2<S>;
    fn rotate_vec2(&self, vec: &Vec2<S>) -> Vec2<S>;
    fn rotate_ray2(&self, ray: &Ray2<S>) -> Ray2<S>;
    fn concat(&self, other: &Self) -> Self;
    fn concat_self(&mut self, other: &Self);
    fn invert(&self) -> Self;
    fn invert_self(&mut self);
}

/// A three-dimensional rotation
pub trait Rotation3
<
    S
>
:   Eq
+   ApproxEq<S>
+   ToMat3<S>
+   ToBasis3<S>
+   ToQuat<S>
{
    fn rotate_point3(&self, point: &Point3<S>) -> Point3<S>;
    fn rotate_vec3(&self, vec: &Vec3<S>) -> Vec3<S>;
    fn rotate_ray3(&self, ray: &Ray3<S>) -> Ray3<S>;
    fn concat(&self, other: &Self) -> Self;
    fn concat_self(&mut self, other: &Self);
    fn invert(&self) -> Self;
    fn invert_self(&mut self);
}

/// 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::Mat2`. To
/// enforce orthogonality at the type level the operations have been restricted
/// to a subeset of those implemented on `Mat2`.
#[deriving(Eq, Clone)]
pub struct Basis2<S> {
    priv mat: Mat2<S>
}

impl<S: Float> Basis2<S> {
    #[inline]
    pub fn as_mat2<'a>(&'a self) -> &'a Mat2<S> { &'a self.mat }
}

pub trait ToBasis2<S: Float> {
    fn to_rot2(&self) -> Basis2<S>;
}

impl<S: Float> ToBasis2<S> for Basis2<S> {
    #[inline]
    fn to_rot2(&self) -> Basis2<S> { self.clone() }
}

impl<S: Float> ToMat2<S> for Basis2<S> {
    #[inline]
    fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
}

impl<S: Float> Rotation2<S> for Basis2<S> {
    #[inline]
    fn rotate_point2(&self, _point: &Point2<S>) -> Point2<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray2(&self, _ray: &Ray2<S>) -> Ray2<S> { fail!("Not yet implemented") }

    #[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: Float> ApproxEq<S> for Basis2<S> {
    #[inline]
    fn approx_epsilon() -> S {
        // TODO: fix this after static methods are fixed in rustc
        fail!(~"Doesn't work!");
    }

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

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

/// 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::Mat3`. To ensure orthogonality is maintained, the operations have
/// been restricted to a subeset of those implemented on `Mat3`.
#[deriving(Eq, Clone)]
pub struct Basis3<S> {
    priv mat: Mat3<S>
}

impl<S: Float> Basis3<S> {
    #[inline]
    pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::look_at(dir, up) }
    }

    /// Create a rotation matrix from a rotation around the `x` axis (pitch).
    pub fn from_angle_x(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::from_angle_x(theta) }
    }

    /// Create a rotation matrix from a rotation around the `y` axis (yaw).
    pub fn from_angle_y(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::from_angle_y(theta) }
    }

    /// Create a rotation matrix from a rotation around the `z` axis (roll).
    pub fn from_angle_z(theta: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::from_angle_z(theta) }
    }

    /// Create a rotation matrix 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).
    pub fn from_euler(x: Rad<S>, y: Rad<S>, z: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::from_euler(x, y ,z) }
    }

    /// Create a rotation matrix from a rotation around an arbitrary axis.
    pub fn from_axis_angle(axis: &Vec3<S>, angle: Rad<S>) -> Basis3<S> {
        Basis3 { mat: Mat3::from_axis_angle(axis, angle) }
    }

    #[inline]
    pub fn as_mat3<'a>(&'a self) -> &'a Mat3<S> { &'a self.mat }
}

pub trait ToBasis3<S: Float> {
    fn to_rot3(&self) -> Basis3<S>;
}

impl<S: Float> ToBasis3<S> for Basis3<S> {
    #[inline]
    fn to_rot3(&self) -> Basis3<S> { self.clone() }
}

impl<S: Float> ToMat3<S> for Basis3<S> {
    #[inline]
    fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
}

impl<S: Float> ToQuat<S> for Basis3<S> {
    #[inline]
    fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
}

impl<S: Float> Rotation3<S> for Basis3<S> {
    #[inline]
    fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }

    #[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: Float> ApproxEq<S> for Basis3<S> {
    #[inline]
    fn approx_epsilon() -> S {
        // TODO: fix this after static methods are fixed in rustc
        fail!(~"Doesn't work!");
    }

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

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

// Quaternion Rotation impls

impl<S: Float> ToBasis3<S> for Quat<S> {
    #[inline]
    fn to_rot3(&self) -> Basis3<S> { Basis3 { mat: self.to_mat3() } }
}

impl<S: Float> ToQuat<S> for Quat<S> {
    #[inline]
    fn to_quat(&self) -> Quat<S> { self.clone() }
}

impl<S: Float> Rotation3<S> for Quat<S> {
    #[inline]
    fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }

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

    #[inline]
    fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }

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

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

    #[inline]
    fn invert(&self) -> Quat<S> { self.conjugate().div_s(self.magnitude2()) }

    #[inline]
    fn invert_self(&mut self) { *self = self.invert() }
}
<|endoftext|>


<commit_before><commit_msg>interrupt running queries and return to toplevel (#323)<commit_after><|endoftext|>


<commit_before>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).
//!
//! # Examples
//!
//! ```
//! let node: Node = Node:new();
//! let last: Node = node
//!                  .execute(Instruction::Add(Source::Literal(1)))
//!                  .execute(Instruction::Add(Source::ACC));
//! println!("2 times 1 equals {}", last.acc);
//! ```

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug)]
pub struct Node {
    pub acc: i32,
    bac: i32
}

impl PartialEq for Node {
    /// Node are equal when they have the same internal state
    fn eq(&self, other: &Node) -> bool {
        self.acc == other.acc && self.bac == other.bac
    }
}

impl Eq for Node {}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    NIL,
    ACC,
    Literal(i32)
}

/// `Destination` are either ports or registers
pub enum Destination {
    NIL,
    ACC
}

impl Node {
    pub fn new() -> Node {
        Node { acc: 0, bac: 0 }
    }

    pub fn with(acc: i32, bac: i32) -> Node {
        Node { acc: acc, bac: bac }
    }

    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        Node { acc: self.acc, bac: self.bac }
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.move_value(value, destination)
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::ACC => Node { acc: value, bac: self.bac },
            _ => self.nop()
        }
    }

    fn swap(&self) -> Node {
        Node { acc: self.bac, bac: self.acc }
    }

    fn save(&self) -> Node {
        Node { acc: self.acc, bac: self.acc }
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        Node { acc: self.acc + value, bac: self.bac }
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        Node { acc: self.acc - value, bac: self.bac }
    }
}

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

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::MOV(Source::NIL,
                                                        Destination::NIL);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::with(2, 1);
        let instruction: Instruction = Instruction::MOV(Source::ACC,
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(0, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::with(1,0);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 0), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::with(2, 0);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }
}

<commit_msg>Remove document examples<commit_after>//! The Tessellated Intelligence System is a
//!
//! > massively parallel computer architecture comprised of non-uniformly
//! > interconnected heterogeneous nodes.
//!
//! The manual can be found [online](https://www.vidarholen.net/contents/junk/files/TIS-100%20Reference%20Manual.pdf).
//! Another useful resource is the unofficial [TIS-100 Hackers Guide](https://alandesmet.github.io/TIS-100-Hackers-Guide/).

/// A `Node` models the basic execution node in TIS-100. You change a node state
/// by executing an `Instruction` on it.
#[derive(Debug)]
pub struct Node {
    pub acc: i32,
    bac: i32
}

impl PartialEq for Node {
    /// Node are equal when they have the same internal state
    fn eq(&self, other: &Node) -> bool {
        self.acc == other.acc && self.bac == other.bac
    }
}

impl Eq for Node {}

/// `Instruction`s are executed by a `Node`.
pub enum Instruction {
    /// Does nothing
    NOP,
    /// Moves value from `Source` to `Destination`
    MOV(Source, Destination),
    /// Swaps the value of the accumulator (acc) and the backup (bac) register
    SWP,
    /// Saves the value of the accumulator (acc) to the backup register
    SAV,
    /// Add value from `Source` to accumulator (acc), storing result in acc
    ADD(Source),
    /// Subtracts value from `Source` from accumulator (acc), storing result in acc
    SUB(Source),
}

/// `Source` are either ports, registers or literals
pub enum Source {
    NIL,
    ACC,
    Literal(i32)
}

/// `Destination` are either ports or registers
pub enum Destination {
    NIL,
    ACC
}

impl Node {
    pub fn new() -> Node {
        Node { acc: 0, bac: 0 }
    }

    pub fn with(acc: i32, bac: i32) -> Node {
        Node { acc: acc, bac: bac }
    }

    pub fn execute(&self, instruction: Instruction) -> Node {
        match instruction {
            Instruction::NOP => self.nop(),
            Instruction::MOV(source, destination) => self.mov(source, destination) ,
            Instruction::SWP => self.swap(),
            Instruction::SAV => self.save(),
            Instruction::ADD(source) => self.add(source),
            Instruction::SUB(source) => self.subtract(source),
        }
    }

    fn nop(&self) -> Node {
        Node { acc: self.acc, bac: self.bac }
    }

    fn mov(&self, source: Source, destination: Destination) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.move_value(value, destination)
    }

    fn move_value(&self, value: i32, destination: Destination) -> Node {
        match destination {
            Destination::ACC => Node { acc: value, bac: self.bac },
            _ => self.nop()
        }
    }

    fn swap(&self) -> Node {
        Node { acc: self.bac, bac: self.acc }
    }

    fn save(&self) -> Node {
        Node { acc: self.acc, bac: self.acc }
    }

    fn add(&self, source: Source) -> Node{
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.add_value(value)
    }

    fn add_value(&self, value: i32) -> Node {
        Node { acc: self.acc + value, bac: self.bac }
    }

    fn subtract(&self, source: Source) -> Node {
        let value: i32 = match source {
            Source::NIL => 0,
            Source::ACC => self.acc,
            Source::Literal(value) => value
        };

        self.subtract_value(value)
    }

    fn subtract_value(&self, value: i32) -> Node {
        Node { acc: self.acc - value, bac: self.bac }
    }
}

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

    #[test]
    fn node_should_start_with_accumulator_zero() {
        let node: Node = Node::new();

        assert_eq!(0, node.acc);
    }

    #[test]
    fn node_should_start_with_backup_zero() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(0, next.acc);
    }

    #[test]
    fn node_should_execute_NOP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::NOP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_NIL_to_NIL_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::MOV(Source::NIL,
                                                        Destination::NIL);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_MOV_from_ACC_to_ACC_correctly() {
        let node: Node = Node::with(2, 1);
        let instruction: Instruction = Instruction::MOV(Source::ACC,
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 1), next);
    }

    #[test]
    fn node_should_execute_MOV_from_Literal_to_ACC_correctly() {
        let node: Node = Node::new();
        let instruction: Instruction = Instruction::MOV(Source::Literal(1),
                                                        Destination::ACC);

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }

    #[test]
    fn node_should_execute_SWP_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::SWP;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(0, 1), next);
    }

    #[test]
    fn node_should_execute_SAV_correctly() {
        let node: Node = Node::with(1,0);
        let instruction: Instruction = Instruction::SAV;

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 1), next);
    }

    #[test]
    fn node_should_execute_ADD_from_Literal_correctly() {
        let node: Node = Node::with(1, 0);
        let instruction: Instruction = Instruction::ADD(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(2, 0), next);
    }

    #[test]
    fn node_should_execute_SUB_from_Literal_correctly() {
        let node: Node = Node::with(2, 0);
        let instruction: Instruction = Instruction::SUB(Source::Literal(1));

        let next: Node = node.execute(instruction);

        assert_eq!(Node::with(1, 0), next);
    }
}

<|endoftext|>


<commit_before>use libloading;
use sputnikvm::{SputnikVM};
use serde_json::{Value, Error};
use std::io::{BufReader, Write, stdout};

pub fn test_ffi_transaction(name: &str, v: &Value, debug: bool, sputnikvm_path: &str) {
    let mut ffi = FFI(libloading::Library::new(sputnikvm_path).unwrap_or_else(|error| panic!("{}",error)));
    println!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let svm = ffi.sputnikvm_new(v);
    // ffi.sputnikvm_free(svm);
}

struct FFI(libloading::Library);

impl FFI {
    fn sputnikvm_new(&self, v: &Value) {
        unsafe {
            let f = self.0.get::<fn(v: &Value)> (
                b"sputnikvm_new\0"
            ).unwrap();
            f(v)
        }
    }
    fn sputnikvm_free(&self, svm: *mut SputnikVM) {
        unsafe {
            let f = self.0.get::<fn(svm: *mut SputnikVM)> (
                b"sputnikvm_free\0"
            ).unwrap();
            f(svm)
        }
    }
}
<commit_msg>Problem: vm wasn't firing<commit_after>use libloading;
use sputnikvm::{SputnikVM};
use serde_json::{Value, Error};
use std::io::{BufReader, Write, stdout};

pub fn test_ffi_transaction(name: &str, v: &Value, debug: bool, sputnikvm_path: &str) {
    let mut ffi = FFI(libloading::Library::new(sputnikvm_path).unwrap_or_else(|error| panic!("{}",error)));
    println!("Testing {} ... ", name);
    if debug {
        print!("\n");
    }
    stdout().flush();

    let svm = ffi.sputnikvm_new(v);
    ffi.sputnikvm_fire(svm);
    ffi.sputnikvm_free(svm);
}

struct FFI(libloading::Library);

impl FFI {
    fn sputnikvm_new(&self, v: &Value) -> *mut SputnikVM {
        unsafe {
            let f = self.0.get::<fn(v: &Value) -> *mut SputnikVM > (
                b"sputnikvm_new\0"
            ).unwrap();
            f(v)
        }
    }
    fn sputnikvm_fire(&self, svm: *mut SputnikVM) {
        unsafe {
            let f = self.0.get::<fn(svm: *mut SputnikVM)> (
                b"sputnikvm_fire\0"
            ).unwrap();
            f(svm)
        }
    }
    fn sputnikvm_free(&self, svm: *mut SputnikVM) {
        unsafe {
            let f = self.0.get::<fn(svm: *mut SputnikVM)> (
                b"sputnikvm_free\0"
            ).unwrap();
            f(svm)
        }
    }
}
<|endoftext|>


<commit_before>use nom::multispace;
use std::str;
use std::fmt;

use common::{opt_multispace, statement_terminator};
use select::{limit_clause, nested_selection, LimitClause, SelectStatement};
use order::{order_clause, OrderClause};

#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
pub enum CompoundSelectOperator {
    Union,
    DistinctUnion,
    Intersect,
    Except,
}

impl fmt::Display for CompoundSelectOperator {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CompoundSelectOperator::Union => write!(f, "UNION"),
            CompoundSelectOperator::DistinctUnion => write!(f, "UNION DISTINCT"),
            CompoundSelectOperator::Intersect => write!(f, "INTERSECT"),
            CompoundSelectOperator::Except => write!(f, "EXCEPT"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
pub struct CompoundSelectStatement {
    pub selects: Vec<(Option<CompoundSelectOperator>, SelectStatement)>,
    pub order: Option<OrderClause>,
    pub limit: Option<LimitClause>,
}

impl fmt::Display for CompoundSelectStatement {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for (ref op, ref sel) in &self.selects {
            write!(f, " {}", sel)?;
            if op.is_some() {
                write!(f, " {}", op.as_ref().unwrap())?;
            }
        }
        if self.order.is_some() {
            write!(f, " {}", self.order.as_ref().unwrap())?;
        }
        if self.limit.is_some() {
            write!(f, " {}", self.order.as_ref().unwrap())?;
        }
        Ok(())
    }
}

/// Parse compound operator
named!(compound_op<&[u8], CompoundSelectOperator>,
    alt_complete!(
          do_parse!(
              tag_no_case!("union") >>
              distinct: opt!(
                  preceded!(multispace,
                            alt_complete!(  map!(tag_no_case!("all"), |_| { false })
                                          | map!(tag_no_case!("distinct"), |_| { true }))
                            )) >>
              (match distinct {
                  // DISTINCT is the default in both MySQL and SQLite
                  None => CompoundSelectOperator::DistinctUnion,
                  Some(d) => {
                      if d {
                          CompoundSelectOperator::DistinctUnion
                      } else {
                          CompoundSelectOperator::Union
                      }
                  },
              })
          )
        | map!(tag_no_case!("intersect"), |_| CompoundSelectOperator::Intersect)
        | map!(tag_no_case!("except"), |_| CompoundSelectOperator::Except)
    )
);

/// Parse compound selection
named!(pub compound_selection<&[u8], CompoundSelectStatement>,
    complete!(do_parse!(
        first_select: delimited!(opt!(tag!("(")), nested_selection, opt!(tag!(")"))) >>
        other_selects: many1!(
            complete!(
                do_parse!(opt_multispace >>
                       op: compound_op >>
                       multispace >>
                       opt!(tag!("(")) >>
                       opt_multispace >>
                       select: nested_selection >>
                       opt_multispace >>
                       opt!(tag!(")")) >>
                       (Some(op), select)
                )
            )
        ) >>
        opt_multispace >>
        order: opt!(order_clause) >>
        limit: opt!(limit_clause) >>
        statement_terminator >>
        ({
            let mut v = vec![(None, first_select)];
            v.extend(other_selects);

            CompoundSelectStatement {
                selects: v,
                order: order,
                limit: limit,
            }
        })
    ))
);

#[cfg(test)]
mod tests {
    use super::*;
    use column::Column;
    use common::{FieldDefinitionExpression, FieldValueExpression, Literal};
    use table::Table;

    #[test]
    fn union() {
        let qstr = "SELECT id, 1 FROM Vote UNION SELECT id, stars from Rating;";
        let qstr2 = "(SELECT id, 1 FROM Vote) UNION (SELECT id, stars from Rating);";
        let res = compound_selection(qstr.as_bytes());
        let res2 = compound_selection(qstr2.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::DistinctUnion), second_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
        assert_eq!(res2.unwrap().1, expected);
    }

    #[test]
    fn multi_union() {
        let qstr = "SELECT id, 1 FROM Vote \
                    UNION SELECT id, stars from Rating \
                    UNION DISTINCT SELECT 42, 5 FROM Vote;";
        let res = compound_selection(qstr.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let third_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(42).into(),
                )),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(5).into(),
                )),
            ],
            ..Default::default()
        };

        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::DistinctUnion), second_select),
                (Some(CompoundSelectOperator::DistinctUnion), third_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
    }

    #[test]
    fn union_all() {
        let qstr = "SELECT id, 1 FROM Vote UNION ALL SELECT id, stars from Rating;";
        let res = compound_selection(qstr.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::Union), second_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
    }
}
<commit_msg>Print compound selections correctly<commit_after>use nom::multispace;
use std::str;
use std::fmt;

use common::{opt_multispace, statement_terminator};
use select::{limit_clause, nested_selection, LimitClause, SelectStatement};
use order::{order_clause, OrderClause};

#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
pub enum CompoundSelectOperator {
    Union,
    DistinctUnion,
    Intersect,
    Except,
}

impl fmt::Display for CompoundSelectOperator {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CompoundSelectOperator::Union => write!(f, "UNION"),
            CompoundSelectOperator::DistinctUnion => write!(f, "UNION DISTINCT"),
            CompoundSelectOperator::Intersect => write!(f, "INTERSECT"),
            CompoundSelectOperator::Except => write!(f, "EXCEPT"),
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
pub struct CompoundSelectStatement {
    pub selects: Vec<(Option<CompoundSelectOperator>, SelectStatement)>,
    pub order: Option<OrderClause>,
    pub limit: Option<LimitClause>,
}

impl fmt::Display for CompoundSelectStatement {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for (ref op, ref sel) in &self.selects {
            if op.is_some() {
                write!(f, " {}", op.as_ref().unwrap())?;
            }
            write!(f, " {}", sel)?;
        }
        if self.order.is_some() {
            write!(f, " {}", self.order.as_ref().unwrap())?;
        }
        if self.limit.is_some() {
            write!(f, " {}", self.order.as_ref().unwrap())?;
        }
        Ok(())
    }
}

/// Parse compound operator
named!(compound_op<&[u8], CompoundSelectOperator>,
    alt_complete!(
          do_parse!(
              tag_no_case!("union") >>
              distinct: opt!(
                  preceded!(multispace,
                            alt_complete!(  map!(tag_no_case!("all"), |_| { false })
                                          | map!(tag_no_case!("distinct"), |_| { true }))
                            )) >>
              (match distinct {
                  // DISTINCT is the default in both MySQL and SQLite
                  None => CompoundSelectOperator::DistinctUnion,
                  Some(d) => {
                      if d {
                          CompoundSelectOperator::DistinctUnion
                      } else {
                          CompoundSelectOperator::Union
                      }
                  },
              })
          )
        | map!(tag_no_case!("intersect"), |_| CompoundSelectOperator::Intersect)
        | map!(tag_no_case!("except"), |_| CompoundSelectOperator::Except)
    )
);

/// Parse compound selection
named!(pub compound_selection<&[u8], CompoundSelectStatement>,
    complete!(do_parse!(
        first_select: delimited!(opt!(tag!("(")), nested_selection, opt!(tag!(")"))) >>
        other_selects: many1!(
            complete!(
                do_parse!(opt_multispace >>
                       op: compound_op >>
                       multispace >>
                       opt!(tag!("(")) >>
                       opt_multispace >>
                       select: nested_selection >>
                       opt_multispace >>
                       opt!(tag!(")")) >>
                       (Some(op), select)
                )
            )
        ) >>
        opt_multispace >>
        order: opt!(order_clause) >>
        limit: opt!(limit_clause) >>
        statement_terminator >>
        ({
            let mut v = vec![(None, first_select)];
            v.extend(other_selects);

            CompoundSelectStatement {
                selects: v,
                order: order,
                limit: limit,
            }
        })
    ))
);

#[cfg(test)]
mod tests {
    use super::*;
    use column::Column;
    use common::{FieldDefinitionExpression, FieldValueExpression, Literal};
    use table::Table;

    #[test]
    fn union() {
        let qstr = "SELECT id, 1 FROM Vote UNION SELECT id, stars from Rating;";
        let qstr2 = "(SELECT id, 1 FROM Vote) UNION (SELECT id, stars from Rating);";
        let res = compound_selection(qstr.as_bytes());
        let res2 = compound_selection(qstr2.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::DistinctUnion), second_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
        assert_eq!(res2.unwrap().1, expected);
    }

    #[test]
    fn multi_union() {
        let qstr = "SELECT id, 1 FROM Vote \
                    UNION SELECT id, stars from Rating \
                    UNION DISTINCT SELECT 42, 5 FROM Vote;";
        let res = compound_selection(qstr.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let third_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(42).into(),
                )),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(5).into(),
                )),
            ],
            ..Default::default()
        };

        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::DistinctUnion), second_select),
                (Some(CompoundSelectOperator::DistinctUnion), third_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
    }

    #[test]
    fn union_all() {
        let qstr = "SELECT id, 1 FROM Vote UNION ALL SELECT id, stars from Rating;";
        let res = compound_selection(qstr.as_bytes());

        let first_select = SelectStatement {
            tables: vec![Table::from("Vote")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Value(FieldValueExpression::Literal(
                    Literal::Integer(1).into(),
                )),
            ],
            ..Default::default()
        };
        let second_select = SelectStatement {
            tables: vec![Table::from("Rating")],
            fields: vec![
                FieldDefinitionExpression::Col(Column::from("id")),
                FieldDefinitionExpression::Col(Column::from("stars")),
            ],
            ..Default::default()
        };
        let expected = CompoundSelectStatement {
            selects: vec![
                (None, first_select),
                (Some(CompoundSelectOperator::Union), second_select),
            ],
            order: None,
            limit: None,
        };

        assert_eq!(res.unwrap().1, expected);
    }
}
<|endoftext|>


<commit_before>use crate::locales::Data;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub struct JA_JP;

impl Data for JA_JP {
    const NAME_FIRST_NAME: &'static [&'static str] = &[
        "あかり",
        "いろは",
        "さくら",
        "すず",
        "すみれ",
        "はな",
        "ひかり",
        "ひまり",
        "一翔",
        "一花",
        "一華",
        "一颯",
        "七海",
        "丈",
        "乃愛",
        "仁",
        "伊織",
        "依茉",
        "健",
        "健人",
        "健斗",
        "優",
        "優月",
        "光",
        "光希",
        "光莉",
        "凛",
        "凜",
        "凪",
        "匠",
        "匠海",
        "千愛",
        "千晴",
        "和",
        "和奏",
        "和花",
        "咲",
        "咲希",
        "咲来",
        "咲良",
        "咲茉",
        "啓太",
        "圭",
        "壮真",
        "大和",
        "大晴",
        "大智",
        "大知",
        "大翔",
        "大誠",
        "太陽",
        "奏",
        "奏多",
        "奏太",
        "奏斗",
        "奏汰",
        "実桜",
        "尊",
        "岳",
        "彩心",
        "彩葉",
        "律",
        "心",
        "心咲",
        "心春",
        "心結",
        "心陽",
        "心音",
        "怜",
        "悠",
        "悠人",
        "悠仁",
        "悠斗",
        "悠生",
        "悠真",
        "悠翔",
        "愛",
        "愛莉",
        "愛菜",
        "慧",
        "慶",
        "文乃",
        "新",
        "新太",
        "旭",
        "明莉",
        "晴",
        "晴大",
        "晴斗",
        "晴翔",
        "暖",
        "朔",
        "朝陽",
        "未来",
        "朱莉",
        "杏",
        "杏奈",
        "柚乃",
        "柚希",
        "柚月",
        "柚葉",
        "栞",
        "栞奈",
        "桔平",
        "桜",
        "楓",
        "樹",
        "櫂",
        "海斗",
        "海翔",
        "涼太",
        "湊",
        "湊介",
        "湊士",
        "湊大",
        "湊斗",
        "湊翔",
        "潤",
        "澪",
        "煌",
        "煌大",
        "玲奈",
        "理仁",
        "琉生",
        "琴葉",
        "琴音",
        "瑛太",
        "瑛斗",
        "瑛翔",
        "百花",
        "碧",
        "碧人",
        "碧斗",
        "空",
        "紗奈",
        "紗良",
        "紗菜",
        "紬",
        "紬希",
        "紬葵",
        "結",
        "結人",
        "結愛",
        "結斗",
        "結月",
        "結翔",
        "結菜",
        "結衣",
        "結香",
        "絢斗",
        "綾乃",
        "綾人",
        "美優",
        "美月",
        "美桜",
        "美波",
        "美海",
        "美結",
        "美緒",
        "美羽",
        "翔",
        "翼",
        "航",
        "花",
        "花音",
        "芽依",
        "芽生",
        "芽衣",
        "莉央",
        "莉子",
        "莉愛",
        "莉緒",
        "菫",
        "華",
        "葵",
        "蒼",
        "蒼人",
        "蒼士",
        "蒼大",
        "蒼太",
        "蒼生",
        "蒼空",
        "蒼翔",
        "蓮",
        "蘭",
        "詩",
        "詩織",
        "迅",
        "遥斗",
        "陸",
        "陸斗",
        "陽",
        "陽向",
        "陽咲",
        "陽大",
        "陽太",
        "陽斗",
        "陽翔",
        "陽菜",
        "陽菜乃",
        "陽葵",
        "風花",
        "颯",
        "颯人",
        "颯太",
        "颯斗",
        "颯汰",
        "颯真",
    ];
    const NAME_LAST_NAME: &'static [&'static str] = &[
        "佐藤",
        "鈴木",
        "高橋",
        "田中",
        "伊藤",
        "山本",
        "渡辺",
        "中村",
        "小林",
        "加藤",
        "吉田",
        "山田",
        "佐々木",
        "山口",
        "松本",
        "井上",
        "木村",
        "林",
        "斎藤",
        "清水",
        "山崎",
        "阿部",
        "森",
        "池田",
        "橋本",
        "山下",
        "石川",
        "中島",
        "前田",
        "藤田",
        "後藤",
        "小川",
        "岡田",
        "村上",
        "長谷川",
        "近藤",
        "石井",
        "斉藤",
        "坂本",
        "遠藤",
        "藤井",
        "青木",
        "福田",
        "三浦",
        "西村",
        "藤原",
        "太田",
        "松田",
        "原田",
        "岡本",
        "中野",
        "中川",
        "小野",
        "田村",
        "竹内",
        "金子",
        "中山",
        "和田",
        "石田",
        "工藤",
        "上田",
        "原",
        "森田",
        "酒井",
        "横山",
        "柴田",
        "宮崎",
        "宮本",
        "内田",
        "高木",
        "谷口",
        "安藤",
        "丸山",
        "今井",
        "大野",
        "高田",
        "菅原",
        "河野",
        "武田",
        "藤本",
        "上野",
        "杉山",
        "千葉",
        "村田",
        "増田",
        "小島",
        "小山",
        "大塚",
        "平野",
        "久保",
        "渡部",
        "松井",
        "菊地",
        "岩崎",
        "松尾",
        "佐野",
        "木下",
        "野口",
        "野村",
        "新井",
    ];
    const NAME_TITLE: &'static [&'static str] = &["様"];
    const NAME_TPL: &'static str = &"{LastName} {FirstName}";
    const NAME_WITH_TITLE_TPL: &'static str = &"{LastName}{FirstName}{Title}";

    const JOB_SENIORITY: &'static [&'static str] = &[
        "リード",
        "シニア",
        "ジュニア",
        "コーポレート",
        "ナショナル",
        "地域",
        "区域",
        "中央",
        "グローバル",
        "国際",
        "チーフ",
        "主席",
    ];
    const JOB_FIELD: &'static [&'static str] = &[
        "マーケティング",
        "IT",
        "会計",
        "管理",
        "広告",
        "銀行",
        "社会奉仕",
        "建設",
        "コンサルティング",
        "デザイン",
        "教育",
        "農業",
        "政府",
        "ヘルスケア",
        "ホスピタリティ",
        "法務",
        "製造",
        "鉱業",
        "不動産",
        "リテール",
        "営業",
        "テクノロジー",
    ];
    const JOB_POSITION: &'static [&'static str] = &[
        "スーパーバイザー",
        "アソシエイト",
        "エグゼクティブ",
        "オフィサー",
        "マネージャー",
        "エンジニア",
        "スペシャリスト",
        "ディレクター",
        "コーディネーター",
        "管理者",
        "アーキテクト",
        "アナリスト",
        "デザイナー",
        "プランナー",
        "オーケストレーター",
        "テクニシャン",
        "デベロッパー",
        "プロデューサー",
        "コンサルタント",
        "アシスタント",
        "ファシリテーター",
        "エージェント",
        "代表",
        "ストラテジスト",
    ];
    const JOB_TITLE_TPL: &'static str = &"{Seniority}{Field}{Position}";
}
<commit_msg>Support japanese company names<commit_after>use crate::locales::Data;

#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub struct JA_JP;

impl Data for JA_JP {
    const NAME_FIRST_NAME: &'static [&'static str] = &[
        "あかり",
        "いろは",
        "さくら",
        "すず",
        "すみれ",
        "はな",
        "ひかり",
        "ひまり",
        "一翔",
        "一花",
        "一華",
        "一颯",
        "七海",
        "丈",
        "乃愛",
        "仁",
        "伊織",
        "依茉",
        "健",
        "健人",
        "健斗",
        "優",
        "優月",
        "光",
        "光希",
        "光莉",
        "凛",
        "凜",
        "凪",
        "匠",
        "匠海",
        "千愛",
        "千晴",
        "和",
        "和奏",
        "和花",
        "咲",
        "咲希",
        "咲来",
        "咲良",
        "咲茉",
        "啓太",
        "圭",
        "壮真",
        "大和",
        "大晴",
        "大智",
        "大知",
        "大翔",
        "大誠",
        "太陽",
        "奏",
        "奏多",
        "奏太",
        "奏斗",
        "奏汰",
        "実桜",
        "尊",
        "岳",
        "彩心",
        "彩葉",
        "律",
        "心",
        "心咲",
        "心春",
        "心結",
        "心陽",
        "心音",
        "怜",
        "悠",
        "悠人",
        "悠仁",
        "悠斗",
        "悠生",
        "悠真",
        "悠翔",
        "愛",
        "愛莉",
        "愛菜",
        "慧",
        "慶",
        "文乃",
        "新",
        "新太",
        "旭",
        "明莉",
        "晴",
        "晴大",
        "晴斗",
        "晴翔",
        "暖",
        "朔",
        "朝陽",
        "未来",
        "朱莉",
        "杏",
        "杏奈",
        "柚乃",
        "柚希",
        "柚月",
        "柚葉",
        "栞",
        "栞奈",
        "桔平",
        "桜",
        "楓",
        "樹",
        "櫂",
        "海斗",
        "海翔",
        "涼太",
        "湊",
        "湊介",
        "湊士",
        "湊大",
        "湊斗",
        "湊翔",
        "潤",
        "澪",
        "煌",
        "煌大",
        "玲奈",
        "理仁",
        "琉生",
        "琴葉",
        "琴音",
        "瑛太",
        "瑛斗",
        "瑛翔",
        "百花",
        "碧",
        "碧人",
        "碧斗",
        "空",
        "紗奈",
        "紗良",
        "紗菜",
        "紬",
        "紬希",
        "紬葵",
        "結",
        "結人",
        "結愛",
        "結斗",
        "結月",
        "結翔",
        "結菜",
        "結衣",
        "結香",
        "絢斗",
        "綾乃",
        "綾人",
        "美優",
        "美月",
        "美桜",
        "美波",
        "美海",
        "美結",
        "美緒",
        "美羽",
        "翔",
        "翼",
        "航",
        "花",
        "花音",
        "芽依",
        "芽生",
        "芽衣",
        "莉央",
        "莉子",
        "莉愛",
        "莉緒",
        "菫",
        "華",
        "葵",
        "蒼",
        "蒼人",
        "蒼士",
        "蒼大",
        "蒼太",
        "蒼生",
        "蒼空",
        "蒼翔",
        "蓮",
        "蘭",
        "詩",
        "詩織",
        "迅",
        "遥斗",
        "陸",
        "陸斗",
        "陽",
        "陽向",
        "陽咲",
        "陽大",
        "陽太",
        "陽斗",
        "陽翔",
        "陽菜",
        "陽菜乃",
        "陽葵",
        "風花",
        "颯",
        "颯人",
        "颯太",
        "颯斗",
        "颯汰",
        "颯真",
    ];
    const NAME_LAST_NAME: &'static [&'static str] = &[
        "佐藤",
        "鈴木",
        "高橋",
        "田中",
        "伊藤",
        "山本",
        "渡辺",
        "中村",
        "小林",
        "加藤",
        "吉田",
        "山田",
        "佐々木",
        "山口",
        "松本",
        "井上",
        "木村",
        "林",
        "斎藤",
        "清水",
        "山崎",
        "阿部",
        "森",
        "池田",
        "橋本",
        "山下",
        "石川",
        "中島",
        "前田",
        "藤田",
        "後藤",
        "小川",
        "岡田",
        "村上",
        "長谷川",
        "近藤",
        "石井",
        "斉藤",
        "坂本",
        "遠藤",
        "藤井",
        "青木",
        "福田",
        "三浦",
        "西村",
        "藤原",
        "太田",
        "松田",
        "原田",
        "岡本",
        "中野",
        "中川",
        "小野",
        "田村",
        "竹内",
        "金子",
        "中山",
        "和田",
        "石田",
        "工藤",
        "上田",
        "原",
        "森田",
        "酒井",
        "横山",
        "柴田",
        "宮崎",
        "宮本",
        "内田",
        "高木",
        "谷口",
        "安藤",
        "丸山",
        "今井",
        "大野",
        "高田",
        "菅原",
        "河野",
        "武田",
        "藤本",
        "上野",
        "杉山",
        "千葉",
        "村田",
        "増田",
        "小島",
        "小山",
        "大塚",
        "平野",
        "久保",
        "渡部",
        "松井",
        "菊地",
        "岩崎",
        "松尾",
        "佐野",
        "木下",
        "野口",
        "野村",
        "新井",
    ];
    const NAME_TITLE: &'static [&'static str] = &["様"];
    const NAME_TPL: &'static str = &"{LastName} {FirstName}";
    const NAME_WITH_TITLE_TPL: &'static str = &"{LastName}{FirstName}{Title}";

    const JOB_SENIORITY: &'static [&'static str] = &[
        "リード",
        "シニア",
        "ジュニア",
        "コーポレート",
        "ナショナル",
        "地域",
        "区域",
        "中央",
        "グローバル",
        "国際",
        "チーフ",
        "主席",
    ];
    const JOB_FIELD: &'static [&'static str] = &[
        "マーケティング",
        "IT",
        "会計",
        "管理",
        "広告",
        "銀行",
        "社会奉仕",
        "建設",
        "コンサルティング",
        "デザイン",
        "教育",
        "農業",
        "政府",
        "ヘルスケア",
        "ホスピタリティ",
        "法務",
        "製造",
        "鉱業",
        "不動産",
        "リテール",
        "営業",
        "テクノロジー",
    ];
    const JOB_POSITION: &'static [&'static str] = &[
        "スーパーバイザー",
        "アソシエイト",
        "エグゼクティブ",
        "オフィサー",
        "マネージャー",
        "エンジニア",
        "スペシャリスト",
        "ディレクター",
        "コーディネーター",
        "管理者",
        "アーキテクト",
        "アナリスト",
        "デザイナー",
        "プランナー",
        "オーケストレーター",
        "テクニシャン",
        "デベロッパー",
        "プロデューサー",
        "コンサルタント",
        "アシスタント",
        "ファシリテーター",
        "エージェント",
        "代表",
        "ストラテジスト",
    ];
    const JOB_TITLE_TPL: &'static str = &"{Seniority}{Field}{Position}";

    const COMPANY_SUFFIX: &'static [&'static str] = &["株式会社", "(株)", "有限会社", "(有)"];
    const COMPANY_NAME_TPLS: &'static [&'static str] = &["{Name_1} {Suffix}", "{Suffix} {Name_1}"];
}
<|endoftext|>


<commit_before>#![feature(test)]

#[macro_use]
extern crate clap;
extern crate test;

use clap::{App, Arg, SubCommand};

use test::Bencher;

static ARGS: &'static str = "-o --option=[opt]... 'tests options'
                             [positional] 'tests positionals'";
static OPT3_VALS: [&'static str; 2] = ["fast", "slow"];
static POS3_VALS: [&'static str; 2] = ["vi", "emacs"];

macro_rules! create_app {
    () => ({
        App::new("claptests")
                .version("0.1")
                .about("tests clap library")
                .author("Kevin K. <kbknapp@gmail.com>")
                .args_from_usage(ARGS)
                .arg(Arg::from_usage("-f --flag... 'tests flags'")
                             .global(true))
                .args(&[
                          Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
                          Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
                          Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
                          Arg::from_usage("-O --Option [option3] 'tests options with specific value sets'").possible_values(&OPT3_VALS),
                          Arg::from_usage("[positional3]... 'tests positionals with specific values'").possible_values(&POS3_VALS),
                          Arg::from_usage("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
                          Arg::from_usage("--multvalsmo... [one] [two] 'Tests mutliple values, not mult occs'"),
                          Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
                          Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
                    ])
                .subcommand(SubCommand::with_name("subcmd")
                                        .about("tests subcommands")
                                        .version("0.1")
                                        .author("Kevin K. <kbknapp@gmail.com>")
                                        .arg_from_usage("-o --option [scoption]... 'tests options'")
                                        .arg_from_usage("[scpositional] 'tests positionals'"))
    })
}

#[bench]
fn create_app_from_usage(b: &mut Bencher) {

    b.iter(|| create_app!());
}

#[bench]
fn create_app_builder(b: &mut Bencher) {
    b.iter(|| {
        App::new("claptests")
                .version("0.1")
                .about("tests clap library")
                .author("Kevin K. <kbknapp@gmail.com>")
                .arg(Arg::with_name("opt")
                    .help("tests options")
                    .short("o")
                    .long("option")
                    .takes_value(true)
                    .multiple(true))
                .arg(Arg::with_name("positional")
                    .help("tests positionals")
                    .index(1))
                .arg(Arg::with_name("flag")
                     .short("f")
                     .help("tests flags")
                     .long("flag")
                     .multiple(true)
                     .global(true))
                .arg(Arg::with_name("flag2")
                    .short("F")
                    .help("tests flags with exclusions")
                    .conflicts_with("flag")
                    .requires("option2"))
                .arg(Arg::with_name("option2")
                    .help("tests long options with exclusions")
                    .conflicts_with("option")
                    .requires("positional2")
                    .takes_value(true)
                    .long("long-option-2"))
                .arg(Arg::with_name("positional2")
                    .index(3)
                    .help("tests positionals with exclusions"))
                .arg(Arg::with_name("option3")
                    .short("O")
                    .long("Option")
                    .takes_value(true)
                    .help("tests options with specific value sets")
                    .possible_values(&OPT3_VALS))
                .arg(Arg::with_name("positional3")
                    .multiple(true)
                    .help("tests positionals with specific values")
                    .index(4)
                    .possible_values(&POS3_VALS))
                .arg(Arg::with_name("multvals")
                    .long("multvals")
                    .takes_value(true)
                    .help("Tests mutliple values, not mult occs")
                    .value_names(&["one", "two"]))
                .arg(Arg::with_name("multvalsmo")
                    .long("multvalsmo")
                    .takes_value(true)
                    .multiple(true)
                    .help("Tests mutliple values, not mult occs")
                    .value_names(&["one", "two"]))
                .arg(Arg::with_name("minvals")
                    .long("minvals2")
                    .multiple(true)
                    .takes_value(true)
                    .help("Tests 2 min vals")
                    .min_values(2))
                .arg(Arg::with_name("maxvals")
                    .long("maxvals3")
                    .takes_value(true)
                    .multiple(true)
                    .help("Tests 3 max vals")
                    .max_values(3))
                .subcommand(SubCommand::with_name("subcmd")
                    .about("tests subcommands")
                    .version("0.1")
                    .author("Kevin K. <kbknapp@gmail.com>")
                    .arg(Arg::with_name("scoption")
                        .short("o")
                        .long("option")
                        .multiple(true)
                        .takes_value(true)
                        .help("tests options"))
                    .arg(Arg::with_name("scpositional")
                        .index(1)
                        .help("tests positionals")));
    });
}

#[bench]
fn create_app_macros(b: &mut Bencher) {
    b.iter(|| {
        clap_app!(claptests =>
                (version: "0.1")
                (about: "tests clap library")
                (author: "Kevin K. <kbknapp@gmail.com>")
                (@arg opt: -o --option +takes_value ... "tests options")
                (@arg positional: index(1) "tests positionals")
                (@arg flag: -f --flag ... +global "tests flags")
                (@arg flag2: -F conflicts_with[flag] requires[option2]
                    "tests flags with exclusions")
                (@arg option2: --long_option_2 conflicts_with[option] requires[positional2]
                    "tests long options with exclusions")
                (@arg positional2: index(2) "tests positionals with exclusions")
                (@arg option3: -O --Option +takes_value possible_value[fast slow]
                    "tests options with specific value sets")
                (@arg positional3: index(3) ... possible_value[vi emacs]
                    "tests positionals with specific values")
                (@arg multvals: --multvals +takes_value value_name[one two]
                    "Tests mutliple values, not mult occs")
                (@arg multvalsmo: --multvalsmo ... +takes_value value_name[one two]
                    "Tests mutliple values, not mult occs")
                (@arg minvals: --minvals2 min_values(1) ... +takes_value "Tests 2 min vals")
                (@arg maxvals: --maxvals3 ... +takes_value max_values(3) "Tests 3 max vals")
                (@subcommand subcmd =>
                    (about: "tests subcommands")
                    (version: "0.1")
                    (author: "Kevin K. <kbknapp@gmail.com>")
                    (@arg scoption: -o --option ... +takes_value "tests options")
                    (@arg scpositional: index(1) "tests positionals"))
        );
    });
}

#[bench]
fn parse_clean(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec![""]));
}

#[bench]
fn parse_flag(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"]));
}

#[bench]
fn parse_option(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-o", "option1"]));
}

#[bench]
fn parse_positional(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1"]));
}

#[bench]
fn parse_sc_clean(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd"]));
}

#[bench]
fn parse_sc_flag(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f"]));
}

#[bench]
fn parse_sc_option(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-o", "option1"]));
}

#[bench]
fn parse_sc_positional(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "arg1"]));
}

#[bench]
fn parse_complex1(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-ff", "-o", "option1", "arg1", "-O", "fast", "arg2", "--multvals", "one", "two", "emacs"]));
}

#[bench]
fn parse_complex2(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
}

#[bench]
fn parse_sc_complex(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"]));
}
<commit_msg>bench: adds a bench with short circuiting some calls via ArgsNegateSubcommands<commit_after>#![feature(test)]

#[macro_use]
extern crate clap;
extern crate test;

use clap::{App, Arg, SubCommand, AppSettings};

use test::Bencher;

static ARGS: &'static str = "-o --option=[opt]... 'tests options'
                             [positional] 'tests positionals'";
static OPT3_VALS: [&'static str; 2] = ["fast", "slow"];
static POS3_VALS: [&'static str; 2] = ["vi", "emacs"];

macro_rules! create_app {
    () => ({
        App::new("claptests")
                .version("0.1")
                .about("tests clap library")
                .author("Kevin K. <kbknapp@gmail.com>")
                .args_from_usage(ARGS)
                .arg(Arg::from_usage("-f --flag... 'tests flags'")
                             .global(true))
                .args(&[
                          Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
                          Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
                          Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
                          Arg::from_usage("-O --Option [option3] 'tests options with specific value sets'").possible_values(&OPT3_VALS),
                          Arg::from_usage("[positional3]... 'tests positionals with specific values'").possible_values(&POS3_VALS),
                          Arg::from_usage("--multvals [one] [two] 'Tests mutliple values, not mult occs'"),
                          Arg::from_usage("--multvalsmo... [one] [two] 'Tests mutliple values, not mult occs'"),
                          Arg::from_usage("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
                          Arg::from_usage("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3)
                    ])
                .subcommand(SubCommand::with_name("subcmd")
                                        .about("tests subcommands")
                                        .version("0.1")
                                        .author("Kevin K. <kbknapp@gmail.com>")
                                        .arg_from_usage("-o --option [scoption]... 'tests options'")
                                        .arg_from_usage("[scpositional] 'tests positionals'"))
    })
}

#[bench]
fn create_app_from_usage(b: &mut Bencher) {

    b.iter(|| create_app!());
}

#[bench]
fn create_app_builder(b: &mut Bencher) {
    b.iter(|| {
        App::new("claptests")
                .version("0.1")
                .about("tests clap library")
                .author("Kevin K. <kbknapp@gmail.com>")
                .arg(Arg::with_name("opt")
                    .help("tests options")
                    .short("o")
                    .long("option")
                    .takes_value(true)
                    .multiple(true))
                .arg(Arg::with_name("positional")
                    .help("tests positionals")
                    .index(1))
                .arg(Arg::with_name("flag")
                     .short("f")
                     .help("tests flags")
                     .long("flag")
                     .multiple(true)
                     .global(true))
                .arg(Arg::with_name("flag2")
                    .short("F")
                    .help("tests flags with exclusions")
                    .conflicts_with("flag")
                    .requires("option2"))
                .arg(Arg::with_name("option2")
                    .help("tests long options with exclusions")
                    .conflicts_with("option")
                    .requires("positional2")
                    .takes_value(true)
                    .long("long-option-2"))
                .arg(Arg::with_name("positional2")
                    .index(3)
                    .help("tests positionals with exclusions"))
                .arg(Arg::with_name("option3")
                    .short("O")
                    .long("Option")
                    .takes_value(true)
                    .help("tests options with specific value sets")
                    .possible_values(&OPT3_VALS))
                .arg(Arg::with_name("positional3")
                    .multiple(true)
                    .help("tests positionals with specific values")
                    .index(4)
                    .possible_values(&POS3_VALS))
                .arg(Arg::with_name("multvals")
                    .long("multvals")
                    .takes_value(true)
                    .help("Tests mutliple values, not mult occs")
                    .value_names(&["one", "two"]))
                .arg(Arg::with_name("multvalsmo")
                    .long("multvalsmo")
                    .takes_value(true)
                    .multiple(true)
                    .help("Tests mutliple values, not mult occs")
                    .value_names(&["one", "two"]))
                .arg(Arg::with_name("minvals")
                    .long("minvals2")
                    .multiple(true)
                    .takes_value(true)
                    .help("Tests 2 min vals")
                    .min_values(2))
                .arg(Arg::with_name("maxvals")
                    .long("maxvals3")
                    .takes_value(true)
                    .multiple(true)
                    .help("Tests 3 max vals")
                    .max_values(3))
                .subcommand(SubCommand::with_name("subcmd")
                    .about("tests subcommands")
                    .version("0.1")
                    .author("Kevin K. <kbknapp@gmail.com>")
                    .arg(Arg::with_name("scoption")
                        .short("o")
                        .long("option")
                        .multiple(true)
                        .takes_value(true)
                        .help("tests options"))
                    .arg(Arg::with_name("scpositional")
                        .index(1)
                        .help("tests positionals")));
    });
}

#[bench]
fn create_app_macros(b: &mut Bencher) {
    b.iter(|| {
        clap_app!(claptests =>
                (version: "0.1")
                (about: "tests clap library")
                (author: "Kevin K. <kbknapp@gmail.com>")
                (@arg opt: -o --option +takes_value ... "tests options")
                (@arg positional: index(1) "tests positionals")
                (@arg flag: -f --flag ... +global "tests flags")
                (@arg flag2: -F conflicts_with[flag] requires[option2]
                    "tests flags with exclusions")
                (@arg option2: --long_option_2 conflicts_with[option] requires[positional2]
                    "tests long options with exclusions")
                (@arg positional2: index(2) "tests positionals with exclusions")
                (@arg option3: -O --Option +takes_value possible_value[fast slow]
                    "tests options with specific value sets")
                (@arg positional3: index(3) ... possible_value[vi emacs]
                    "tests positionals with specific values")
                (@arg multvals: --multvals +takes_value value_name[one two]
                    "Tests mutliple values, not mult occs")
                (@arg multvalsmo: --multvalsmo ... +takes_value value_name[one two]
                    "Tests mutliple values, not mult occs")
                (@arg minvals: --minvals2 min_values(1) ... +takes_value "Tests 2 min vals")
                (@arg maxvals: --maxvals3 ... +takes_value max_values(3) "Tests 3 max vals")
                (@subcommand subcmd =>
                    (about: "tests subcommands")
                    (version: "0.1")
                    (author: "Kevin K. <kbknapp@gmail.com>")
                    (@arg scoption: -o --option ... +takes_value "tests options")
                    (@arg scpositional: index(1) "tests positionals"))
        );
    });
}

#[bench]
fn parse_clean(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec![""]));
}

#[bench]
fn parse_flag(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"]));
}

#[bench]
fn parse_option(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-o", "option1"]));
}

#[bench]
fn parse_positional(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1"]));
}

#[bench]
fn parse_sc_clean(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd"]));
}

#[bench]
fn parse_sc_flag(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f"]));
}

#[bench]
fn parse_sc_option(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-o", "option1"]));
}

#[bench]
fn parse_sc_positional(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "arg1"]));
}

#[bench]
fn parse_complex1(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "-ff", "-o", "option1", "arg1", "-O", "fast", "arg2", "--multvals", "one", "two", "emacs"]));
}

#[bench]
fn parse_complex2(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
}

#[bench]
fn parse_complex2_with_args_negate_scs(b: &mut Bencher) {
    b.iter(|| create_app!().setting(AppSettings::ArgsNegateSubcommands).get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
}

#[bench]
fn parse_sc_complex(b: &mut Bencher) {
    b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"]));
}
<|endoftext|>


<commit_before>use std::sync::mpsc;
use specs;

#[derive(Clone, Debug)]
pub struct CharacterInputState {
  pub x_movement: f32,
  pub y_movement: f32,
}

impl CharacterInputState {
  pub fn new() -> CharacterInputState {
    CharacterInputState {
      x_movement: 0.0,
      y_movement: 0.0,
    }
  }
}

impl specs::Component for CharacterInputState {
  type Storage = specs::HashMapStorage<CharacterInputState>;
}

#[derive(Debug)]
pub enum CharacterControl {
  Left,
  Right,
  Up,
  Down,
  XMoveStop,
  YMoveStop,
}

#[derive(Debug)]
pub struct CharacterControlSystem {
  queue: mpsc::Receiver<CharacterControl>,
  x_move: Option<f32>,
  y_move: Option<f32>,
}

impl CharacterControlSystem {
  pub fn new() -> (CharacterControlSystem, mpsc::Sender<CharacterControl>) {
    let (tx, rx) = mpsc::channel();
    (CharacterControlSystem {
      queue: rx,
      x_move: None,
      y_move: None,
    }, tx)
  }
}

impl<C> specs::System<C> for CharacterControlSystem {
  fn run(&mut self, arg: specs::RunArg, _: C) {
    use specs::Join;

    let mut character_input = arg.fetch(|w| w.write::<CharacterInputState>());
    while let Ok(control) = self.queue.try_recv() {
      match control {
        CharacterControl::Up => self.y_move = Some(0.5),
        CharacterControl::Down => self.y_move = Some(-0.5),
        CharacterControl::YMoveStop => self.y_move = None,
        CharacterControl::Right => self.x_move = Some(0.5),
        CharacterControl::Left => self.x_move = Some(-0.5),
        CharacterControl::XMoveStop => self.x_move = None,
      }
    }
    if let Some(x) = self.x_move {
      for m in (&mut character_input).join() {
        m.x_movement += x;
      }
    }
    if let Some(y) = self.y_move {
      for m in (&mut character_input).join() {
        m.y_movement += y;
      }
    }
  }
}
<commit_msg>Adjust diagonal movement speed<commit_after>use std::sync::mpsc;
use specs;

#[derive(Clone, Debug)]
pub struct CharacterInputState {
  pub x_movement: f32,
  pub y_movement: f32,
}

impl CharacterInputState {
  pub fn new() -> CharacterInputState {
    CharacterInputState {
      x_movement: 0.0,
      y_movement: 0.0,
    }
  }
}

impl specs::Component for CharacterInputState {
  type Storage = specs::HashMapStorage<CharacterInputState>;
}

#[derive(Debug)]
pub enum CharacterControl {
  Left,
  Right,
  Up,
  Down,
  XMoveStop,
  YMoveStop,
}

#[derive(Debug)]
pub struct CharacterControlSystem {
  queue: mpsc::Receiver<CharacterControl>,
  x_move: Option<f32>,
  y_move: Option<f32>,
}

impl CharacterControlSystem {
  pub fn new() -> (CharacterControlSystem, mpsc::Sender<CharacterControl>) {
    let (tx, rx) = mpsc::channel();
    (CharacterControlSystem {
      queue: rx,
      x_move: None,
      y_move: None,
    }, tx)
  }
}

impl<C> specs::System<C> for CharacterControlSystem {
  fn run(&mut self, arg: specs::RunArg, _: C) {
    use specs::Join;

    let mut character_input = arg.fetch(|w| w.write::<CharacterInputState>());
    while let Ok(control) = self.queue.try_recv() {
      match control {
        CharacterControl::Up => self.y_move = Some(0.5),
        CharacterControl::Down => self.y_move = Some(-0.5),
        CharacterControl::YMoveStop => self.y_move = None,
        CharacterControl::Right => self.x_move = Some(0.5),
        CharacterControl::Left => self.x_move = Some(-0.5),
        CharacterControl::XMoveStop => self.x_move = None,
      }
    }
    if let Some(x) = self.x_move {
      if let Some(y) = self.y_move {
        for m in (&mut character_input).join() {
          m.x_movement += x / 1.5;
          m.y_movement += y / 1.5;
        }
      }
    }
    if let Some(x) = self.x_move {
      if self.y_move == None {
        for m in (&mut character_input).join() {
          m.x_movement += x;
        }
      }
    }
    if let Some(y) = self.y_move {
      if self.x_move == None {
        for m in (&mut character_input).join() {
          m.y_movement += y;
        }
      }
    }
  }
}
<|endoftext|>