<commit_before>pub type Coordinate = [i32; 2];

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

#[derive(Clone, Debug)]
pub struct Grid {
    cell_size: [::Float; 2],
}

impl Grid {
    /// Create a new grid.
    pub fn new(size: ::Float) -> Grid {
        Grid {
            cell_size: [size, size],
        }
    }

    /// Get all the corners of a given cell, starting with
    /// North-West and going clockwise
    pub fn get_corners(&self, c: Coordinate) -> [::Point; 4] {
        use ::Grid;
        let ext = [self.cell_size[0] * 0.5, self.cell_size[1] * 0.5];
        let center = self.get_cell_center(c);
        [[center[0]-ext[0], center[1]-ext[1], 0.0],
         [center[0]+ext[0], center[1]-ext[1], 0.0],
         [center[0]+ext[0], center[1]+ext[1], 0.0],
         [center[0]-ext[0], center[1]+ext[1], 0.0]]
    }

    /// Fold all of the edges in the area.
    pub fn fold_edges_in_area<U,
        F: Fn(U, ::Point, ::Point, Coordinate, Direction) -> U
    >(  &self, area: &::Area, u: U, fun: F) -> U
    {
        use ::Grid;
        self.fold_in_area(area, u, |mut u, c| {
            let corners = self.get_corners(c);
            u = fun(u, corners[0], corners[1], c, Direction::North);
            u = fun(u, corners[1], corners[2], c, Direction::East);
            u
        })
    }
}

impl ::Grid for Grid {
    type Coordinate = Coordinate;
    type Direction = Direction;

    fn get_cell_center(&self, c: Coordinate) -> ::Point {
        [(c[0] as f32 + 0.5) * self.cell_size[0],
         (c[1] as f32 + 0.5) * self.cell_size[1],
         0.0]
    }

    fn get_coordinate(&self, p: &::Point) -> Coordinate {
        [(p[0] / self.cell_size[0]) as i32,
         (p[1] / self.cell_size[1]) as i32]
    }

    fn get_neighbour(&self, c: Coordinate, d: Direction) -> Coordinate {
        match d {
            Direction::North => [c[0], c[1]+1],
            Direction::East  => [c[0]+1, c[1]],
            Direction::South => [c[0], c[1]-1],
            Direction::West  => [c[0]-1, c[1]],
        }
    }

    fn fold_neighbours<U, F: Fn(U, Coordinate, Direction) -> U>(&self, coord: Coordinate, u: U, fun: F) -> U {
        [Direction::North, Direction::East, Direction::South, Direction::West]
            .iter().fold(u, |u, &d| fun(u, self.get_neighbour(coord, d), d))
    }

    fn fold_in_radius<U, F: Fn(U, Coordinate) -> U>(&self, coord: Coordinate, radius: ::Float, mut u: U, fun: F) -> U {
        let ext_x = (radius / self.cell_size[0]) as i32;
        let ext_y = (radius / self.cell_size[1]) as i32;
        for x in coord[0] - ext_x .. coord[0] + ext_x + 1 {
            for y in coord[1] - ext_y .. coord[1] + ext_y + 1 {
                let dist = self.get_distance(coord, [x, y]);
                if dist <= radius {
                    u = fun(u, [x, y]);
                }
            }
        }
        u
    }

    fn fold_in_area<U, F: Fn(U, Coordinate) -> U>(&self, area: &::Area, mut u: U, fun: F) -> U {
        let min_c = self.get_coordinate(&area[0]);
        let max_c = self.get_coordinate(&area[1]);
        for x in min_c[0] .. max_c[0]+1 {
            for y in min_c[1] .. max_c[1] + 1 {
                u = fun(u, [x,y]);
            }
        }
        u
    }
}

impl ::Grid2 for Grid {
    fn get_edge(&self, c: Coordinate, d: Direction) -> [::Point; 2] {
        let corners = self.get_corners(c);
        match d {
            Direction::North => [corners[0], corners[1]],
            Direction::East  => [corners[1], corners[2]],
            Direction::South => [corners[2], corners[3]],
            Direction::West  => [corners[3], corners[0]],
        }
    }
}<commit_msg>Fixed quad's get_coordinate<commit_after>pub type Coordinate = [i32; 2];

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

#[derive(Clone, Debug)]
pub struct Grid {
    cell_size: [::Float; 2],
}

impl Grid {
    /// Create a new grid.
    pub fn new(size: ::Float) -> Grid {
        Grid {
            cell_size: [size, size],
        }
    }

    /// Get all the corners of a given cell, starting with
    /// North-West and going clockwise
    pub fn get_corners(&self, c: Coordinate) -> [::Point; 4] {
        use ::Grid;
        let ext = [self.cell_size[0] * 0.5, self.cell_size[1] * 0.5];
        let center = self.get_cell_center(c);
        [[center[0]-ext[0], center[1]-ext[1], 0.0],
         [center[0]+ext[0], center[1]-ext[1], 0.0],
         [center[0]+ext[0], center[1]+ext[1], 0.0],
         [center[0]-ext[0], center[1]+ext[1], 0.0]]
    }

    /// Fold all of the edges in the area.
    pub fn fold_edges_in_area<U,
        F: Fn(U, ::Point, ::Point, Coordinate, Direction) -> U
    >(  &self, area: &::Area, u: U, fun: F) -> U
    {
        use ::Grid;
        self.fold_in_area(area, u, |mut u, c| {
            let corners = self.get_corners(c);
            u = fun(u, corners[0], corners[1], c, Direction::North);
            u = fun(u, corners[1], corners[2], c, Direction::East);
            u
        })
    }
}

impl ::Grid for Grid {
    type Coordinate = Coordinate;
    type Direction = Direction;

    fn get_cell_center(&self, c: Coordinate) -> ::Point {
        [(c[0] as f32 + 0.5) * self.cell_size[0],
         (c[1] as f32 + 0.5) * self.cell_size[1],
         0.0]
    }

    fn get_coordinate(&self, p: &::Point) -> Coordinate {
        [(p[0] / self.cell_size[0]).floor() as i32,
         (p[1] / self.cell_size[1]).floor() as i32]
    }

    fn get_neighbour(&self, c: Coordinate, d: Direction) -> Coordinate {
        match d {
            Direction::North => [c[0], c[1]+1],
            Direction::East  => [c[0]+1, c[1]],
            Direction::South => [c[0], c[1]-1],
            Direction::West  => [c[0]-1, c[1]],
        }
    }

    fn fold_neighbours<U, F: Fn(U, Coordinate, Direction) -> U>(&self, coord: Coordinate, u: U, fun: F) -> U {
        [Direction::North, Direction::East, Direction::South, Direction::West]
            .iter().fold(u, |u, &d| fun(u, self.get_neighbour(coord, d), d))
    }

    fn fold_in_radius<U, F: Fn(U, Coordinate) -> U>(&self, coord: Coordinate, radius: ::Float, mut u: U, fun: F) -> U {
        let ext_x = (radius / self.cell_size[0]) as i32;
        let ext_y = (radius / self.cell_size[1]) as i32;
        for x in coord[0] - ext_x .. coord[0] + ext_x + 1 {
            for y in coord[1] - ext_y .. coord[1] + ext_y + 1 {
                let dist = self.get_distance(coord, [x, y]);
                if dist <= radius {
                    u = fun(u, [x, y]);
                }
            }
        }
        u
    }

    fn fold_in_area<U, F: Fn(U, Coordinate) -> U>(&self, area: &::Area, mut u: U, fun: F) -> U {
        let min_c = self.get_coordinate(&area[0]);
        let max_c = self.get_coordinate(&area[1]);
        for x in min_c[0] .. max_c[0]+1 {
            for y in min_c[1] .. max_c[1] + 1 {
                u = fun(u, [x,y]);
            }
        }
        u
    }
}

impl ::Grid2 for Grid {
    fn get_edge(&self, c: Coordinate, d: Direction) -> [::Point; 2] {
        let corners = self.get_corners(c);
        match d {
            Direction::North => [corners[0], corners[1]],
            Direction::East  => [corners[1], corners[2]],
            Direction::South => [corners[2], corners[3]],
            Direction::West  => [corners[3], corners[0]],
        }
    }
}<|endoftext|>


<commit_before>//! Utilities for generating random values
//!
//! The entire [`rand`](https://github.com/rust-lang-nursery/rand) crate which allows you to
//! generate random values is re-exported for your convenience. That means that you can use any
//! of its parts by importing from this module.
//! See the documentation for [`rand_crate`](../../rand/index.html).
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::rand::Rand;
//! # fn main() {}
//! ```
//!
//! The [`random()`] function is the most common function you will use. In fact,
//! it's exported from the turtle crate directly so you don't even have to use the `rand` module
//! in order to access it.
//!
//! Instead of this:
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::Turtle;
//! use turtle::rand::random;
//! # fn main() {}
//! ```
//!
//! You can do this:
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::{Turtle, random};
//! # fn main() {}
//! ```
//!
//! This means that for the most part, unless you are doing something very advanced, you won't need
//! to import this module. The [`random()`] function should be enough for
//! most cases. See the next section for more information on that.
//!
//! # Generating Random Values
//!
//! The [`random()`] function allows you to generate random values for many different types.
//! The following are some examples of types that can be used with [`random()`]:
//!
//! * [`Distance`] - `f64` values greater than or equal to `0.0` and less than `1.0`
//! * [`Angle`] - `f64` values greater than or equal to `0.0` and less than `1.0`
//! * [`Speed`] - any speed value in the valid range, not including instant
//! * [`Color`] - colors with random red, green, blue and alpha values (use
//!   [`opaque()`](../color/struct.Color.html#method.opaque) to get a solid random color)
//! * [`Point`] - a random point with two `f64` values greater than or equal to `0.0` and less than `1.0`
//! * and more!
//!
//! Using [`random()`] often requires you to specify a type that you want to generate. For example,
//! if you run the following, the compiler will tell you that it needs you to give it more
//! information about the type that you want to generate:
//!
//! ```rust,compile_fail,E0283
//! # use turtle::{Turtle, random};
//! let mut turtle = Turtle::new();
//! turtle.set_speed(random());
//! ```
//!
//! This will produce an error that looks something like the following:
//!
//! ```text
//! error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<turtle::Speed>`
//!  --> src/rand.rs:5:8
//!   |
//! 5 | turtle.set_speed(random());
//!   |        ^^^^^^^^^
//! ```
//!
//! To resolve this, you can either annotate the type by generating the random value in a separate
//! variable, or use Rust's "turbofish" syntax.
//!
//! ```rust
//! # use turtle::{Turtle, Speed, random};
//! let mut turtle = Turtle::new();
//! // 1. Separate out into a variable, then annotate the desired type
//! let speed: Speed = random();
//! turtle.set_speed(speed);
//! // 2. Turbofish syntax ::<T>
//! turtle.set_speed(random::<Speed>());
//! ```
//!
//! # Generating Random Values in a Range
//!
//! The [`random_range()`] function allows you to generate values in a given range. You provide
//! a lower bound and an upper bound. The number generated will be greater than or equal to the
//! lower bound and strictly less than the upper bound.
//!
//! ```rust
//! # use turtle::random_range;
//! // Generates an f64 value between 394.0 and 499.99999...
//! let value: f64 = random_range(394.0, 500.0);
//! assert!(value >= 394.0 && value < 500.0);
//! // Generates a u64 value between 32 and 64
//! let value = random_range::<u64>(32, 65);
//! assert!(value >= 32 && value <= 64);
//! // You do not need to specify the type if the compiler has enough information:
//! fn foo(a: u64) {}
//! foo(random_range(381, 920));
//! ```
//!
//! Most types that can be used with [`random()`] can also be used with [`random_range()`]. This
//! includes all of the types listed above.
//!
//! When [`random_range()`] is used to generate a [`Point`], it creates a random point within the
//! rectangle formed by the two points given as arguments to [`random_range()`]. This is
//! illustrated in the example below:
//!
//! ```rust
//! # use turtle::{Point, random_range};
//! // Generates a Point value with:
//! //   x-coordinate between 46.0 and 99932.0
//! //   y-coordinate between 309.0 and 1803.0
//! let value: Point = random_range([99932.0, 309.0].into(), [46.0, 1803.0].into());
//! assert!(value.x >= 46.0 && value.x < 99932.0);
//! assert!(value.y >= 309.0 && value.y < 1803.0);
//! ```
//!
//! # How can one function generate so many different return types?
//!
//! Knowing how [`random()`] works is **not required** in order to be able to use it. That being said,
//! it is an excellent example of combing the concepts of "generics" and "traits". If you are not
//! familiar with those concepts yet, take a look at the
//! [Rust book](https://doc.rust-lang.org/book/second-edition/). It has an excellent
//! [section on both generics and traits](https://doc.rust-lang.org/book/second-edition/ch10-00-generics.html).
//!
//! The type signature of the [`random()`] function is similar to the following:
//!
//! ```rust,compile_fail,E0308
//! # use turtle::rand::Rand;
//! fn random<T: Rand>() -> T { /* ... */ }
//! ```
//!
//! This tells us the following:
//!
//! * The `random()` function takes **no arguments** and returns a value of type `T`
//! * The generic type `T` is required to implement the [`Rand`] trait
//!
//! This is the incredible part about this function. It requires *zero* arguments, and yet can
//! generate all kinds of values. This is because while it doesn't require any *parameters*, it
//! does take a single *type argument* in order to determine what type to generate a value of.
//! This is done at compile time so no work needs to be performed at runtime in order to determine
//! the type to generate or how to generate it.
//!
//! This also explains why we sometimes need to use the turbofish syntax (`::<T>`) in order to
//! specify the type `T`. When a function requires a type argument and doesn't take that argument
//! as one of its parameters, the compiler can often end up in a situation where it doesn't have
//! the necessary information to determine which type to return.
//! The turbofish syntax and type annotations provide two different ways to clarify what we want.
//!
//! That being said, there are a lot of situations where the compiler *can* figure out what type
//! we need. Each of the types we covered above, implements the [`Rand`] trait. We specified which
//! type we would like the function to return by annotating the variable that we assigned the
//! random value to.
//!
//! ```rust
//! # use turtle::{Speed, random};
//! let speed: Speed = random();
//! ```
//!
//! If we were passing the value to a function that is known to take [`Speed`] as its type, the
//! compiler can use that information to determine the return type of [`random()`]. The following
//! example compiles without any additional annotations:
//!
//! ```rust
//! # use turtle::{Speed, random};
//! fn foo(speed: Speed) {}
//! // No type annotations required!
//! foo(random());
//! ```
//!
//! This generates a random speed using the implementation of [`Rand`] for the [`Speed`] type in this
//! crate.
//!
//! # The Orphan Rule
//! Not all of the implementations of [`Rand`] for the types above are implemented in this
//! crate. There is a rule known as the [orphan rule](https://doc.rust-lang.org/book/second-edition/ch10-02-traits.html#implementing-a-trait-on-a-type)
//! which prevents anyone from implementing a trait on a type that they do not define. That is why
//! we implemented [`Rand`] for [`Speed`], [`Color`], and [`Point`], but not for type aliases like
//! [`Distance`]. [`Distance`] is a type alias for `f64`. `f64` is provided by the standard
//! library, so we cannot implement any traits for it. The implementations of [`Rand`] for types
//! like that come from the `rand` crate itself.
//!
//! [`Rand`]: ../../rand/trait.Rand.html
//! [`random()`]: ../fn.random.html
//! [`random_range()`]: fn.random_range.html
//! [`Distance`]: ../type.Distance.html
//! [`Angle`]: ../type.Angle.html
//! [`Speed`]: ../speed/struct.Speed.html
//! [`Color`]: ../color/struct.Color.html
//! [`Point`]: ../struct.Point.html

pub use ::rand::*;

use self::distributions::uniform::SampleUniform;

/// Implement this type to allow it to be used with the random_range function.
pub trait RandomRange {
    fn random_range<R: Rng>(rng: &mut R, low: Self, high: Self) -> Self;
}

impl<T> RandomRange for T
where
    T: PartialOrd + SampleUniform,
{
    fn random_range<R: Rng>(rng: &mut R, low: T, high: T) -> T {
        rng.gen_range(low, high)
    }
}

/// Generates a random value in the given range.
///
/// The value `x` that is returned will be such that low ≤ x < high.
///
/// See [Generating Random Values in a Range](index.html#generating-random-values-in-a-range)
/// for more information.
///
/// # Panics
/// Panics if low ≥ high
///
/// # Example:
/// ```rust
/// # use turtle::random_range;
/// // Generates an f64 value between 100 and 199
/// let value: f64 = random_range(100.0, 200.0);
/// assert!(value >= 100.0 && value < 200.0);
/// // Generates a u64 value between 1000 and 3000000
/// let value = random_range::<u64>(1000, 3000001);
/// assert!(value >= 1000 && value < 3000001);
/// // You do not need to specify the type if the compiler has enough information:
/// fn foo(a: u64) {}
/// foo(random_range(432, 1938));
/// ```
pub fn random_range<T: RandomRange>(low: T, high: T) -> T {
    let mut rng = thread_rng();
    RandomRange::random_range(&mut rng, low, high)
}
<commit_msg>Updating rand's docs for the latest rand crate<commit_after>//! Utilities for generating random values
//!
//! The entire [`rand`](https://github.com/rust-lang-nursery/rand) crate which allows you to
//! generate random values is re-exported for your convenience. That means that you can use any
//! of its parts by importing from this module.
//!
//! **Almost all of the documented items listed at the bottom of this page are from the `rand`
//! crate directly.** The only additional function provided specifically by `turtle` is the
//! [`random_range()`] function.
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::rand::{random, random_range};
//! # fn main() {}
//! ```
//!
//! Of everything provided, the [`random()`] function is probably the most common function you will
//! use. In fact, it's exported from the turtle crate directly so you don't even have to use the
//! `rand` module in order to access it.
//!
//! Instead of this:
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::Turtle;
//! use turtle::rand::random;
//! # fn main() {}
//! ```
//!
//! You can do this:
//!
//! ```rust,no_run
//! extern crate turtle;
//! use turtle::{Turtle, random};
//! # fn main() {}
//! ```
//!
//! This means that for the most part, unless you are doing something very advanced, you won't need
//! to import this module. The [`random()`] function should be enough for
//! most cases. See the next section for more information on that.
//!
//! # Generating Random Values
//!
//! The [`random()`] function allows you to generate random values for many different types.
//! The following are some examples of types that can be used with [`random()`]:
//!
//! * [`Distance`] - `f64` values greater than or equal to `0.0` and less than `1.0`
//! * [`Angle`] - `f64` values greater than or equal to `0.0` and less than `1.0`
//! * [`Speed`] - any speed value in the valid range, not including instant
//! * [`Color`] - colors with random red, green, blue and alpha values (use
//!   [`opaque()`](../color/struct.Color.html#method.opaque) to get a solid random color)
//! * [`Point`] - a random point with two `f64` values greater than or equal to `0.0` and less than `1.0`
//! * and more!
//!
//! Using [`random()`] often requires you to specify a type that you want to generate. For example,
//! if you run the following, the compiler will tell you that it needs you to give it more
//! information about the type that you want to generate:
//!
//! ```rust,compile_fail,E0283
//! # use turtle::{Turtle, random};
//! let mut turtle = Turtle::new();
//! turtle.set_speed(random());
//! ```
//!
//! This will produce an error that looks something like the following:
//!
//! ```text
//! error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<turtle::Speed>`
//!  --> src/rand.rs:5:8
//!   |
//! 5 | turtle.set_speed(random());
//!   |        ^^^^^^^^^
//! ```
//!
//! To resolve this, you can either annotate the type by generating the random value in a separate
//! variable, or use Rust's "turbofish" syntax.
//!
//! ```rust
//! # use turtle::{Turtle, Speed, random};
//! let mut turtle = Turtle::new();
//! // 1. Separate out into a variable, then annotate the desired type
//! let speed: Speed = random();
//! turtle.set_speed(speed);
//! // 2. Turbofish syntax ::<T>
//! turtle.set_speed(random::<Speed>());
//! ```
//!
//! # Generating Random Values in a Range
//!
//! The [`random_range()`] function allows you to generate values in a given range. You provide
//! a lower bound and an upper bound. The number generated will be greater than or equal to the
//! lower bound and strictly less than the upper bound.
//!
//! ```rust
//! # use turtle::random_range;
//! // Generates an f64 value between 394.0 and 499.99999...
//! let value: f64 = random_range(394.0, 500.0);
//! assert!(value >= 394.0 && value < 500.0);
//! // Generates a u64 value between 32 and 64
//! let value = random_range::<u64>(32, 65);
//! assert!(value >= 32 && value <= 64);
//! // You do not need to specify the type if the compiler has enough information:
//! fn foo(a: u64) {}
//! foo(random_range(381, 920));
//! ```
//!
//! Most types that can be used with [`random()`] can also be used with [`random_range()`]. This
//! includes all of the types listed above.
//!
//! When [`random_range()`] is used to generate a [`Point`], it creates a random point within the
//! rectangle formed by the two points given as arguments to [`random_range()`]. This is
//! illustrated in the example below:
//!
//! ```rust
//! # use turtle::{Point, random_range};
//! // Generates a Point value with:
//! //   x-coordinate between 46.0 and 99932.0
//! //   y-coordinate between 309.0 and 1803.0
//! let value: Point = random_range([99932.0, 309.0].into(), [46.0, 1803.0].into());
//! assert!(value.x >= 46.0 && value.x < 99932.0);
//! assert!(value.y >= 309.0 && value.y < 1803.0);
//! ```
//!
//! # How can one function generate so many different return types?
//!
//! Knowing how [`random()`] works is **not required** in order to be able to use it. That being said,
//! it is an excellent example of combing the concepts of "generics" and "traits". If you are not
//! familiar with those concepts yet, take a look at the
//! [Rust book](https://doc.rust-lang.org/book/second-edition/). It has an excellent
//! [section on both generics and traits](https://doc.rust-lang.org/book/second-edition/ch10-00-generics.html).
//!
//! The type signature of the [`random()`] function is similar to the following:
//!
//! ```rust,compile_fail,E0308
//! # use turtle::rand::distributions::{Distribution, Standard};
//! fn random<T>() -> T where Standard: Distribution<T> { /* ... */ }
//! ```
//!
//! This tells us the following:
//!
//! * The `random()` function takes **no arguments** and returns a value of type `T`
//! * The generic type `T` is required to fulfill the condition `Standard: Distribution<T>`
//!
//! That's pretty incredible! With *zero* arguments, [`random()`] can generate all kinds of values.
//! This works because while it doesn't have any normal arguments passed in, it does require a
//! single *type* argument to be provided. This type is required to be part of a specific *trait*
//! implementation and the [`random()`] function is able to use that implementation to generate a
//! random value. This is done at compile time so no additional work needs to be performed at
//! runtime in order to determine the type to generate or how to generate it.
//!
//! This also explains why we sometimes need to use the turbofish syntax (`::<T>`) in order to
//! specify the type `T`. When a function requires a type argument and doesn't take that argument
//! as one of its parameters, the compiler can often end up in a situation where it doesn't have
//! the necessary information to determine which type to return.
//!
//! The turbofish syntax and type annotations provide two different ways to clarify what we want.
//!
//! That being said, there are a lot of situations where the compiler *can* figure out what type
//! we need. In some of the examples above, we specified which type we would like the function to
//! return by annotating the variable that we assigned the random value to.
//!
//! ```rust
//! # use turtle::{Speed, random};
//! let speed: Speed = random();
//! ```
//!
//! If we were passing the value to a function that is known to take [`Speed`] as its type, the
//! compiler can use that information to determine the return type of [`random()`]. The following
//! example compiles without any additional annotations:
//!
//! ```rust
//! # use turtle::{Speed, random};
//! fn foo(speed: Speed) {}
//! // No type annotations required!
//! foo(random());
//! ```
//!
//! # The Orphan Rule
//!
//! Not all of the implementations of the traits from the `rand` crate for the types above are
//! implemented in this crate. There is a rule known as the [orphan rule] which prevents anyone
//! from implementing a trait on a type that they do not define. That is why we implemented the
//! `rand` traits for for [`Speed`], [`Color`], and [`Point`], but not for type aliases like
//! [`Distance`]. [`Distance`] is a type alias for `f64`. `f64` is provided by the standard
//! library, so we cannot implement any traits for it. The implementations of the `rand` crate's
//! traits for those types come from the `rand` crate itself.
//!
//! [`random()`]: ../fn.random.html
//! [`random_range()`]: fn.random_range.html
//! [`Distance`]: ../type.Distance.html
//! [`Angle`]: ../type.Angle.html
//! [`Speed`]: ../speed/struct.Speed.html
//! [`Color`]: ../color/struct.Color.html
//! [`Point`]: ../struct.Point.html
//! [orphan rule]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type

pub use ::rand::*;

use self::distributions::uniform::SampleUniform;

/// Implement this type to allow it to be used with the random_range function.
pub trait RandomRange {
    fn random_range<R: Rng>(rng: &mut R, low: Self, high: Self) -> Self;
}

impl<T> RandomRange for T
where
    T: PartialOrd + SampleUniform,
{
    fn random_range<R: Rng>(rng: &mut R, low: T, high: T) -> T {
        rng.gen_range(low, high)
    }
}

/// Generates a random value in the given range.
///
/// The value `x` that is returned will be such that low ≤ x < high.
///
/// See [Generating Random Values in a Range](index.html#generating-random-values-in-a-range)
/// for more information.
///
/// # Panics
/// Panics if low ≥ high
///
/// # Example:
/// ```rust
/// # use turtle::random_range;
/// // Generates an f64 value between 100 and 199
/// let value: f64 = random_range(100.0, 200.0);
/// assert!(value >= 100.0 && value < 200.0);
/// // Generates a u64 value between 1000 and 3000000
/// let value = random_range::<u64>(1000, 3000001);
/// assert!(value >= 1000 && value < 3000001);
/// // You do not need to specify the type if the compiler has enough information:
/// fn foo(a: u64) {}
/// foo(random_range(432, 1938));
/// ```
pub fn random_range<T: RandomRange>(low: T, high: T) -> T {
    let mut rng = thread_rng();
    RandomRange::random_range(&mut rng, low, high)
}
<|endoftext|>


<commit_before>// mrusty. mruby safe bindings for Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use std::fmt::Display;

use super::mruby::*;
use super::read_line::ReadLine;

/// A `struct` that exposes an `Mruby` to a REPL.
///
/// # Examples
///
/// ```no-run
/// let mruby = Mruby::new();
/// let repl = Repl::new(mruby);
///
/// repl.start();
/// ```
pub struct Repl {
    mruby: MrubyType,
    name: String
}

impl Repl {
    /// Creates a new `Repl`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::Mruby;
    /// # use mrusty::Repl;
    /// let mruby = Mruby::new();
    /// let repl = Repl::new(mruby);
    /// ```
    pub fn new(mruby: MrubyType) -> Repl {
        Repl {
            mruby: mruby,
            name: "mrusty".to_owned()
        }
    }

    /// Renames a `Repl`. The command line will start with `{name}> `.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::Mruby;
    /// # use mrusty::Repl;
    /// let mruby = Mruby::new();
    /// let mut repl = Repl::new(mruby);
    ///
    /// repl.rename("repl");
    /// ```
    pub fn rename(&mut self, name: &str) {
        self.name = name.to_owned();
    }

    /// Starts a `Repl`.
    ///
    /// Use `'\'` for multiline statements.
    ///
    /// # Examples
    ///
    /// ```no-run
    /// let mruby = Mruby::new();
    /// let repl = Repl::new(mruby);
    ///
    /// repl.start(&GnuReadLine);
    /// ```
    pub fn start<E: Display>(&self, read_line: &ReadLine<E>) {
        let mut command = String::new();

        let single = self.name.clone() + "> ";
        let multi  = self.name.clone() + "* ";

        loop {
            self.mruby.filename("repl");

            let head = if command.is_empty() {
                &single
            } else {
                &multi
            };

            let input = match read_line.read(head) {
                Ok(Some(s)) => s,
                Ok(None) => break,
                Err(e) => {
                    println!("{}", e);

                    break
                }
            };

            if input.ends_with("\\") {
                let trimmed = input.trim_right_matches("\\");

                command = command + trimmed + "\n";
                read_line.add(&trimmed);

                continue
            } else {
                read_line.add(&input);
            }

            if command == "" {
                command = input;
            } else {
                command = command + &input;
            }

            match self.mruby.run(&command) {
                Ok(value) => {
                    let result = value.call("to_s", vec![]).unwrap().to_str().unwrap();

                    println!("{}", result);
                },
                Err(message) => {
                    println!("{}", message);
                }
            }

            if !command.is_empty() {
                command = String::new();
            }
        }

        println!("");
    }
}
<commit_msg>small doc fixes for Repl<commit_after>// mrusty. mruby safe bindings for Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use std::fmt::Display;

use super::mruby::*;
use super::read_line::ReadLine;

/// A `struct` that exposes an `Mruby` to a REPL.
///
/// # Examples
///
/// Using `GnuReadLine`, which requires the `gnu-readline` feature:
///
/// ```no-run
/// let mruby = Mruby::new();
/// let repl = Repl::new(mruby);
///
/// repl.start(&GnuReadLine);
/// ```
pub struct Repl {
    mruby: MrubyType,
    name: String
}

impl Repl {
    /// Creates a new `Repl`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::Mruby;
    /// # use mrusty::Repl;
    /// let mruby = Mruby::new();
    /// let repl = Repl::new(mruby);
    /// ```
    pub fn new(mruby: MrubyType) -> Repl {
        Repl {
            mruby: mruby,
            name: "mrusty".to_owned()
        }
    }

    /// Renames a `Repl`. The command line will start with `{name}> `.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::Mruby;
    /// # use mrusty::Repl;
    /// let mruby = Mruby::new();
    /// let mut repl = Repl::new(mruby);
    ///
    /// repl.rename("repl");
    /// ```
    pub fn rename(&mut self, name: &str) {
        self.name = name.to_owned();
    }

    /// Starts a `Repl`.
    ///
    /// Use `'\'` for multiline statements.
    ///
    /// # Examples
    ///
    /// Using `GnuReadLine`, which requires the `gnu-readline` feature:
    ///
    /// ```no-run
    /// let mruby = Mruby::new();
    /// let repl = Repl::new(mruby);
    ///
    /// repl.start(&GnuReadLine);
    /// ```
    pub fn start<E: Display>(&self, read_line: &ReadLine<E>) {
        let mut command = String::new();

        let single = self.name.clone() + "> ";
        let multi  = self.name.clone() + "* ";

        loop {
            self.mruby.filename("repl");

            let head = if command.is_empty() {
                &single
            } else {
                &multi
            };

            let input = match read_line.read(head) {
                Ok(Some(s)) => s,
                Ok(None) => break,
                Err(e) => {
                    println!("{}", e);

                    break
                }
            };

            if input.ends_with("\\") {
                let trimmed = input.trim_right_matches("\\");

                command = command + trimmed + "\n";
                read_line.add(&trimmed);

                continue
            } else {
                read_line.add(&input);
            }

            if command == "" {
                command = input;
            } else {
                command = command + &input;
            }

            match self.mruby.run(&command) {
                Ok(value) => {
                    let result = value.call("to_s", vec![]).unwrap().to_str().unwrap();

                    println!("{}", result);
                },
                Err(message) => {
                    println!("{}", message);
                }
            }

            if !command.is_empty() {
                command = String::new();
            }
        }

        println!("");
    }
}
<|endoftext|>


<commit_before>
use std::str;
use std::io::{self, Read, Write};
use std::fs::File;
use std::path::Path;

use hyper::{Get, Post, StatusCode, RequestUri, Decoder, Encoder, Next};
use hyper::header::{ContentLength, ContentType};
use hyper::net::HttpStream;

use hyper::server::Server;
use hyper::server::Handler as HyperHandler;
use hyper::server::Request as HyperRequest;
use hyper::server::Response as HyperResponse;
use hyper::method::Method;
use hyper::version::HttpVersion;

use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::sync::Arc;
use std::marker::Reflect;
use std::clone::Clone;
use std::marker::PhantomData;

use mime_types::Types as MimeTypes;

pub use typemap::Key;
pub use hyper::header::Headers;
pub use hyper::header;
pub use hyper::mime;
pub use request::Request;
pub use response::Response;
pub use router::Router;
pub use srouter::SRouter;
pub use shandler::SHandler;

#[derive(Debug, PartialEq, Clone)]
pub enum Error {
    NotFound(String),
    InvalidConfig,
    InvalidRouterConfig,
    FileNotExist,
    ShouldRedirect(String),
    Prompt(String),
    Warning(String),
    Fatal(String),
    Custom(String),
}

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Clone)]
pub struct ReqPathParams;

pub trait SModule {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

    // here add routers ....
    fn router(&self, &mut SRouter) -> Result<()>;
    // fn router(&self, SRouter) -> Result<SRouter>;

}

pub trait SAppWrapper {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

}

// later will add more fields
pub struct SApp<T: SModule + Send + 'static, W: SAppWrapper + Send + 'static> {
    pub address: String,
    pub port:    u32,
    // for app entry, global middeware
    pub wrapper: Option<W>,
    // for actually use to recognize
    pub routers: Router,
    // do simple static file service?
    pub static_service: bool,
    // marker for type T
    pub _marker: PhantomData<T>,
}

impl<T, W> SApp<T, W>
    where   T: SModule + Send + Sync + Reflect + Clone,
            W: SAppWrapper + Send + Sync + Reflect + Clone
    {
    pub fn new() -> SApp<T, W> {
        SApp {
            address: String::new(),
            port: 0,
            wrapper: None,
            routers: Router::new(),
            static_service: true,
            _marker: PhantomData
        }
    }

    pub fn run(self) {

        let listen_addr = self.address.clone() + ":" + &self.port.to_string();
        let arc_sapp = Arc::new(Box::new(self));

        let server = Server::http(&listen_addr.parse().unwrap()).unwrap();
        let _guard = server.handle(move |_| {
            RequestHandler::new(arc_sapp.clone())
        });
    }

    pub fn with_wrapper(&mut self, w: W) -> &mut Self {
        self.wrapper = Some(w);
        self
    }

    pub fn address(&mut self, address: &str) -> &mut Self {
        self.address = address.to_owned();
        self
    }

    pub fn port(&mut self, port: u32) -> &mut Self {
        self.port = port;
        self
    }

    pub fn static_service(&mut self, open: bool) -> &mut Self {
        self.static_service = open;
        self
    }

    // add methods of this smodule
    // prefix:  such as '/user'
    pub fn add_module(&mut self, sm: T) -> &mut Self {

        let mut router = SRouter::new();
        // get the sm router
        // pass self.router in
        sm.router(&mut router).unwrap();
        // combile this router to global big router
        // create a new closure, containing
        //      0. execute sapp.before();
        //      1. execute sm.before();
        //      2. execute a_router map pair value part function;
        //      3. execute sm.after();
        //      4. execute sapp.after();
        // fill the self.routers finally
        // assign this new closure to the routers router map pair  prefix + url part

        for (method, handler_vec) in router.into_router() {
            // add to wrapped router
            for &(glob, ref handler) in handler_vec.iter() {
                let method = method.clone();
                let glob = glob.clone();
                let handler = handler.clone();
                let sm = sm.clone();
                let wrapper = self.wrapper.clone().unwrap();
                self.routers.route(method, glob, Arc::new(Box::new(move |req: &mut Request| -> Result<Response> {
                    wrapper.before(req)?;
                    sm.before(req)?;
                    let mut response: Response = handler.handle(req)?;
                    sm.after(req, &mut response)?;
                    wrapper.after(req, &mut response)?;
                    Ok(response)
                })));
            }
        }

        // self.modules.push(sm);

        self
    }
}

// this is very expensive in time
// should make it as global
lazy_static! {
    static ref MTYPES: MimeTypes = { MimeTypes::new().unwrap() };
}

fn simple_file_get(path: &str) -> Result<(Vec<u8>, String)> {
    let new_path;
    if &path[(path.len()-1)..] == "/" {
        new_path = "static/".to_owned() + path + "index.html";
    }
    else {
        new_path = "static/".to_owned() + path;
    }
    //println!("file path: {}", new_path);
    match File::open(&new_path) {
        Ok(ref mut file) => {
            let mut s: Vec<u8> = vec![];
            file.read_to_end(&mut s).unwrap_or(0);

            let mt_str = MTYPES.mime_for_path(Path::new(&new_path));

            Ok((s, mt_str.to_owned()))
        },
        Err(_) => Err(Error::FileNotExist)
    }
}

pub struct RequestHandler<
        T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static> {
    // router, keep the original handler function
    // pub router: SRouter,
    // wrapped router, keep the wrapped handler function
    // for actually use to recognize
    pub sapp: Arc<Box<SApp<T, W>>>,
    pub path: String,
    pub method: Method,
    pub version: HttpVersion,
    pub headers: Headers,
    pub buf: Vec<u8>,
    pub body: String,
    pub has_body: bool,
    // response deliver
    pub response: Result<Response>,
    pub static_file: Option<Vec<u8>>,
}

impl<T, W> RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
{
    pub fn new(sapp: Arc<Box<SApp<T, W>>>) -> RequestHandler<T, W> {
        RequestHandler {
            sapp: sapp,
            path: String::new(),
            method: Default::default(),
            version: Default::default(),
            headers: Default::default(),
            buf: vec![0; 2048],
            body: String::new(),
            has_body: false,
            response: Err(Error::NotFound("/".to_owned())),
            static_file: None,
        }
    }

}

impl<T, W> HyperHandler<HttpStream> for RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
 {
    fn on_request(&mut self, req: HyperRequest) -> Next {

        match *req.uri() {
            RequestUri::AbsolutePath(ref path) =>  {
                // if has_body
                if req.headers().get::<ContentLength>().is_some()
                    || req.headers().get::<ContentType>().is_some()
                 {
                    self.path = path.to_owned();
                    self.method = req.method().clone();
                    self.version = req.version().clone();
                    self.headers = req.headers().clone();
                    self.has_body = true;

                    Next::read_and_write()
                }
                else {
                    // if no body
                    let pathstr = &path[..];
                    let pathvec: Vec<&str> = pathstr.split('?').collect();
                    let path = pathvec[0].to_owned();
                    let mut query_string = None;

                    // if has query_string
                    if pathvec.len() > 1 {
                        query_string = Some(pathvec[1].to_owned());
                    }

                    // make swiftrs request from hyper request
                    let mut sreq = Request::new(
                        req.method().clone(),
                        req.version().clone(),
                        req.headers().clone(),
                        path.clone(),
                        query_string);

                    self.response = self.sapp.routers.handle_method(&mut sreq, &path).unwrap();

                    // match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    //     Ok(response) => self.response = Some(response),
                    //     Err(e) => {
                    //         if e == Error::NotFoundError {
                    //             self.response = None
                    //         }
                    //     }
                    // }

                    Next::write()
                }

                // XXX: Need more work
                // self.response = self.routers.handle_method(&mut sreq, &path).unwrap().ok();

                // TODO: complete it later
                // .unwrap_or_else(||
                    // match req.method {
                    //     method::Options => Ok(self.handle_options(&path)),
                    //     // For HEAD, fall back to GET. Hyper ensures no response body is written.
                    //     method::Head => {
                    //         req.method = method::Get;
                    //         self.handle_method(req, &path).unwrap_or(
                    //             Err(IronError::new(NoRoute, status::NotFound))
                    //         )
                    //     }
                    //     _ => Err(IronError::new(NoRoute, status::NotFound))
                    // }
                // );
                // currently

                // if is_more {
                //     Next::read_and_write()
                // } else {
                //     Next::write()
                // }

                // Next::read_and_write()
                // Next::write()

            },
            _ => Next::write()
        }
    }
    fn on_request_readable(&mut self, transport: &mut Decoder<HttpStream>) -> Next {

        if self.has_body {
            match transport.read(&mut self.buf) {
                Ok(0) => {
                    debug!("Read 0, eof");

                    // TODO: need optimize
                    let pathstr = &self.path[..];
                    let pathvec: Vec<&str> = pathstr.split('?').collect();
                    let path = pathvec[0].to_owned();
                    let mut query_string = None;

                    // if has query_string
                    if pathvec.len() > 1 {
                        query_string = Some(pathvec[1].to_owned());
                    }
                    let mut sreq = Request::new(
                        self.method.clone(),
                        self.version.clone(),
                        self.headers.clone(),
                        path.clone(),
                        query_string);

                    // TODO: optimize this memory copy
                    sreq.set_raw_body(self.body.clone());

                    self.response = self.sapp.routers.handle_method(&mut sreq, &path).unwrap();

                    // match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    //     Ok(response) => self.response = Some(response),
                    //     Err(e) => {
                    //         if e == Error::NotFoundError {
                    //             self.response = None
                    //         }
                    //     }
                    // }
                    //

                    return Next::write()
                },
                Ok(n) => {
                    self.body.push_str(str::from_utf8(&self.buf[0..n]).unwrap());
                    return Next::read_and_write()
                }
                Err(e) => match e.kind() {
                    io::ErrorKind::WouldBlock => return Next::read_and_write(),
                    _ => {
                        println!("read error {:?}", e);
                        return Next::end()
                    }
                }
            }
        }

        Next::write()
    }

    fn on_response(&mut self, res: &mut HyperResponse) -> Next {

        match self.response {
            Ok(ref response) => {
                if let &Some(ref body) = response.body() {
                    // default set content type as html
                    res.headers_mut().set(ContentType::html());

                    // update top level headers to low level headers
                    for header in response.headers().iter() {
                        res.headers_mut()
                            .set_raw(header.name().to_owned(),
                                vec![header.value_string().as_bytes().to_vec()]);
                    }

                    // here, set hyper response status code, and headers
                    res.headers_mut().set(ContentLength(body.len() as u64));
                }

                Next::write()
            },
            Err(ref e) => {
                // Inner Error
                // end
                match e {
                    &Error::NotFound(ref path) => {

                        if self.sapp.static_service {
                            match simple_file_get(path) {
                                Ok((avec, mt_str)) => {
                                    println!("serve file: {}", path);
                                    let body_len = avec.len() as u64;
                                    self.static_file = Some(avec);
                                    // TODO: need jude file mime type according to path
                                    // and set the header
                                    // let mt_str = MTYPES.mime_for_path(Path::new(path));
                                    res.headers_mut().set_raw("Content-Type", vec![mt_str.as_bytes().to_vec()]);
                                    res.headers_mut().set(ContentLength(body_len));
                                },
                                Err(_) => {
                                    println!("NotFound: {}", path);
                                    res.set_status(StatusCode::NotFound);
                                    res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                                }
                            }
                        }
                        else {
                            println!("NotFound: {}", path);
                            res.set_status(StatusCode::NotFound);
                            res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                        }
                    },
                    &Error::Fatal(ref astr) => {
                        println!("fatal error: {}", astr);
                        res.set_status(StatusCode::InternalServerError);
                        return Next::end();
                    },
                    _ => {

                    }

                }

                Next::write()
            }
        }

    }

    fn on_response_writable(&mut self, transport: &mut Encoder<HttpStream>) -> Next {

        match self.response {
            Ok(ref response) => {
                if let &Some(ref body) = response.body() {
                    // write response.body.unwrap() to transport
                    transport.write(body).unwrap();
                }

                Next::end()
            },
            Err(ref e) => {
                match e {
                    &Error::NotFound(ref path) => {
                        if self.sapp.static_service {
                            match self.static_file {
                                Some(ref avec) => {
                                    transport.write(avec).unwrap();
                                },
                                None => {
                                    transport.write("404 Not Found".as_bytes()).unwrap();
                                }
                            }
                        }
                        else {
                            transport.write("404 Not Found".as_bytes()).unwrap();
                        }

                    },
                    _ => {

                    }
                }

                // end
                Next::end()
            }
        }

    }
}
<commit_msg>improve the response body write algorithm.<commit_after>
use std::str;
use std::io::{self, Read, Write};
use std::fs::File;
use std::path::Path;

use hyper::{Get, Post, StatusCode, RequestUri, Decoder, Encoder, Next};
use hyper::header::{ContentLength, ContentType};
use hyper::net::HttpStream;

use hyper::server::Server;
use hyper::server::Handler as HyperHandler;
use hyper::server::Request as HyperRequest;
use hyper::server::Response as HyperResponse;
use hyper::method::Method;
use hyper::version::HttpVersion;

use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::sync::Arc;
use std::marker::Reflect;
use std::clone::Clone;
use std::marker::PhantomData;

use mime_types::Types as MimeTypes;

pub use typemap::Key;
pub use hyper::header::Headers;
pub use hyper::header;
pub use hyper::mime;
pub use request::Request;
pub use response::Response;
pub use router::Router;
pub use srouter::SRouter;
pub use shandler::SHandler;

#[derive(Debug, PartialEq, Clone)]
pub enum Error {
    NotFound(String),
    InvalidConfig,
    InvalidRouterConfig,
    FileNotExist,
    ShouldRedirect(String),
    Prompt(String),
    Warning(String),
    Fatal(String),
    Custom(String),
}

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Clone)]
pub struct ReqPathParams;

pub trait SModule {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

    // here add routers ....
    fn router(&self, &mut SRouter) -> Result<()>;
    // fn router(&self, SRouter) -> Result<SRouter>;

}

pub trait SAppWrapper {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

}

// later will add more fields
pub struct SApp<T: SModule + Send + 'static, W: SAppWrapper + Send + 'static> {
    pub address: String,
    pub port:    u32,
    // for app entry, global middeware
    pub wrapper: Option<W>,
    // for actually use to recognize
    pub routers: Router,
    // do simple static file service?
    pub static_service: bool,
    // marker for type T
    pub _marker: PhantomData<T>,
}

impl<T, W> SApp<T, W>
    where   T: SModule + Send + Sync + Reflect + Clone,
            W: SAppWrapper + Send + Sync + Reflect + Clone
    {
    pub fn new() -> SApp<T, W> {
        SApp {
            address: String::new(),
            port: 0,
            wrapper: None,
            routers: Router::new(),
            static_service: true,
            _marker: PhantomData
        }
    }

    pub fn run(self) {

        let listen_addr = self.address.clone() + ":" + &self.port.to_string();
        let arc_sapp = Arc::new(Box::new(self));

        let server = Server::http(&listen_addr.parse().unwrap()).unwrap();
        let _guard = server.handle(move |_| {
            RequestHandler::new(arc_sapp.clone())
        });
    }

    pub fn with_wrapper(&mut self, w: W) -> &mut Self {
        self.wrapper = Some(w);
        self
    }

    pub fn address(&mut self, address: &str) -> &mut Self {
        self.address = address.to_owned();
        self
    }

    pub fn port(&mut self, port: u32) -> &mut Self {
        self.port = port;
        self
    }

    pub fn static_service(&mut self, open: bool) -> &mut Self {
        self.static_service = open;
        self
    }

    // add methods of this smodule
    // prefix:  such as '/user'
    pub fn add_module(&mut self, sm: T) -> &mut Self {

        let mut router = SRouter::new();
        // get the sm router
        // pass self.router in
        sm.router(&mut router).unwrap();
        // combile this router to global big router
        // create a new closure, containing
        //      0. execute sapp.before();
        //      1. execute sm.before();
        //      2. execute a_router map pair value part function;
        //      3. execute sm.after();
        //      4. execute sapp.after();
        // fill the self.routers finally
        // assign this new closure to the routers router map pair  prefix + url part

        for (method, handler_vec) in router.into_router() {
            // add to wrapped router
            for &(glob, ref handler) in handler_vec.iter() {
                let method = method.clone();
                let glob = glob.clone();
                let handler = handler.clone();
                let sm = sm.clone();
                let wrapper = self.wrapper.clone().unwrap();
                self.routers.route(method, glob, Arc::new(Box::new(move |req: &mut Request| -> Result<Response> {
                    wrapper.before(req)?;
                    sm.before(req)?;
                    let mut response: Response = handler.handle(req)?;
                    sm.after(req, &mut response)?;
                    wrapper.after(req, &mut response)?;
                    Ok(response)
                })));
            }
        }

        // self.modules.push(sm);

        self
    }
}

// this is very expensive in time
// should make it as global
lazy_static! {
    static ref MTYPES: MimeTypes = { MimeTypes::new().unwrap() };
}

fn simple_file_get(path: &str) -> Result<(Vec<u8>, String)> {
    let new_path;
    if &path[(path.len()-1)..] == "/" {
        new_path = "static/".to_owned() + path + "index.html";
    }
    else {
        new_path = "static/".to_owned() + path;
    }
    //println!("file path: {}", new_path);
    match File::open(&new_path) {
        Ok(ref mut file) => {
            let mut s: Vec<u8> = vec![];
            file.read_to_end(&mut s).unwrap_or(0);

            let mt_str = MTYPES.mime_for_path(Path::new(&new_path));

            Ok((s, mt_str.to_owned()))
        },
        Err(_) => Err(Error::FileNotExist)
    }
}

pub struct RequestHandler<
        T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static> {
    // router, keep the original handler function
    // pub router: SRouter,
    // wrapped router, keep the wrapped handler function
    // for actually use to recognize
    pub sapp: Arc<Box<SApp<T, W>>>,
    pub path: String,
    pub method: Method,
    pub version: HttpVersion,
    pub headers: Headers,
    pub buf: Vec<u8>,
    pub body: String,
    pub has_body: bool,
    pub write_pos: usize,
    // response deliver
    pub response: Result<Response>,
    pub static_file: Option<Vec<u8>>,
}

impl<T, W> RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
{
    pub fn new(sapp: Arc<Box<SApp<T, W>>>) -> RequestHandler<T, W> {
        RequestHandler {
            sapp: sapp,
            path: String::new(),
            method: Default::default(),
            version: Default::default(),
            headers: Default::default(),
            buf: vec![0; 2048],
            body: String::new(),
            has_body: false,
            write_pos: 0,
            response: Err(Error::NotFound("/".to_owned())),
            static_file: None,
        }
    }

}

impl<T, W> HyperHandler<HttpStream> for RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
 {
    fn on_request(&mut self, req: HyperRequest) -> Next {

        match *req.uri() {
            RequestUri::AbsolutePath(ref path) =>  {
                // if has_body
                if req.headers().get::<ContentLength>().is_some()
                    || req.headers().get::<ContentType>().is_some()
                 {
                    self.path = path.to_owned();
                    self.method = req.method().clone();
                    self.version = req.version().clone();
                    self.headers = req.headers().clone();
                    self.has_body = true;

                    Next::read_and_write()
                }
                else {
                    // if no body
                    let pathstr = &path[..];
                    let pathvec: Vec<&str> = pathstr.split('?').collect();
                    let path = pathvec[0].to_owned();
                    let mut query_string = None;

                    // if has query_string
                    if pathvec.len() > 1 {
                        query_string = Some(pathvec[1].to_owned());
                    }

                    // make swiftrs request from hyper request
                    let mut sreq = Request::new(
                        req.method().clone(),
                        req.version().clone(),
                        req.headers().clone(),
                        path.clone(),
                        query_string);

                    self.response = self.sapp.routers.handle_method(&mut sreq, &path).unwrap();

                    // match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    //     Ok(response) => self.response = Some(response),
                    //     Err(e) => {
                    //         if e == Error::NotFoundError {
                    //             self.response = None
                    //         }
                    //     }
                    // }

                    Next::write()
                }

                // XXX: Need more work
                // self.response = self.routers.handle_method(&mut sreq, &path).unwrap().ok();

                // TODO: complete it later
                // .unwrap_or_else(||
                    // match req.method {
                    //     method::Options => Ok(self.handle_options(&path)),
                    //     // For HEAD, fall back to GET. Hyper ensures no response body is written.
                    //     method::Head => {
                    //         req.method = method::Get;
                    //         self.handle_method(req, &path).unwrap_or(
                    //             Err(IronError::new(NoRoute, status::NotFound))
                    //         )
                    //     }
                    //     _ => Err(IronError::new(NoRoute, status::NotFound))
                    // }
                // );
                // currently

                // if is_more {
                //     Next::read_and_write()
                // } else {
                //     Next::write()
                // }

                // Next::read_and_write()
                // Next::write()

            },
            _ => Next::write()
        }
    }
    fn on_request_readable(&mut self, transport: &mut Decoder<HttpStream>) -> Next {

        if self.has_body {
            match transport.read(&mut self.buf) {
                Ok(0) => {
                    debug!("Read 0, eof");

                    // TODO: need optimize
                    let pathstr = &self.path[..];
                    let pathvec: Vec<&str> = pathstr.split('?').collect();
                    let path = pathvec[0].to_owned();
                    let mut query_string = None;

                    // if has query_string
                    if pathvec.len() > 1 {
                        query_string = Some(pathvec[1].to_owned());
                    }
                    let mut sreq = Request::new(
                        self.method.clone(),
                        self.version.clone(),
                        self.headers.clone(),
                        path.clone(),
                        query_string);

                    // TODO: optimize this memory copy
                    sreq.set_raw_body(self.body.clone());

                    self.response = self.sapp.routers.handle_method(&mut sreq, &path).unwrap();

                    // match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    //     Ok(response) => self.response = Some(response),
                    //     Err(e) => {
                    //         if e == Error::NotFoundError {
                    //             self.response = None
                    //         }
                    //     }
                    // }
                    //

                    return Next::write()
                },
                Ok(n) => {
                    self.body.push_str(str::from_utf8(&self.buf[0..n]).unwrap());
                    return Next::read_and_write()
                }
                Err(e) => match e.kind() {
                    io::ErrorKind::WouldBlock => return Next::read_and_write(),
                    _ => {
                        println!("read error {:?}", e);
                        return Next::end()
                    }
                }
            }
        }

        Next::write()
    }

    fn on_response(&mut self, res: &mut HyperResponse) -> Next {

        match self.response {
            Ok(ref response) => {
                if let &Some(ref body) = response.body() {
                    // default set content type as html
                    res.headers_mut().set(ContentType::html());

                    // update top level headers to low level headers
                    for header in response.headers().iter() {
                        res.headers_mut()
                            .set_raw(header.name().to_owned(),
                                vec![header.value_string().as_bytes().to_vec()]);
                    }

                    // here, set hyper response status code, and headers
                    res.headers_mut().set(ContentLength(body.len() as u64));
                }

                Next::write()
            },
            Err(ref e) => {
                // Inner Error
                // end
                match e {
                    &Error::NotFound(ref path) => {

                        if self.sapp.static_service {
                            match simple_file_get(path) {
                                Ok((avec, mt_str)) => {
                                    println!("serve file: {}", path);
                                    let body_len = avec.len() as u64;
                                    self.static_file = Some(avec);
                                    // TODO: need jude file mime type according to path
                                    // and set the header
                                    // let mt_str = MTYPES.mime_for_path(Path::new(path));
                                    res.headers_mut().set_raw("Content-Type", vec![mt_str.as_bytes().to_vec()]);
                                    res.headers_mut().set(ContentLength(body_len));
                                },
                                Err(_) => {
                                    println!("NotFound: {}", path);
                                    res.set_status(StatusCode::NotFound);
                                    res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                                }
                            }
                        }
                        else {
                            println!("NotFound: {}", path);
                            res.set_status(StatusCode::NotFound);
                            res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                        }
                    },
                    &Error::Fatal(ref astr) => {
                        println!("fatal error: {}", astr);
                        res.set_status(StatusCode::InternalServerError);
                        return Next::end();
                    },
                    _ => {

                    }

                }

                Next::write()
            }
        }

    }

    fn on_response_writable(&mut self, transport: &mut Encoder<HttpStream>) -> Next {

        match self.response {
            Ok(ref response) => {
                if let &Some(ref body) = response.body() {
                    // match transport.write(body)
                    // write response.body.unwrap() to transport
                    match transport.write(&body[self.write_pos..]) {
                        Ok(0) => {
                            println!("why write zero byte?");
                            Next::end()
                        },
                        Ok(n) => {
                            self.write_pos += n;
                            Next::write()
                        },
                        Err(e) => match e.kind() {
                            io::ErrorKind::WouldBlock => Next::write(),
                            _ => {
                                println!("write error {:?}", e);
                                Next::end()
                            }
                        }
                    }
                }
                else {
                    Next::end()
                }

            },
            Err(ref e) => {
                match e {
                    &Error::NotFound(ref path) => {
                        if self.sapp.static_service {
                            match self.static_file {
                                Some(ref avec) => {
                                    // transport.write(avec).unwrap();
                                    match transport.write(&avec[self.write_pos..]) {
                                        Ok(0) => {
                                            println!("why write zero byte?");
                                            Next::end()
                                        },
                                        Ok(n) => {
                                            self.write_pos += n;
                                            Next::write()
                                        },
                                        Err(e) => match e.kind() {
                                            io::ErrorKind::WouldBlock => Next::write(),
                                            _ => {
                                                println!("write error {:?}", e);
                                                Next::end()
                                            }
                                        }
                                    }
                                },
                                None => {
                                    transport.write("404 Not Found".as_bytes()).unwrap();
                                    // end
                                    Next::end()
                                }
                            }
                        }
                        else {
                            transport.write("404 Not Found".as_bytes()).unwrap();
                            Next::end()
                        }
                    },
                    _ => {
                        Next::end()
                    }
                }
            }
        }

    }
}
<|endoftext|>


<commit_before>//TODO
//should directly test the plugins, because why not?
//maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            },
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

//TODO port is fragile
fn make_owned_port_connections(ports: &[Port], size: usize, port_tag: f32, input_tag: f32, output_tag: f32) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![input_tag; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![output_tag; size]),
            ControlInput => OwnedPortData::ControlInput(port_tag),
            ControlOutput => OwnedPortData::ControlOutput(port_tag),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => PortData::ControlOutput(RefCell::new(data)),
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

//TODO immediately: factor

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;
    test_sample_count(sample_count, 0);
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE*4;
    test_sample_count(sample_count, 1);
}

fn test_sample_count(sample_count: usize, port: u8) {
    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, port as f32, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, port as f32, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<commit_msg>dead todo<commit_after>//TODO
//should directly test the plugins, because why not?
//maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            },
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

//TODO port is fragile
fn make_owned_port_connections(ports: &[Port], size: usize, port_tag: f32, input_tag: f32, output_tag: f32) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![input_tag; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![output_tag; size]),
            ControlInput => OwnedPortData::ControlInput(port_tag),
            ControlOutput => OwnedPortData::ControlOutput(port_tag),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => PortData::ControlOutput(RefCell::new(data)),
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;
    test_sample_count(sample_count, 0);
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE*4;
    test_sample_count(sample_count, 1);
}

fn test_sample_count(sample_count: usize, port: u8) {
    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, port as f32, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, port as f32, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<|endoftext|>


<commit_before>
use timer::{oneshot_ms};
use time::SteadyTime;

struct ElapsedChecker {
    start: SteadyTime
}

impl ElapsedChecker {
    fn new() -> ElapsedChecker {
        ElapsedChecker {
            start: SteadyTime::now()
        }
    }

    fn check(&self, expected_ms: i64) {
        let actual_elapsed_ms = (SteadyTime::now() - self.start).num_milliseconds();
        assert!(actual_elapsed_ms-100 < expected_ms, "Elapsed too late: {}ms instead of {}ms", actual_elapsed_ms, expected_ms);
        assert!(actual_elapsed_ms+100 > expected_ms, "Elapsed too soon: {}ms instead of {}ms", actual_elapsed_ms, expected_ms);
    }
}

#[test]
fn simple_wait() {
    let checker = ElapsedChecker::new();
    let timer = oneshot_ms(1400);
    timer.recv().unwrap();
    checker.check(1400);
}
<commit_msg>Add some more complicated tests<commit_after>
use timer::{oneshot_ms, periodic_ms};
use time::SteadyTime;

struct ElapsedChecker {
    start: SteadyTime
}

impl ElapsedChecker {
    fn new() -> ElapsedChecker {
        ElapsedChecker {
            start: SteadyTime::now()
        }
    }

    fn check(&self, expected_ms: i64) {
        let actual_elapsed_ms = (SteadyTime::now() - self.start).num_milliseconds();
        assert!(actual_elapsed_ms-100 < expected_ms, "Elapsed too late: {}ms instead of {}ms", actual_elapsed_ms, expected_ms);
        assert!(actual_elapsed_ms+100 > expected_ms, "Elapsed too soon: {}ms instead of {}ms", actual_elapsed_ms, expected_ms);
    }
}

#[test]
fn simple_wait() {
    let checker = ElapsedChecker::new();
    let timer = oneshot_ms(1400);
    timer.recv().unwrap();
    checker.check(1400);
}

#[test]
fn several_concurrent_waits() {
    let checker = ElapsedChecker::new();
    let medium = oneshot_ms(1400);
    let short = oneshot_ms(300);
    let long = oneshot_ms(2000);
    short.recv().unwrap();
    checker.check(300);

    medium.recv().unwrap();
    checker.check(1400);

    long.recv().unwrap();
    checker.check(2000);
}

#[test]
fn several_concurrent_waits_misordered() {
    let checker = ElapsedChecker::new();
    let medium = oneshot_ms(1400);
    let short = oneshot_ms(300);
    let long = oneshot_ms(2000);

    // We wait for the last timer before we check the others,
    // so they should all recv immediately after the first one.
    long.recv().unwrap();
    checker.check(2000);

    short.recv().unwrap();
    checker.check(2000);

    medium.recv().unwrap();
    checker.check(2000);
}

#[test]
fn simple_periodic() {
    let checker = ElapsedChecker::new();
    let p = periodic_ms(200);

    for i in (1..10) {
        p.recv().unwrap();
        checker.check(i*200);
    }
}
<|endoftext|>