<commit_before>use std::io::{IoError, IoErrorKind, Reader};
use std::io::fs::File;

struct Frame;

// TODO: there should be a way to signal IO error.
// This will be handled by the error reform RFCs, I think.
// For now, use IO error to indicate any failure.
type Error = IoError;

fn mk_err() -> Error {
    IoError {
        kind: IoErrorKind::OtherIoError,
        desc: "FLAC decoding error",
        detail: None
    }
}

struct FlacStream {
    metadata_blocks: Vec<MetadataBlock>
}

#[cfg(test)]
fn get_foo_file() -> File {
    File::open(&Path::new("foo.flac")).unwrap()
}

fn read_stream_header(input: &mut Reader) -> Result<(), Error> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const HEADER: u32 = 0x66_4c_61_43;
    let header = try!(input.read_be_u32());
    if header != HEADER { return Err(mk_err()); } // TODO: provide more error info.
    Ok(())
}

#[test]
fn test_read_stream_header() {
    let mut input = get_foo_file();
    read_stream_header(&mut input).unwrap();
}

struct StreamInfo {
    pub min_block_size: u16,
    pub max_block_size: u16,
    pub min_frame_size: Option<u32>,
    pub max_frame_size: Option<u32>,
    pub sample_rate: u32,
    pub n_channels: u8,
    pub bits_per_sample: u8,
    pub n_samples: Option<u64>,
    pub md5_signature: [u8, ..16]
}

struct Seekpoint {
    pub sample: u64,
    pub offset: u64,
    pub n_samples: u16
}

struct SeekTable {
    seekpoints: Vec<Seekpoint>
}

enum MetadataBlock {
    StreamInfoBlock(StreamInfo),
    PaddingBlock(u32),
    ApplicationBlock(u32, Vec<u8>),
    SeekTableBlock(SeekTable),
    VorbisCommentBlock, // TODO
    CuesheetBlock, // TODO
    PictureBlock // TODO
}

struct MetadataBlockHeader {
    is_last: bool,
    block_type: u8,
    length: u32
}

fn read_metadata_block_header(input: &mut Reader) -> Result<MetadataBlockHeader, Error> {
    let byte = try!(input.read_u8());

    // The first bit specifies whether this is the last block, the next 7 bits
    // specify the type of the metadata block to follow.
    let is_last = (byte & 1) == 1;
    let block_type = byte >> 1;

    if block_type == 127 { return Err(mk_err()); } // TODO: "invalid, to avoid confusion with a frame sync code"
    if block_type > 6 { return Err(mk_err()); } // TODO: "reserved"

    // TODO: extend reader to be able to read u24 or maybe arbitrary size ingers.
    let length_msb = try!(input.read_u8());
    let length_lsb = try!(input.read_be_u16());
    let length = length_msb as u32 << 16 | length_lsb as u32;

    let header = MetadataBlockHeader {
        is_last: is_last,
        block_type: block_type,
        length: length
    };
    Ok(header)
}

impl FlacStream {
    pub fn new(input: &mut Reader) -> Result<FlacStream, Error> {
        try!(read_stream_header(input));

        let hdr = try!(read_metadata_block_header(input));
        println!("type: {}, length: {}, last: {}",
                 hdr.block_type, hdr.length, hdr.is_last);
        // Read the STREAMINFO block
        // Read any metadata
        // Read frames

        let flac_stream = FlacStream {
            metadata_blocks: Vec::new()
        };

        Ok(flac_stream)
    }
}

#[test]
fn test_open_stream() {
    let mut input = get_foo_file();
    let flac_stream = FlacStream::new(&mut input).unwrap();
}
<commit_msg>WIP -- working on reading STREAMINFO block<commit_after>use std::io::{IoResult, IoError, IoErrorKind, Reader};
use std::io::fs::File;

struct Frame;

// TODO: there should be a way to signal IO error.
// This will be handled by the error reform RFCs, I think.
// For now, use IO error to indicate any failure.
type Error = IoError;

fn mk_err() -> Error {
    IoError {
        kind: IoErrorKind::OtherIoError,
        desc: "FLAC decoding error",
        detail: None
    }
}

struct FlacStream {
    metadata_blocks: Vec<MetadataBlock>
}

#[cfg(test)]
fn get_foo_file() -> File {
    File::open(&Path::new("foo.flac")).unwrap()
}

fn read_stream_header(input: &mut Reader) -> Result<(), Error> {
    // A FLAC stream starts with a 32-bit header 'fLaC' (big endian).
    const HEADER: u32 = 0x66_4c_61_43;
    let header = try!(input.read_be_u32());
    if header != HEADER { return Err(mk_err()); } // TODO: provide more error info.
    Ok(())
}

#[test]
fn test_read_stream_header() {
    let mut input = get_foo_file();
    read_stream_header(&mut input).unwrap();
}

struct StreamInfo {
    pub min_block_size: u16,
    pub max_block_size: u16,
    pub min_frame_size: Option<u32>,
    pub max_frame_size: Option<u32>,
    pub sample_rate: u32,
    pub n_channels: u8,
    pub bits_per_sample: u8,
    pub n_samples: Option<u64>,
    pub md5_signature: [u8, ..16]
}

struct Seekpoint {
    pub sample: u64,
    pub offset: u64,
    pub n_samples: u16
}

struct SeekTable {
    seekpoints: Vec<Seekpoint>
}

enum MetadataBlock {
    StreamInfoBlock(StreamInfo),
    PaddingBlock(u32),
    ApplicationBlock(u32, Vec<u8>),
    SeekTableBlock(SeekTable),
    VorbisCommentBlock, // TODO
    CuesheetBlock, // TODO
    PictureBlock // TODO
}

struct MetadataBlockHeader {
    is_last: bool,
    block_type: u8,
    length: u32
}

fn read_metadata_block_header(input: &mut Reader) -> Result<MetadataBlockHeader, Error> {
    let byte = try!(input.read_u8());

    // The first bit specifies whether this is the last block, the next 7 bits
    // specify the type of the metadata block to follow.
    let is_last = (byte & 1) == 1;
    let block_type = byte >> 1;

    if block_type == 127 { return Err(mk_err()); } // TODO: "invalid, to avoid confusion with a frame sync code"
    if block_type > 6 { return Err(mk_err()); } // TODO: "reserved"

    // The length field is 24 bits, or 3 bytes.
    let length = try!(input.read_be_uint_n(3)) as u32;

    let header = MetadataBlockHeader {
        is_last: is_last,
        block_type: block_type,
        length: length
    };
    Ok(header)
}

fn read_streaminfo_block(input: &mut Reader) -> Result<StreamInfo, Error> {
    let min_block_size = try!(input.read_be_u16());
    let max_block_size = try!(input.read_be_u16());
    // The frame size fields are 24 bits, or 3 bytes.
    let min_frame_size = try!(input.read_be_uint_n(3)) as u32;
    let max_frame_size = try!(input.read_be_uint_n(3)) as u32;

    // Sample data is packed as 20 bits sample rate, 3 bits #channels - 1,
    // 5 bits #bits per sample - 1, 36 bits #samples in stream.
    let sample_rate_msb = try!(input.read_be_u16());
    let sample_rate_lsb = try!(input.read_byte());
    // Stitch together the value from the first 16 bits,
    // and then 4 bits of the next byte.
    let sample_rate = sample_rate_msb as u32 << 4 | sample_rate_lsb as u32 >> 4;
    // Next three bits are the number of channels - 1; mask out and add 1.
    let n_channels = ((sample_rate_lsb >> 1) & 0x7) + 1;
    // The final bit is the most significant of bits per sample - 1
    let bps_msb = sample_rate_lsb & 1;
    let bps_lsb = try!(input.read_byte());
    // Stitch together these values, add 1 because # - 1 is stored.
    let bits_per_sample = (bps_msb << 5 | (bps_lsb >> 4)) + 1;
    // Number of samples in 36 bits, we have 4, 32 to go.
    let n_samples_lsb = try!(input.read_be_u32());
    let n_samples = (bps_lsb & 0xf) as u64 << 32 | n_samples_lsb as u64;

    let md5_signature = try!(input.read_exact(16));
}

impl FlacStream {
    pub fn new(input: &mut Reader) -> Result<FlacStream, Error> {
        try!(read_stream_header(input));

        let hdr = try!(read_metadata_block_header(input));
        println!("type: {}, length: {}, last: {}",
                 hdr.block_type, hdr.length, hdr.is_last);
        // Read the STREAMINFO block
        // Read any metadata
        // Read frames

        let flac_stream = FlacStream {
            metadata_blocks: Vec::new()
        };

        Ok(flac_stream)
    }
}

#[test]
fn test_open_stream() {
    let mut input = get_foo_file();
    let flac_stream = FlacStream::new(&mut input).unwrap();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;

pub mod parser;
pub mod ast;
<commit_msg>Make error module public<commit_after>#[macro_use]
extern crate nom;

pub mod parser;
pub mod ast;
pub mod error;
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! The official Piston window back-end for the Piston game engine

extern crate glutin_window;
extern crate piston;

use std::cell::RefCell;
use std::rc::Rc;
use std::any::Any;

use glutin_window::GlutinWindow;
use piston::{ event, window };

/// The type of event emitted from event loop.
pub type PistonEvent = event::Event<<GlutinWindow as window::Window>::Event>;

/// Contains everything required for controlling window, graphics, event loop.
#[derive(Clone)]
pub struct PistonWindow<T = ()> {
    /// The window.
    pub window: Rc<RefCell<GlutinWindow>>,
    /// The event loop.
    pub events: Rc<RefCell<event::events::Events<GlutinWindow, PistonEvent>>>,
    /// The event.
    pub event: Option<PistonEvent>,
    /// Application structure.
    pub app: Rc<RefCell<T>>,
}

impl<T> PistonWindow<T> {
    /// Creates a new piston object.
    pub fn new(window: Rc<RefCell<GlutinWindow>>, app: Rc<RefCell<T>>) -> Self {
        use piston::event::Events;

        PistonWindow {
            window: window.clone(),
            events: Rc::new(RefCell::new(window.events())),
            event: None,
            app: app,
        }
    }
}

impl Iterator for PistonWindow {
    type Item = PistonWindow;

    fn next(&mut self) -> Option<PistonWindow> {
        if let Some(e) = self.events.borrow_mut().next() {
            Some(PistonWindow {
                window: self.window.clone(),
                events: self.events.clone(),
                event: Some(e),
                app: self.app.clone(),
            })
        } else { None }
    }
}

impl event::GenericEvent for PistonWindow {
    fn event_id(&self) -> event::EventId {
        match self.event {
            Some(ref e) => e.event_id(),
            None => event::EventId("")
        }
    }

    fn with_args<'a, F, U>(&'a self, f: F) -> U
       where F: FnMut(&Any) -> U
    {
        self.event.as_ref().unwrap().with_args(f)
    }

    fn from_args(event_id: event::EventId, any: &Any, old_event: &Self) -> Option<Self> {
        if let Some(ref e) = old_event.event {
            match event::GenericEvent::from_args(event_id, any, e) {
                Some(e) => {
                    Some(PistonWindow {
                        window: old_event.window.clone(),
                        events: old_event.events.clone(),
                        event: Some(e),
                        app: old_event.app.clone(),
                    })
                }
                None => None
            }
        } else { None }
    }
}

impl window::Window for PistonWindow {
    type Event = <GlutinWindow as window::Window>::Event;

    fn should_close(&self) -> bool { self.window.borrow().should_close() }
    fn size(&self) -> window::Size { self.window.borrow().size() }
    fn draw_size(&self) -> window::Size { self.window.borrow().draw_size() }
    fn swap_buffers(&mut self) { self.window.borrow_mut().swap_buffers() }
    fn poll_event(&mut self) -> Option<Self::Event> {
        window::Window::poll_event(&mut *self.window.borrow_mut())
    }
}

impl window::AdvancedWindow for PistonWindow {
    fn get_title(&self) -> String { self.window.borrow().get_title() }
    fn set_title(&mut self, title: String) {
        self.window.borrow_mut().set_title(title)
    }
    fn get_exit_on_esc(&self) -> bool { self.window.borrow().get_exit_on_esc() }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.window.borrow_mut().set_exit_on_esc(value)
    }
    fn set_capture_cursor(&mut self, value: bool) {
        self.window.borrow_mut().set_capture_cursor(value)
    }
}

/// Creates a new empty application.
pub fn empty_app() -> Rc<RefCell<()>> { Rc::new(RefCell::new(())) }
<commit_msg>Added `PistonWindow::app`<commit_after>#![deny(missing_docs)]

//! The official Piston window back-end for the Piston game engine

extern crate glutin_window;
extern crate piston;

use std::cell::RefCell;
use std::rc::Rc;
use std::any::Any;

use glutin_window::GlutinWindow;
use piston::{ event, window };

/// The type of event emitted from event loop.
pub type PistonEvent = event::Event<<GlutinWindow as window::Window>::Event>;

/// Contains everything required for controlling window, graphics, event loop.
#[derive(Clone)]
pub struct PistonWindow<T = ()> {
    /// The window.
    pub window: Rc<RefCell<GlutinWindow>>,
    /// The event loop.
    pub events: Rc<RefCell<event::events::Events<GlutinWindow, PistonEvent>>>,
    /// The event.
    pub event: Option<PistonEvent>,
    /// Application structure.
    pub app: Rc<RefCell<T>>,
}

impl<T> PistonWindow<T> {
    /// Creates a new piston object.
    pub fn new(window: Rc<RefCell<GlutinWindow>>, app: Rc<RefCell<T>>) -> Self {
        use piston::event::Events;

        PistonWindow {
            window: window.clone(),
            events: Rc::new(RefCell::new(window.events())),
            event: None,
            app: app,
        }
    }

    /// Changes application structure.
    pub fn app<U>(self, app: Rc<RefCell<U>>) -> PistonWindow<U> {
        PistonWindow {
            window: self.window.clone(),
            events: self.events.clone(),
            event: self.event,
            app: app,
        }
    }
}

impl Iterator for PistonWindow {
    type Item = PistonWindow;

    fn next(&mut self) -> Option<PistonWindow> {
        if let Some(e) = self.events.borrow_mut().next() {
            Some(PistonWindow {
                window: self.window.clone(),
                events: self.events.clone(),
                event: Some(e),
                app: self.app.clone(),
            })
        } else { None }
    }
}

impl event::GenericEvent for PistonWindow {
    fn event_id(&self) -> event::EventId {
        match self.event {
            Some(ref e) => e.event_id(),
            None => event::EventId("")
        }
    }

    fn with_args<'a, F, U>(&'a self, f: F) -> U
       where F: FnMut(&Any) -> U
    {
        self.event.as_ref().unwrap().with_args(f)
    }

    fn from_args(event_id: event::EventId, any: &Any, old_event: &Self) -> Option<Self> {
        if let Some(ref e) = old_event.event {
            match event::GenericEvent::from_args(event_id, any, e) {
                Some(e) => {
                    Some(PistonWindow {
                        window: old_event.window.clone(),
                        events: old_event.events.clone(),
                        event: Some(e),
                        app: old_event.app.clone(),
                    })
                }
                None => None
            }
        } else { None }
    }
}

impl window::Window for PistonWindow {
    type Event = <GlutinWindow as window::Window>::Event;

    fn should_close(&self) -> bool { self.window.borrow().should_close() }
    fn size(&self) -> window::Size { self.window.borrow().size() }
    fn draw_size(&self) -> window::Size { self.window.borrow().draw_size() }
    fn swap_buffers(&mut self) { self.window.borrow_mut().swap_buffers() }
    fn poll_event(&mut self) -> Option<Self::Event> {
        window::Window::poll_event(&mut *self.window.borrow_mut())
    }
}

impl window::AdvancedWindow for PistonWindow {
    fn get_title(&self) -> String { self.window.borrow().get_title() }
    fn set_title(&mut self, title: String) {
        self.window.borrow_mut().set_title(title)
    }
    fn get_exit_on_esc(&self) -> bool { self.window.borrow().get_exit_on_esc() }
    fn set_exit_on_esc(&mut self, value: bool) {
        self.window.borrow_mut().set_exit_on_esc(value)
    }
    fn set_capture_cursor(&mut self, value: bool) {
        self.window.borrow_mut().set_capture_cursor(value)
    }
}

/// Creates a new empty application.
pub fn empty_app() -> Rc<RefCell<()>> { Rc::new(RefCell::new(())) }
<|endoftext|>


<commit_before>//! Elasticsearch Response Iterators
//!
//! A crate to handle parsing and handling Elasticsearch search results which provides
//! convenient iterators to step through the results returned. It is designed to work
//! with [`elastic-reqwest`](https://github.com/elastic-rs/elastic-hyper/).
//!
//! ## Usage
//!
//! Query your Elasticsearch Cluster, then iterate through the results
//!
//! ```no_run
//! # extern crate elastic_responses;
//! # use elastic_responses::SearchResponse;
//! # fn do_request() -> SearchResponse { unimplemented!() }
//! # fn main() {
//! // Send a request (omitted, see `samples/basic`), and read the response.
//! // Parse body to JSON as an elastic_responses::SearchResponse object
//! let body_as_json: SearchResponse = do_request();
//!
//! // Use hits() or aggs() iterators
//! // Hits
//! for i in body_as_json.hits() {
//!   println!("{:?}",i);
//! }
//!
//! // Agregations
//! for i in body_as_json.aggs() {
//!   println!("{:?}",i);
//! }
//! # }
//! ```

#![feature(custom_derive, custom_attribute)]

#[macro_use]
extern crate log;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate quick_error;

extern crate serde;
extern crate serde_json;

extern crate slog_stdlog;
extern crate slog_envlogger;

/// Error types from Elasticsearch
pub mod error;

/// Response type parsing.
pub mod parse;

mod get;
mod search;

pub use self::get::*;
pub use self::search::*;

use std::io::Read;

use error::*;

/// A raw HTTP response with enough information to parse
/// a concrete type from it.
pub struct HttpResponse<R> {
    code: u16,
    body: R,
}

impl<R> HttpResponse<R> {
    /// Create a new HTTP response from the given status code
    /// and body.
    pub fn new(status: u16, body: R) -> Self {
        HttpResponse {
            code: status,
            body: body,
        }
    }

    /// Get the status code.
    pub fn status(&self) -> u16 {
        self.code
    }
}

type ApiResult<T> = Result<T, ResponseError>;

/// Convert a response message into a either a success
/// or failure result.
pub trait FromResponse
    where Self: Sized
{
    fn from_response<I: Into<HttpResponse<R>>, R: Read>(res: I) -> ApiResult<Self>;
}
<commit_msg>remove unneeded features<commit_after>//! Elasticsearch Response Iterators
//!
//! A crate to handle parsing and handling Elasticsearch search results which provides
//! convenient iterators to step through the results returned. It is designed to work
//! with [`elastic-reqwest`](https://github.com/elastic-rs/elastic-hyper/).
//!
//! ## Usage
//!
//! Query your Elasticsearch Cluster, then iterate through the results
//!
//! ```no_run
//! # extern crate elastic_responses;
//! # use elastic_responses::SearchResponse;
//! # fn do_request() -> SearchResponse { unimplemented!() }
//! # fn main() {
//! // Send a request (omitted, see `samples/basic`), and read the response.
//! // Parse body to JSON as an elastic_responses::SearchResponse object
//! let body_as_json: SearchResponse = do_request();
//!
//! // Use hits() or aggs() iterators
//! // Hits
//! for i in body_as_json.hits() {
//!   println!("{:?}",i);
//! }
//!
//! // Agregations
//! for i in body_as_json.aggs() {
//!   println!("{:?}",i);
//! }
//! # }
//! ```

#[macro_use]
extern crate log;

#[macro_use]
extern crate serde_derive;

#[macro_use]
extern crate quick_error;

extern crate serde;
extern crate serde_json;

extern crate slog_stdlog;
extern crate slog_envlogger;

/// Error types from Elasticsearch
pub mod error;

/// Response type parsing.
pub mod parse;

mod get;
mod search;

pub use self::get::*;
pub use self::search::*;

use std::io::Read;

use error::*;

/// A raw HTTP response with enough information to parse
/// a concrete type from it.
pub struct HttpResponse<R> {
    code: u16,
    body: R,
}

impl<R> HttpResponse<R> {
    /// Create a new HTTP response from the given status code
    /// and body.
    pub fn new(status: u16, body: R) -> Self {
        HttpResponse {
            code: status,
            body: body,
        }
    }

    /// Get the status code.
    pub fn status(&self) -> u16 {
        self.code
    }
}

type ApiResult<T> = Result<T, ResponseError>;

/// Convert a response message into a either a success
/// or failure result.
pub trait FromResponse
    where Self: Sized
{
    fn from_response<I: Into<HttpResponse<R>>, R: Read>(res: I) -> ApiResult<Self>;
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "unstable", feature(plugin))]
#![cfg_attr(feature = "unstable", plugin(clippy))]

//! An implementation of the [Shoemake Arcball Camera](https://www.talisman.org/~erlkonig/misc/shoemake92-arcball.pdf)
//! using [cgmath](https://crates.io/crates/cgmath). See the
//! [cube example](https://github.com/Twinklebear/arcball/blob/master/examples/cube.rs) for an example
//! of use with [glium](https://crates.io/crates/glium).
extern crate cgmath;

use cgmath::prelude::*;
use cgmath::{Matrix4, Quaternion, Vector2, Vector3};

/// The Shoemake Arcball camera.
pub struct ArcballCamera {
    look_at: Matrix4<f32>,
    translation: Matrix4<f32>,
    rotation: Quaternion<f32>,
    camera: Matrix4<f32>,
    inv_camera: Matrix4<f32>,
    motion_speed: f32,
    zoom_speed: f32,
    inv_screen: [f32; 2],
}

impl ArcballCamera {
    /// Create a new Arcball camera starting from the look at matrix `look_at`. The `motion_speed`
    /// sets the speed for panning and `zoom_speed` the speed for zooming the camera. `screen` should be
    /// `[screen_width, screen_height]`
    pub fn new(look_at: &Matrix4<f32>, motion_speed: f32, zoom_speed: f32, screen: [f32; 2]) -> ArcballCamera {
        ArcballCamera {
            look_at: *look_at,
            translation: Transform::one(),
            rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0),
            camera: *look_at,
            inv_camera: look_at.invert().unwrap(),
            motion_speed: motion_speed,
            zoom_speed: zoom_speed,
            inv_screen: [1.0 / screen[0], 1.0 / screen[1]],
        }
    }
    /// Get the view matrix computed by the camera.
    pub fn get_mat4(&self) -> Matrix4<f32> {
        self.camera
    }
    /// Rotate the camera, mouse positions should be in pixel coordinates.
    ///
    /// Rotates starting from the orientation at the previous mouse position, `mouse_prev`,
    /// and rotating to desired orientation at the current mouse position, `mouse_cur`.
    pub fn rotate(&mut self, mouse_prev: Vector2<f32>, mouse_cur: Vector2<f32>) {
        let m_cur = Vector2::new(clamp(mouse_cur.x * 2.0 * self.inv_screen[0] - 1.0, -1.0, 1.0),
                                    clamp(1.0 - 2.0 * mouse_cur.y * self.inv_screen[1], -1.0, 1.0));
        let m_prev = Vector2::new(clamp(mouse_prev.x * 2.0 * self.inv_screen[0] - 1.0, -1.0, 1.0),
                                    clamp(1.0 - 2.0 * mouse_prev.y * self.inv_screen[1], -1.0, 1.0));
        let mouse_cur_ball = ArcballCamera::screen_to_arcball(m_cur);
        let mouse_prev_ball = ArcballCamera::screen_to_arcball(m_prev);
        self.rotation = mouse_cur_ball * mouse_prev_ball * self.rotation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Zoom the camera in by some amount, positive values zoom in, negative zoom out.
    pub fn zoom(&mut self, amount: f32, elapsed: f32) {
        let motion = Vector3::new(0.0, 0.0, amount);
        self.translation = Matrix4::from_translation(motion * self.zoom_speed * elapsed) * self.translation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Pan the camera following the delta motion of the mouse. Mouse delta should be in pixels.
    pub fn pan(&mut self, mouse_delta: Vector2<f32>, elapsed: f32) {
        let motion = Vector3::new(mouse_delta.x, mouse_delta.y, 0.0) * self.motion_speed * elapsed;
        self.translation = Matrix4::from_translation(motion) * self.translation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Update the screen dimensions if the window has resized.
    pub fn update_screen(&mut self, width: f32, height: f32) {
        self.inv_screen[0] = 1.0 / width;
        self.inv_screen[1] = 1.0 / height;
    }
    fn screen_to_arcball(p: Vector2<f32>) -> Quaternion<f32> {
        let dist = cgmath::dot(p, p);
        // If we're on/in the sphere return the point on it
        if dist <= 1.0 {
            Quaternion::new(0.0, p.x, p.y, f32::sqrt(1.0 - dist))
        } else {
            let unit_p = p.normalize();
            Quaternion::new(0.0, unit_p.x, unit_p.y, 0.0)
        }
    }
}

fn clamp(x: f32, min: f32, max: f32) -> f32 {
    if x < min {
        min
    } else if x > max {
        max
    } else {
        x
    }
}

<commit_msg>Fix some typos and wording in the docs<commit_after>#![cfg_attr(feature = "unstable", feature(plugin))]
#![cfg_attr(feature = "unstable", plugin(clippy))]

//! An implementation of the [Shoemake Arcball Camera](https://www.talisman.org/~erlkonig/misc/shoemake92-arcball.pdf)
//! using [cgmath](https://crates.io/crates/cgmath). See the
//! [cube example](https://github.com/Twinklebear/arcball/blob/master/examples/cube.rs) for an example
//! of use with [glium](https://crates.io/crates/glium).
extern crate cgmath;

use cgmath::prelude::*;
use cgmath::{Matrix4, Quaternion, Vector2, Vector3};

/// The Shoemake Arcball camera.
pub struct ArcballCamera {
    look_at: Matrix4<f32>,
    translation: Matrix4<f32>,
    rotation: Quaternion<f32>,
    camera: Matrix4<f32>,
    inv_camera: Matrix4<f32>,
    motion_speed: f32,
    zoom_speed: f32,
    inv_screen: [f32; 2],
}

impl ArcballCamera {
    /// Create a new Arcball camera starting from the look at matrix `look_at`. The `motion_speed`
    /// sets the speed for panning and `zoom_speed` the speed for zooming the camera. `screen` should be
    /// `[screen_width, screen_height]`.
    pub fn new(look_at: &Matrix4<f32>, motion_speed: f32, zoom_speed: f32, screen: [f32; 2]) -> ArcballCamera {
        ArcballCamera {
            look_at: *look_at,
            translation: Transform::one(),
            rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0),
            camera: *look_at,
            inv_camera: look_at.invert().unwrap(),
            motion_speed: motion_speed,
            zoom_speed: zoom_speed,
            inv_screen: [1.0 / screen[0], 1.0 / screen[1]],
        }
    }
    /// Get the view matrix computed by the camera.
    pub fn get_mat4(&self) -> Matrix4<f32> {
        self.camera
    }
    /// Rotate the camera, mouse positions should be in pixel coordinates.
    ///
    /// Rotates from the orientation at the previous mouse position specified by `mouse_prev`
    /// to the orientation at the current mouse position, `mouse_cur`.
    pub fn rotate(&mut self, mouse_prev: Vector2<f32>, mouse_cur: Vector2<f32>) {
        let m_cur = Vector2::new(clamp(mouse_cur.x * 2.0 * self.inv_screen[0] - 1.0, -1.0, 1.0),
                                    clamp(1.0 - 2.0 * mouse_cur.y * self.inv_screen[1], -1.0, 1.0));
        let m_prev = Vector2::new(clamp(mouse_prev.x * 2.0 * self.inv_screen[0] - 1.0, -1.0, 1.0),
                                    clamp(1.0 - 2.0 * mouse_prev.y * self.inv_screen[1], -1.0, 1.0));
        let mouse_cur_ball = ArcballCamera::screen_to_arcball(m_cur);
        let mouse_prev_ball = ArcballCamera::screen_to_arcball(m_prev);
        self.rotation = mouse_cur_ball * mouse_prev_ball * self.rotation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Zoom the camera in by some amount. Positive values zoom in, negative zoom out.
    pub fn zoom(&mut self, amount: f32, elapsed: f32) {
        let motion = Vector3::new(0.0, 0.0, amount);
        self.translation = Matrix4::from_translation(motion * self.zoom_speed * elapsed) * self.translation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Pan the camera following the motion of the mouse. The mouse delta should be in pixels.
    pub fn pan(&mut self, mouse_delta: Vector2<f32>, elapsed: f32) {
        let motion = Vector3::new(mouse_delta.x, mouse_delta.y, 0.0) * self.motion_speed * elapsed;
        self.translation = Matrix4::from_translation(motion) * self.translation;
        self.camera = self.translation * self.look_at * Matrix4::from(self.rotation);
        self.inv_camera = self.camera.invert().unwrap();
    }
    /// Update the screen dimensions, e.g. if the window has resized.
    pub fn update_screen(&mut self, width: f32, height: f32) {
        self.inv_screen[0] = 1.0 / width;
        self.inv_screen[1] = 1.0 / height;
    }
    fn screen_to_arcball(p: Vector2<f32>) -> Quaternion<f32> {
        let dist = cgmath::dot(p, p);
        // If we're on/in the sphere return the point on it
        if dist <= 1.0 {
            Quaternion::new(0.0, p.x, p.y, f32::sqrt(1.0 - dist))
        } else {
            let unit_p = p.normalize();
            Quaternion::new(0.0, unit_p.x, unit_p.y, 0.0)
        }
    }
}

fn clamp(x: f32, min: f32, max: f32) -> f32 {
    if x < min {
        min
    } else if x > max {
        max
    } else {
        x
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2016
// Jeff Nettleton
//
// Licensed under the MIT license (http://opensource.org/licenses/MIT). This
// file may not be copied, modified, or distributed except according to those
// terms

//! # Canteen
//!
//! ## Description
//!
//! A pure Rust clone of [Flask](http://flask.pocoo.org), a simple but powerful Python
//! web framework.
//!
//! ## Example
//!
//! The principle behind Canteen is simple -- handler functions are defined as simple
//! Rust functions that take a `Request` and return a `Response`. Handlers are then attached
//! to one or more routes and HTTP methods/verbs. Routes are specified using a simple
//! syntax that lets you define variables within them; variables that can then be
//! extracted to perform various operations. Currently, the following variable types can
//! be used:
//!
//! - `<str:name>` will match anything inside a path segment, returns a `String`
//! - `<int:name>` will return a signed integer (`i32`) from a path segment
//!   - ex: `cnt.add_route("/api/foo/<int:foo_id>", &[Method::Get], my_handler)` will match
//!   `"/api/foo/123"` but not `"/api/foo/123.34"` or `"/api/foo/bar"`
//! - `<uint:name>` will return an unsigned integer (`u32`)
//! - `<float:name>` does the same thing as the `int` parameter definition, but matches numbers
//! with decimal points and returns an `f32`
//! - `<path:name>` will greedily take all path data contained, returns a `String`
//!   - ex: `cnt.add_route("/static/<path:name>", &[Method::Get], utils::static_file)` will
//!   serve anything in the `/static/` directory as a file
//!
//! ```rust
//! extern crate canteen;
//!
//! use canteen::{Canteen, Request, Response, Method};
//! use canteen::utils;
//!
//! fn hello_handler(req: &Request) -> Response {
//!     let mut res = Response::new();
//!
//!     res.set_status(200);
//!     res.set_content_type("text/plain");
//!     res.append("Hello, world!");
//!
//!     res
//! }
//!
//! fn double_handler(req: &Request) -> Response {
//!     let to_dbl: i32 = req.get("to_dbl");
//!
//!     /* simpler response generation syntax */
//!     utils::make_response(format!("{}", to_dbl * 2), "text/plain", 200)
//! }
//!
//! fn main() {
//!     let mut cnt = Canteen::new(("127.0.0.1", 8080));
//!
//!     // set the default route handler to show a 404 message
//!     cnt.set_default(utils::err_404);
//!
//!     // respond to requests to / with "Hello, world!"
//!     cnt.add_route("/", &[Method::Get], hello_handler);
//!
//!     // pull a variable from the path and do something with it
//!     cnt.add_route("/double/<int:to_dbl>", &[Method::Get], double_handler);
//!
//!     // serve raw files from the /static/ directory
//!     cnt.add_route("/static/<path:path>", &[Method::Get], utils::static_file);
//!
//!     /* cnt.run() */;
//! }
//! ```

extern crate mio;
extern crate regex;
extern crate chrono;
extern crate rustc_serialize;

pub mod utils;
pub mod route;
pub mod request;
pub mod response;

use std::io::Result;
use std::io::prelude::*;
use std::net::ToSocketAddrs;
use std::collections::HashMap;
use std::collections::HashSet;
use mio::tcp::{TcpListener, TcpStream};
use mio::util::Slab;
use mio::*;

pub use request::*;
pub use response::*;

struct Client {
    sock:   TcpStream,
    token:  Token,
    events: EventSet,
    i_buf:  Vec<u8>,
    o_buf:  Vec<u8>,
}

impl Client {
    fn new(sock: TcpStream, token: Token) -> Client {
        Client {
            sock:   sock,
            token:  token,
            events: EventSet::hup(),
            i_buf:  Vec::with_capacity(2048),
            o_buf:  Vec::with_capacity(2048),
        }
    }

    fn receive(&mut self) -> Result<bool> {
        let mut buf: Vec<u8> = Vec::with_capacity(2048);

        match self.sock.try_read_buf(&mut buf) {
            Ok(size)  => {
                match size {
                    Some(_) => {
                        self.events.remove(EventSet::readable());
                        self.events.insert(EventSet::writable());
                        self.i_buf.extend(buf);
                        return Ok(true);
                    },
                    None    => {
                        return Ok(false);
                    },
                }
            },
            Err(e)  => {
                panic!("failed to read from socket! <token: {:?}> <error: {:?}>", self.token, e);
            },
        }

        Ok(false)
    }

    // write the client's output buffer to the socket.
    //
    // the following return values mean:
    //  - Ok(true):  we can close the connection
    //  - Ok(false): keep listening for writeable event and continue next time
    //  - Err(e):    something dun fucked up
    fn send(&mut self) -> Result<bool> {
        while self.o_buf.len() > 0 {
            match self.sock.write(&self.o_buf.as_slice()) {
                Ok(sz)  => {
                    if sz == self.o_buf.len() {
                        // we did it!
                        self.events.remove(EventSet::writable());
                        break;
                    } else {
                        // keep going
                        self.o_buf = self.o_buf.split_off(sz);
                    }
                },
                Err(e)  => {
                    panic!("failed to write to socket! <token: {:?}> <error: {:?}>", self.token, e);
                }
            }
        }

        Ok(true)
    }

    fn register(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        self.events.insert(EventSet::readable());

        evl.register(&self.sock, self.token, self.events, PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to register client! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }

    fn reregister(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        evl.reregister(&self.sock, self.token, self.events, PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to re-register client! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }
}

/// The primary struct provided by the library. The aim is to have a similar
/// interface to Flask, the Python microframework.
pub struct Canteen {
    routes:  HashMap<route::RouteDef, route::Route>,
    rcache:  HashMap<route::RouteDef, route::RouteDef>,
    server:  TcpListener,
    token:   Token,
    conns:   Slab<Client>,
    default: fn(&Request) -> Response,
}

impl Handler for Canteen {
    type Timeout = ();
    type Message = u32;

    fn ready(&mut self, evl: &mut EventLoop<Canteen>, token: Token, events: EventSet) {
        if events.is_error() || events.is_hup() {
            self.reset_connection(token);
            return;
        }

        if events.is_readable() {
            if self.token == token {
                self.accept(evl);
            } else {
                self.readable(evl, token)
                    .and_then(|_| self.get_client(token)
                                      .reregister(evl))
                    .unwrap_or_else(|e| {
                        panic!("read event failed! <token: {:?}> <error: {:?}>", token, e);
                    });
            }

            return;
        }

        if events.is_writable() {
            match self.get_client(token).send() {
                Ok(true)    => { self.reset_connection(token); },
                Ok(false)   => { let _ = self.get_client(token).reregister(evl); },
                Err(_)      => { panic!("something really bad happened!"); },
            }
        }
    }
}

impl Canteen {
    /// Creates a new Canteen instance.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    ///
    /// let cnt = Canteen::new(("127.0.0.1", 8081));
    /// ```
    pub fn new<A: ToSocketAddrs>(addr: A) -> Canteen {
        Canteen {
            routes:  HashMap::new(),
            rcache:  HashMap::new(),
            server:  TcpListener::bind(&addr.to_socket_addrs().unwrap().next().unwrap()).unwrap(),
            token:   Token(1),
            conns:   Slab::new_starting_at(Token(2), 2048),
            default: utils::err_404,
        }
    }

    /// Adds a new route definition to be handled by Canteen.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::{Canteen, Request, Response, Method};
    /// use canteen::utils;
    ///
    /// fn handler(_: &Request) -> Response {
    ///     utils::make_response("<b>Hello, world!</b>", "text/html", 200)
    /// }
    ///
    /// fn main() {
    ///     let mut cnt = Canteen::new(("127.0.0.1", 8082));
    ///     cnt.add_route("/hello", &[Method::Get], handler);
    /// }
    /// ```
    pub fn add_route(&mut self, path: &str, mlist: &[Method],
                     handler: fn(&Request) -> Response) -> &mut Canteen {
        let mut methods: HashSet<Method> = HashSet::new();

        // make them unique
        for m in mlist {
            methods.insert(*m);
        }

        for m in methods {
            let rd = route::RouteDef {
                pathdef:    String::from(path),
                method:     m,
            };

            if self.routes.contains_key(&rd) {
                panic!("a route handler for {} has already been defined!", path);
            }

            self.routes.insert(rd, route::Route::new(&path, m, handler));
        }

        self
    }

    /// Defines a default route for undefined paths.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    /// use canteen::utils;
    ///
    /// let mut cnt = Canteen::new(("127.0.0.1", 8083));
    /// cnt.set_default(utils::err_404);
    /// ```
    pub fn set_default(&mut self, handler: fn(&Request) -> Response) {
        self.default = handler;
    }

    fn get_client<'a>(&'a mut self, token: Token) -> &'a mut Client {
        &mut self.conns[token]
    }

    fn accept(&mut self, evl: &mut EventLoop<Canteen>) {
        let (sock, _) = match self.server.accept() {
            Ok(s)   => {
                match s {
                    Some(sock)  => sock,
                    None        => {
                        panic!("failed to accept new connection!");
                    }
                }
            },
            Err(e)  => {
                panic!("failed to accept new connection! <error: {:?}>", e);
            },
        };

        match self.conns.insert_with(|token| Client::new(sock, token)) {
            Some(token) => {
                match self.get_client(token).register(evl) {
                    Ok(_)   => {},
                    Err(e)  => {
                        panic!("failed to register client! <token: {:?}> <error: {:?}>", token, e);
                    },
                }
            },
            None        => {
                panic!("failed to add client connection!");
            },
        }

        self.reregister(evl);
    }

    fn handle_request(&mut self, rqstr: &str) -> Vec<u8> {
        let mut req = Request::from_str(&rqstr);
        let resolved = route::RouteDef { pathdef: req.path.clone(), method: req.method };
        let mut handler: fn(&Request) -> Response = self.default;

        if self.rcache.contains_key(&resolved) {
            let ref route = self.routes[&self.rcache[&resolved]];

            handler = route.handler;
            req.params = route.parse(&req.path);
        } else {
            for (path, route) in &self.routes {
                match (route).is_match(&req) {
                    true  => {
                        handler = route.handler;
                        req.params = route.parse(&req.path);
                        self.rcache.insert(resolved, (*path).clone());
                        break;
                    },
                    false => continue,
                }
            }
        }

        handler(&req).gen_output()
    }

    fn readable(&mut self, evl: &mut EventLoop<Canteen>, token: Token) -> Result<bool> {
        match self.get_client(token).receive() {
            Ok(true)    => {
                let buf = self.get_client(token).i_buf.clone();
                let rqstr = String::from_utf8(buf).unwrap();
                let output = self.handle_request(&rqstr);

                self.get_client(token).o_buf.extend(output);
            },
            Ok(false)   => {},
            Err(e)      => {
                panic!("message wasn't actually readable! <error: {:?}>", e);
            },
        };

        let _ = self.get_client(token).reregister(evl);

        Ok(true)
    }

    fn reset_connection(&mut self, token: Token) {
        // kill the connection
        self.conns.remove(token);
    }

    fn register(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        evl.register(&self.server, self.token, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to register server! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }

    fn reregister(&mut self, evl: &mut EventLoop<Canteen>) {
        match evl.reregister(&self.server, self.token,
                             EventSet::readable(),
                             PollOpt::edge() | PollOpt::oneshot()) {
            Ok(_)   => {},
            Err(e)  => {
               panic!("failed to register server! <token: {:?}> <error: {:?}>", self.token, e);
           }
        };
    }

    /// Creates the listener and starts a Canteen server's event loop.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    ///
    /// let cnt = Canteen::new(("127.0.0.1", 8084));
    /// /* cnt.run(); */
    /// ```
    pub fn run(&mut self) {
        let mut evl = EventLoop::new().unwrap();
        self.register(&mut evl).ok();
        evl.run(self).unwrap();
    }
}
<commit_msg>don't copy unnecessarily<commit_after>// Copyright (c) 2016
// Jeff Nettleton
//
// Licensed under the MIT license (http://opensource.org/licenses/MIT). This
// file may not be copied, modified, or distributed except according to those
// terms

//! # Canteen
//!
//! ## Description
//!
//! A pure Rust clone of [Flask](http://flask.pocoo.org), a simple but powerful Python
//! web framework.
//!
//! ## Example
//!
//! The principle behind Canteen is simple -- handler functions are defined as simple
//! Rust functions that take a `Request` and return a `Response`. Handlers are then attached
//! to one or more routes and HTTP methods/verbs. Routes are specified using a simple
//! syntax that lets you define variables within them; variables that can then be
//! extracted to perform various operations. Currently, the following variable types can
//! be used:
//!
//! - `<str:name>` will match anything inside a path segment, returns a `String`
//! - `<int:name>` will return a signed integer (`i32`) from a path segment
//!   - ex: `cnt.add_route("/api/foo/<int:foo_id>", &[Method::Get], my_handler)` will match
//!   `"/api/foo/123"` but not `"/api/foo/123.34"` or `"/api/foo/bar"`
//! - `<uint:name>` will return an unsigned integer (`u32`)
//! - `<float:name>` does the same thing as the `int` parameter definition, but matches numbers
//! with decimal points and returns an `f32`
//! - `<path:name>` will greedily take all path data contained, returns a `String`
//!   - ex: `cnt.add_route("/static/<path:name>", &[Method::Get], utils::static_file)` will
//!   serve anything in the `/static/` directory as a file
//!
//! ```rust
//! extern crate canteen;
//!
//! use canteen::{Canteen, Request, Response, Method};
//! use canteen::utils;
//!
//! fn hello_handler(req: &Request) -> Response {
//!     let mut res = Response::new();
//!
//!     res.set_status(200);
//!     res.set_content_type("text/plain");
//!     res.append("Hello, world!");
//!
//!     res
//! }
//!
//! fn double_handler(req: &Request) -> Response {
//!     let to_dbl: i32 = req.get("to_dbl");
//!
//!     /* simpler response generation syntax */
//!     utils::make_response(format!("{}", to_dbl * 2), "text/plain", 200)
//! }
//!
//! fn main() {
//!     let mut cnt = Canteen::new(("127.0.0.1", 8080));
//!
//!     // set the default route handler to show a 404 message
//!     cnt.set_default(utils::err_404);
//!
//!     // respond to requests to / with "Hello, world!"
//!     cnt.add_route("/", &[Method::Get], hello_handler);
//!
//!     // pull a variable from the path and do something with it
//!     cnt.add_route("/double/<int:to_dbl>", &[Method::Get], double_handler);
//!
//!     // serve raw files from the /static/ directory
//!     cnt.add_route("/static/<path:path>", &[Method::Get], utils::static_file);
//!
//!     /* cnt.run() */;
//! }
//! ```

extern crate mio;
extern crate regex;
extern crate chrono;
extern crate rustc_serialize;

pub mod utils;
pub mod route;
pub mod request;
pub mod response;

use std::io::Result;
use std::io::prelude::*;
use std::net::ToSocketAddrs;
use std::collections::HashMap;
use std::collections::HashSet;
use mio::tcp::{TcpListener, TcpStream};
use mio::util::Slab;
use mio::*;

pub use request::*;
pub use response::*;

struct Client {
    sock:   TcpStream,
    token:  Token,
    events: EventSet,
    i_buf:  Vec<u8>,
    o_buf:  Vec<u8>,
}

impl Client {
    fn new(sock: TcpStream, token: Token) -> Client {
        Client {
            sock:   sock,
            token:  token,
            events: EventSet::hup(),
            i_buf:  Vec::with_capacity(2048),
            o_buf:  Vec::new(),
        }
    }

    fn receive(&mut self) -> Result<bool> {
        let mut buf: Vec<u8> = Vec::with_capacity(2048);

        match self.sock.try_read_buf(&mut buf) {
            Ok(size)  => {
                match size {
                    Some(_) => {
                        self.events.remove(EventSet::readable());
                        self.events.insert(EventSet::writable());
                        self.i_buf.extend(buf);
                        return Ok(true);
                    },
                    None    => {
                        return Ok(false);
                    },
                }
            },
            Err(e)  => {
                panic!("failed to read from socket! <token: {:?}> <error: {:?}>", self.token, e);
            },
        }

        Ok(false)
    }

    // write the client's output buffer to the socket.
    //
    // the following return values mean:
    //  - Ok(true):  we can close the connection
    //  - Ok(false): keep listening for writeable event and continue next time
    //  - Err(e):    something dun fucked up
    fn send(&mut self) -> Result<bool> {
        while self.o_buf.len() > 0 {
            match self.sock.write(&self.o_buf.as_slice()) {
                Ok(sz)  => {
                    if sz == self.o_buf.len() {
                        // we did it!
                        self.events.remove(EventSet::writable());
                        break;
                    } else {
                        // keep going
                        self.o_buf = self.o_buf.split_off(sz);
                    }
                },
                Err(e)  => {
                    panic!("failed to write to socket! <token: {:?}> <error: {:?}>", self.token, e);
                }
            }
        }

        Ok(true)
    }

    fn register(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        self.events.insert(EventSet::readable());

        evl.register(&self.sock, self.token, self.events, PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to register client! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }

    fn reregister(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        evl.reregister(&self.sock, self.token, self.events, PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to re-register client! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }
}

/// The primary struct provided by the library. The aim is to have a similar
/// interface to Flask, the Python microframework.
pub struct Canteen {
    routes:  HashMap<route::RouteDef, route::Route>,
    rcache:  HashMap<route::RouteDef, route::RouteDef>,
    server:  TcpListener,
    token:   Token,
    conns:   Slab<Client>,
    default: fn(&Request) -> Response,
}

impl Handler for Canteen {
    type Timeout = ();
    type Message = u32;

    fn ready(&mut self, evl: &mut EventLoop<Canteen>, token: Token, events: EventSet) {
        if events.is_error() || events.is_hup() {
            self.reset_connection(token);
            return;
        }

        if events.is_readable() {
            if self.token == token {
                self.accept(evl);
            } else {
                self.readable(evl, token)
                    .and_then(|_| self.get_client(token)
                                      .reregister(evl))
                    .unwrap_or_else(|e| {
                        panic!("read event failed! <token: {:?}> <error: {:?}>", token, e);
                    });
            }

            return;
        }

        if events.is_writable() {
            match self.get_client(token).send() {
                Ok(true)    => { self.reset_connection(token); },
                Ok(false)   => { let _ = self.get_client(token).reregister(evl); },
                Err(_)      => { panic!("something really bad happened!"); },
            }
        }
    }
}

impl Canteen {
    /// Creates a new Canteen instance.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    ///
    /// let cnt = Canteen::new(("127.0.0.1", 8081));
    /// ```
    pub fn new<A: ToSocketAddrs>(addr: A) -> Canteen {
        Canteen {
            routes:  HashMap::new(),
            rcache:  HashMap::new(),
            server:  TcpListener::bind(&addr.to_socket_addrs().unwrap().next().unwrap()).unwrap(),
            token:   Token(1),
            conns:   Slab::new_starting_at(Token(2), 2048),
            default: utils::err_404,
        }
    }

    /// Adds a new route definition to be handled by Canteen.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::{Canteen, Request, Response, Method};
    /// use canteen::utils;
    ///
    /// fn handler(_: &Request) -> Response {
    ///     utils::make_response("<b>Hello, world!</b>", "text/html", 200)
    /// }
    ///
    /// fn main() {
    ///     let mut cnt = Canteen::new(("127.0.0.1", 8082));
    ///     cnt.add_route("/hello", &[Method::Get], handler);
    /// }
    /// ```
    pub fn add_route(&mut self, path: &str, mlist: &[Method],
                     handler: fn(&Request) -> Response) -> &mut Canteen {
        let mut methods: HashSet<Method> = HashSet::new();

        // make them unique
        for m in mlist {
            methods.insert(*m);
        }

        for m in methods {
            let rd = route::RouteDef {
                pathdef:    String::from(path),
                method:     m,
            };

            if self.routes.contains_key(&rd) {
                panic!("a route handler for {} has already been defined!", path);
            }

            self.routes.insert(rd, route::Route::new(&path, m, handler));
        }

        self
    }

    /// Defines a default route for undefined paths.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    /// use canteen::utils;
    ///
    /// let mut cnt = Canteen::new(("127.0.0.1", 8083));
    /// cnt.set_default(utils::err_404);
    /// ```
    pub fn set_default(&mut self, handler: fn(&Request) -> Response) {
        self.default = handler;
    }

    fn get_client<'a>(&'a mut self, token: Token) -> &'a mut Client {
        &mut self.conns[token]
    }

    fn accept(&mut self, evl: &mut EventLoop<Canteen>) {
        let (sock, _) = match self.server.accept() {
            Ok(s)   => {
                match s {
                    Some(sock)  => sock,
                    None        => {
                        panic!("failed to accept new connection!");
                    }
                }
            },
            Err(e)  => {
                panic!("failed to accept new connection! <error: {:?}>", e);
            },
        };

        match self.conns.insert_with(|token| Client::new(sock, token)) {
            Some(token) => {
                match self.get_client(token).register(evl) {
                    Ok(_)   => {},
                    Err(e)  => {
                        panic!("failed to register client! <token: {:?}> <error: {:?}>", token, e);
                    },
                }
            },
            None        => {
                panic!("failed to add client connection!");
            },
        }

        self.reregister(evl);
    }

    fn handle_request(&mut self, rqstr: &str) -> Vec<u8> {
        let mut req = Request::from_str(&rqstr);
        let resolved = route::RouteDef { pathdef: req.path.clone(), method: req.method };
        let mut handler: fn(&Request) -> Response = self.default;

        if self.rcache.contains_key(&resolved) {
            let ref route = self.routes[&self.rcache[&resolved]];

            handler = route.handler;
            req.params = route.parse(&req.path);
        } else {
            for (path, route) in &self.routes {
                match (route).is_match(&req) {
                    true  => {
                        handler = route.handler;
                        req.params = route.parse(&req.path);
                        self.rcache.insert(resolved, (*path).clone());
                        break;
                    },
                    false => continue,
                }
            }
        }

        handler(&req).gen_output()
    }

    fn readable(&mut self, evl: &mut EventLoop<Canteen>, token: Token) -> Result<bool> {
        match self.get_client(token).receive() {
            Ok(true)    => {
                let buf = self.get_client(token).i_buf.clone();
                let rqstr = String::from_utf8(buf).unwrap();
                self.get_client(token).o_buf = self.handle_request(&rqstr);
            },
            Ok(false)   => {},
            Err(e)      => {
                panic!("message wasn't actually readable! <error: {:?}>", e);
            },
        };

        let _ = self.get_client(token).reregister(evl);

        Ok(true)
    }

    fn reset_connection(&mut self, token: Token) {
        // kill the connection
        self.conns.remove(token);
    }

    fn register(&mut self, evl: &mut EventLoop<Canteen>) -> Result<()> {
        evl.register(&self.server, self.token, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot())
           .or_else(|e| {
               panic!("failed to register server! <token: {:?}> <error: {:?}>", self.token, e);
           })
    }

    fn reregister(&mut self, evl: &mut EventLoop<Canteen>) {
        match evl.reregister(&self.server, self.token,
                             EventSet::readable(),
                             PollOpt::edge() | PollOpt::oneshot()) {
            Ok(_)   => {},
            Err(e)  => {
               panic!("failed to register server! <token: {:?}> <error: {:?}>", self.token, e);
           }
        };
    }

    /// Creates the listener and starts a Canteen server's event loop.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use canteen::Canteen;
    ///
    /// let cnt = Canteen::new(("127.0.0.1", 8084));
    /// /* cnt.run(); */
    /// ```
    pub fn run(&mut self) {
        let mut evl = EventLoop::new().unwrap();
        self.register(&mut evl).ok();
        evl.run(self).unwrap();
    }
}
<|endoftext|>


<commit_before>
extern crate core;

use std::iter::FromIterator;
use core::slice::Items;
use std::collections::RingBuf;
use std::collections::Deque;

mod cube;

pub mod generators {
    pub use cube::Cube;
}

pub struct Vector1<T>(pub [T, ..1]);
pub struct Vector2<T>(pub [T, ..2]);
pub struct Vector3<T>(pub [T, ..3]);
pub struct Vector4<T>(pub [T, ..4]);

impl<T> FromIterator<T> for Vector1<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector1<T> {
        let mut iter = iter;
        match iter.next() {
            Some(a) => Vector1([a]),
            _ => fail!("should have found 2 vertices to buld a Vector1")
        }
    }
}

impl<T: Clone> Clone for Vector1<T> {
    fn clone(&self) -> Vector1<T> {
        let &Vector1(ref v) = self;
        Vector1([v[0].clone()])
    }
}

impl<T> Poly<T> for Vector1<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector1(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector2<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector2<T> {
        let mut iter = iter;
        match (iter.next(), iter.next()) {
            (Some(a), Some(b)) => Vector2([a, b]),
            _ => fail!("should have found 2 vertices to buld a Vector2")
        }
    }
}

impl<T: Clone> Clone for Vector2<T> {
    fn clone(&self) -> Vector2<T> {
        let &Vector2(ref v) = self;
        Vector2([v[0].clone(),
                 v[1].clone()])
    }
}

impl<T> Poly<T> for Vector2<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector2(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector3<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector3<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c)) => Vector3([a, b, c]),
            _ => fail!("should have found 3 vertices to buld a Vector3")
        }
    }
}

impl<T: Clone> Clone for Vector3<T> {
    fn clone(&self) -> Vector3<T> {
        let &Vector3(ref v) = self;
        Vector3([v[0].clone(),
                 v[1].clone(),
                 v[2].clone()])
    }
}

impl<T> Poly<T> for Vector3<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector3(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector4<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector4<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c), Some(d)) => Vector4([a, b, c, d]),
            _ => fail!("should have found 4 vertices to buld a quad")
        }
    }
}

impl<T: Clone> Clone for Vector4<T> {
    fn clone(&self) -> Vector4<T> {
        let &Vector4(ref v) = self;
        Vector4([v[0].clone(),
                 v[1].clone(),
                 v[2].clone(),
                 v[3].clone()])
    }
}

impl<T> Poly<T> for Vector4<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector4(ref s) = self;
        s.as_slice()
    }
}

trait Poly<T> : FromIterator<T> {
    fn as_slice<'a>(&'a self) -> &'a [T];

    fn iter<'a>(&'a self) -> Items<T> {
        self.as_slice().iter()
    }
}

pub struct Triangle<T>(Vector3<T>);

impl<T> Triangle<T> {
    pub fn new(v0: T, v1: T, v2: T) -> Triangle<T> {
        Triangle(Vector3([v0, v1, v2]))
    }
}

impl<T: Clone> Clone for Triangle<T> {
    fn clone(&self) -> Triangle<T> {
        let &Triangle(ref v) = self;
        Triangle(v.clone())
    }
}

impl<T> FromIterator<T> for Triangle<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Triangle<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c)) => Triangle(Vector3([a, b, c])),
            _ => fail!("should have found 3 vertices to buld a triangle")
        }
    }
}

impl<T> Poly<T> for Triangle<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Triangle(Vector3(ref s)) = self;
        s.as_slice()
    }
}

pub struct Quad<T>(pub Vector4<T>);

impl<T> Quad<T> {
    pub fn new(v0: T, v1: T, v2: T, v3: T) -> Quad<T> {
        Quad(Vector4([v0, v1, v2, v3]))
    }
}

pub trait ToTriangle<T> {
    fn to_triangles(&self, |T|);
}

impl<T: Clone> ToTriangle<Triangle<T>> for Quad<T> {
    fn to_triangles(&self, emit: |Triangle<T>|) {
        let &Quad(Vector4([ref v0, ref v1, ref v2, ref v3])) = self;
        emit(Triangle::new(v0.clone(), v1.clone(), v2.clone()));
        emit(Triangle::new(v2.clone(), v3.clone(), v0.clone()));
    }
}

impl<T> FromIterator<T> for Quad<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Quad<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c), Some(d)) => Quad(Vector4([a, b, c, d])),
            _ => fail!("should have found 4 vertices to buld a quad")
        }
    }
}

impl<T> Poly<T> for Quad<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Quad(Vector4(ref s)) = self;
        s.as_slice()
    }
}

trait VertexPass<IN, OUT> {
    fn vertex_pass(&self, &IN) -> OUT;

    fn transform_primative<A: Poly<IN>, B: Poly<OUT>>(&self, a: &A) -> B {
        a.iter().map(|v| self.vertex_pass(v)).collect()
    }
}

pub struct IndexDeref<'a, T> {
    vertices: &'a [T]
}

impl<'a, T> IndexDeref<'a, T> {
    pub fn new(vertices: &'a [T]) -> IndexDeref<'a, T> {
        IndexDeref {
            vertices: vertices
        }
    }
}

impl<'a, T: Clone> VertexPass<uint, T> for IndexDeref<'a, T> {
    fn vertex_pass(&self, index: &uint) -> T {
        self.vertices[*index].clone()
    }
}

pub trait Generator<T, P: Poly<T>> : Iterator<P> {
    fn vertices(self) -> VertexGenerator<Self, T> {
        VertexGenerator {
            source: self,
            spare: Vec::new()
        }
    }

    fn geometry<'a, OUT_P>(self, max: uint, f: |P, emit: |OUT_P||:'a) -> GeometryMap<'a, Self, P, OUT_P> {
        GeometryMap {
            source: self,
            max: max,
            buffer: Some(RingBuf::with_capacity(max)),
            f: f
        }
    }

    fn to_triangles<OUT_P>(self) -> ConvertTriangles<Self, OUT_P> {
        ConvertTriangles {
            source: self,
            buffer: Some(RingBuf::with_capacity(2)),
        }
    }
}

pub struct GeometryMap<'a, SRC, IN_P, OUT_P> {
    source: SRC,
    max: uint,
    buffer: Option<RingBuf<OUT_P>>,
    f: |IN_P, |OUT_P||:'a
}

impl<'a, IN_P, OUT_P, SRC: Iterator<IN_P>> Iterator<OUT_P> for GeometryMap<'a, SRC, IN_P, OUT_P> {
    fn next(&mut self) -> Option<OUT_P> {
        loop {
            match self.buffer.get_mut_ref().pop_front() {
                p @ Some(_) => return p,
                None => ()
            }

            match self.source.next() {
                Some(p) => {
                    let mut buf = self.buffer.take().unwrap();
                    (self.f)(p, |emited| buf.push(emited));
                    self.buffer = Some(buf);
                }
                None => return None
            }

        }
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        match self.source.size_hint() {
            (base, Some(s)) => {
                (base, Some(s*self.max))
            },
            (base, None) => {
                (base, Some(base*self.max))
            }
        }
    }
}

pub struct ConvertTriangles<SRC, OUT_P> {
    source: SRC,
    buffer: Option<RingBuf<OUT_P>>,
}

impl<IN_V, IN_P: ToTriangle<OUT_P>, OUT_P: Poly<IN_V>, SRC: Iterator<IN_P>> Iterator<OUT_P> for ConvertTriangles<SRC, OUT_P> {
    fn next(&mut self) -> Option<OUT_P> {
        loop {
            match self.buffer.get_mut_ref().pop_front() {
                p @ Some(_) => return p,
                None => ()
            }

            match self.source.next() {
                Some(p) => {
                    let mut buf = self.buffer.take().unwrap();
                    p.to_triangles(|emited| buf.push(emited));
                    self.buffer = Some(buf);
                }
                None => return None
            }

        }
    }
}

impl<OUT_V, IN_P: ToTriangle<OUT_P>, OUT_P: Poly<OUT_V>, SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for ConvertTriangles<SRC, OUT_P> {}

impl<'a, IN_P, OUT_V, OUT_P: Poly<OUT_V>, SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for GeometryMap<'a, SRC, IN_P, OUT_P> {}

impl<'a, IN_V, IN_P: Poly<IN_V>,
         OUT_V, OUT_P: Poly<OUT_V>,
         SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for core::iter::Map<'a, IN_P, OUT_P, SRC> {}

pub struct VertexGenerator<SRC, T> {
    source: SRC,
    spare: Vec<T>
}

impl<T: Clone, P: Poly<T>, SRC: Iterator<P>> Iterator<T> for VertexGenerator<SRC, T> {
    fn next(&mut self) -> Option<T> {
        loop {
            match self.spare.remove(0) {
                out @ Some(_) => return out,
                None => ()
            }

            match self.source.next() {
                Some(s) => {
                    self.spare.push_all(s.as_slice());
                }
                None => return None
            }
        }
    }
}

#[cfg(test)]
mod test {
    use IndexDeref;
    use VertexPass;
    use Triangle;
    use Poly;

    #[test]
    fn index_deref() {
        let index = &[0, 1, 2, 3];
        let index = IndexDeref::new(index);

        assert_eq!(index.vertex_pass(&0), 0u);
        assert_eq!(index.vertex_pass(&1), 1u);
        assert_eq!(index.vertex_pass(&2), 2u);
        assert_eq!(index.vertex_pass(&3), 3u);
    }

    #[test]
    fn index_geo_deref() {
        let a = &[7u, 8, 9, 10];
        let index = IndexDeref::new(a);

        let out: Triangle<uint> = index.transform_primative(&Triangle::new(0u, 1, 2));
        assert_eq!(out.as_slice(), Triangle::new(7u, 8, 9).as_slice())
    }
}<commit_msg>made Poly public<commit_after>
extern crate core;

use std::iter::FromIterator;
use core::slice::Items;
use std::collections::RingBuf;
use std::collections::Deque;

mod cube;

pub mod generators {
    pub use cube::Cube;
}

pub struct Vector1<T>(pub [T, ..1]);
pub struct Vector2<T>(pub [T, ..2]);
pub struct Vector3<T>(pub [T, ..3]);
pub struct Vector4<T>(pub [T, ..4]);

impl<T> FromIterator<T> for Vector1<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector1<T> {
        let mut iter = iter;
        match iter.next() {
            Some(a) => Vector1([a]),
            _ => fail!("should have found 2 vertices to buld a Vector1")
        }
    }
}

impl<T: Clone> Clone for Vector1<T> {
    fn clone(&self) -> Vector1<T> {
        let &Vector1(ref v) = self;
        Vector1([v[0].clone()])
    }
}

impl<T> Poly<T> for Vector1<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector1(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector2<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector2<T> {
        let mut iter = iter;
        match (iter.next(), iter.next()) {
            (Some(a), Some(b)) => Vector2([a, b]),
            _ => fail!("should have found 2 vertices to buld a Vector2")
        }
    }
}

impl<T: Clone> Clone for Vector2<T> {
    fn clone(&self) -> Vector2<T> {
        let &Vector2(ref v) = self;
        Vector2([v[0].clone(),
                 v[1].clone()])
    }
}

impl<T> Poly<T> for Vector2<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector2(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector3<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector3<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c)) => Vector3([a, b, c]),
            _ => fail!("should have found 3 vertices to buld a Vector3")
        }
    }
}

impl<T: Clone> Clone for Vector3<T> {
    fn clone(&self) -> Vector3<T> {
        let &Vector3(ref v) = self;
        Vector3([v[0].clone(),
                 v[1].clone(),
                 v[2].clone()])
    }
}

impl<T> Poly<T> for Vector3<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector3(ref s) = self;
        s.as_slice()
    }
}

impl<T> FromIterator<T> for Vector4<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Vector4<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c), Some(d)) => Vector4([a, b, c, d]),
            _ => fail!("should have found 4 vertices to buld a quad")
        }
    }
}

impl<T: Clone> Clone for Vector4<T> {
    fn clone(&self) -> Vector4<T> {
        let &Vector4(ref v) = self;
        Vector4([v[0].clone(),
                 v[1].clone(),
                 v[2].clone(),
                 v[3].clone()])
    }
}

impl<T> Poly<T> for Vector4<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Vector4(ref s) = self;
        s.as_slice()
    }
}

pub trait Poly<T> : FromIterator<T> {
    fn as_slice<'a>(&'a self) -> &'a [T];

    fn iter<'a>(&'a self) -> Items<T> {
        self.as_slice().iter()
    }
}

pub struct Triangle<T>(Vector3<T>);

impl<T> Triangle<T> {
    pub fn new(v0: T, v1: T, v2: T) -> Triangle<T> {
        Triangle(Vector3([v0, v1, v2]))
    }
}

impl<T: Clone> Clone for Triangle<T> {
    fn clone(&self) -> Triangle<T> {
        let &Triangle(ref v) = self;
        Triangle(v.clone())
    }
}

impl<T> FromIterator<T> for Triangle<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Triangle<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c)) => Triangle(Vector3([a, b, c])),
            _ => fail!("should have found 3 vertices to buld a triangle")
        }
    }
}

impl<T> Poly<T> for Triangle<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Triangle(Vector3(ref s)) = self;
        s.as_slice()
    }
}

pub struct Quad<T>(pub Vector4<T>);

impl<T> Quad<T> {
    pub fn new(v0: T, v1: T, v2: T, v3: T) -> Quad<T> {
        Quad(Vector4([v0, v1, v2, v3]))
    }
}

pub trait ToTriangle<T> {
    fn to_triangles(&self, |T|);
}

impl<T: Clone> ToTriangle<Triangle<T>> for Quad<T> {
    fn to_triangles(&self, emit: |Triangle<T>|) {
        let &Quad(Vector4([ref v0, ref v1, ref v2, ref v3])) = self;
        emit(Triangle::new(v0.clone(), v1.clone(), v2.clone()));
        emit(Triangle::new(v2.clone(), v3.clone(), v0.clone()));
    }
}

impl<T> FromIterator<T> for Quad<T> {
    fn from_iter<I: Iterator<T>>(iter: I) -> Quad<T> {
        let mut iter = iter;
        match (iter.next(), iter.next(), iter.next(), iter.next()) {
            (Some(a), Some(b), Some(c), Some(d)) => Quad(Vector4([a, b, c, d])),
            _ => fail!("should have found 4 vertices to buld a quad")
        }
    }
}

impl<T> Poly<T> for Quad<T> {
    fn as_slice<'a>(&'a self) -> &'a [T] {
        let &Quad(Vector4(ref s)) = self;
        s.as_slice()
    }
}

trait VertexPass<IN, OUT> {
    fn vertex_pass(&self, &IN) -> OUT;

    fn transform_primative<A: Poly<IN>, B: Poly<OUT>>(&self, a: &A) -> B {
        a.iter().map(|v| self.vertex_pass(v)).collect()
    }
}

pub struct IndexDeref<'a, T> {
    vertices: &'a [T]
}

impl<'a, T> IndexDeref<'a, T> {
    pub fn new(vertices: &'a [T]) -> IndexDeref<'a, T> {
        IndexDeref {
            vertices: vertices
        }
    }
}

impl<'a, T: Clone> VertexPass<uint, T> for IndexDeref<'a, T> {
    fn vertex_pass(&self, index: &uint) -> T {
        self.vertices[*index].clone()
    }
}

pub trait Generator<T, P: Poly<T>> : Iterator<P> {
    fn vertices(self) -> VertexGenerator<Self, T> {
        VertexGenerator {
            source: self,
            spare: Vec::new()
        }
    }

    fn geometry<'a, OUT_P>(self, max: uint, f: |P, emit: |OUT_P||:'a) -> GeometryMap<'a, Self, P, OUT_P> {
        GeometryMap {
            source: self,
            max: max,
            buffer: Some(RingBuf::with_capacity(max)),
            f: f
        }
    }

    fn to_triangles<OUT_P>(self) -> ConvertTriangles<Self, OUT_P> {
        ConvertTriangles {
            source: self,
            buffer: Some(RingBuf::with_capacity(2)),
        }
    }
}

pub struct GeometryMap<'a, SRC, IN_P, OUT_P> {
    source: SRC,
    max: uint,
    buffer: Option<RingBuf<OUT_P>>,
    f: |IN_P, |OUT_P||:'a
}

impl<'a, IN_P, OUT_P, SRC: Iterator<IN_P>> Iterator<OUT_P> for GeometryMap<'a, SRC, IN_P, OUT_P> {
    fn next(&mut self) -> Option<OUT_P> {
        loop {
            match self.buffer.get_mut_ref().pop_front() {
                p @ Some(_) => return p,
                None => ()
            }

            match self.source.next() {
                Some(p) => {
                    let mut buf = self.buffer.take().unwrap();
                    (self.f)(p, |emited| buf.push(emited));
                    self.buffer = Some(buf);
                }
                None => return None
            }

        }
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        match self.source.size_hint() {
            (base, Some(s)) => {
                (base, Some(s*self.max))
            },
            (base, None) => {
                (base, Some(base*self.max))
            }
        }
    }
}

pub struct ConvertTriangles<SRC, OUT_P> {
    source: SRC,
    buffer: Option<RingBuf<OUT_P>>,
}

impl<IN_V, IN_P: ToTriangle<OUT_P>, OUT_P: Poly<IN_V>, SRC: Iterator<IN_P>> Iterator<OUT_P> for ConvertTriangles<SRC, OUT_P> {
    fn next(&mut self) -> Option<OUT_P> {
        loop {
            match self.buffer.get_mut_ref().pop_front() {
                p @ Some(_) => return p,
                None => ()
            }

            match self.source.next() {
                Some(p) => {
                    let mut buf = self.buffer.take().unwrap();
                    p.to_triangles(|emited| buf.push(emited));
                    self.buffer = Some(buf);
                }
                None => return None
            }

        }
    }
}

impl<OUT_V, IN_P: ToTriangle<OUT_P>, OUT_P: Poly<OUT_V>, SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for ConvertTriangles<SRC, OUT_P> {}

impl<'a, IN_P, OUT_V, OUT_P: Poly<OUT_V>, SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for GeometryMap<'a, SRC, IN_P, OUT_P> {}

impl<'a, IN_V, IN_P: Poly<IN_V>,
         OUT_V, OUT_P: Poly<OUT_V>,
         SRC: Iterator<IN_P>> Generator<OUT_V, OUT_P> for core::iter::Map<'a, IN_P, OUT_P, SRC> {}

pub struct VertexGenerator<SRC, T> {
    source: SRC,
    spare: Vec<T>
}

impl<T: Clone, P: Poly<T>, SRC: Iterator<P>> Iterator<T> for VertexGenerator<SRC, T> {
    fn next(&mut self) -> Option<T> {
        loop {
            match self.spare.remove(0) {
                out @ Some(_) => return out,
                None => ()
            }

            match self.source.next() {
                Some(s) => {
                    self.spare.push_all(s.as_slice());
                }
                None => return None
            }
        }
    }
}

#[cfg(test)]
mod test {
    use IndexDeref;
    use VertexPass;
    use Triangle;
    use Poly;

    #[test]
    fn index_deref() {
        let index = &[0, 1, 2, 3];
        let index = IndexDeref::new(index);

        assert_eq!(index.vertex_pass(&0), 0u);
        assert_eq!(index.vertex_pass(&1), 1u);
        assert_eq!(index.vertex_pass(&2), 2u);
        assert_eq!(index.vertex_pass(&3), 3u);
    }

    #[test]
    fn index_geo_deref() {
        let a = &[7u, 8, 9, 10];
        let index = IndexDeref::new(a);

        let out: Triangle<uint> = index.transform_primative(&Triangle::new(0u, 1, 2));
        assert_eq!(out.as_slice(), Triangle::new(7u, 8, 9).as_slice())
    }
}<|endoftext|>


<commit_before>/*!

*/

//! TypeDef is used to identify and compare types, as well as print their names.
//!
//! If you do not need readable type name, you should use `TypeId`. This
//! wrapper re-implements `TypeId`.
//!
//! To get a name of a type:
//!
//! ```
//! use typedef::{ TypeDef };
//!
//! assert_eq!(TypeDef::name_of::<int>(), "int");
//! ```
//!
//! Type can also serve as type identifier and name container:
//!
//! ```
//! use typedef::{ TypeDef };
//!
//! let typedef = TypeDef::of::<int>();
//!
//! assert!(typedef.is::<int>());
//! assert_eq!(typedef.get_str(), "int");
//! ```
//!
//! More common usage would be in a generic method:
//!
//! ```
//! use std::fmt::{ Show };
//! use typedef::{ TypeDef };
//!
//! fn foo<T: 'static + Show>(value: T) -> String {
//!     format!(
//!         "the value of {} type is {}",
//!         TypeDef::of::<T>(),
//!         value
//!     )
//! }
//!
//! fn main() {
//!     assert_eq!(foo(15i), "the value of int type is 15");
//! }
//! ```

use std::intrinsics::TypeId;
use std::intrinsics::get_tydesc;
use std::fmt;

/// Create a TypeDef structure to identify a type and to print its name.
///
/// ```
/// use typedef::{ TypeDef };
///
/// let typedef = TypeDef::of::<int>();
///
/// assert!(typedef.is::<int>());
/// assert!(typedef.get_str() == "int");
/// ```
#[stable]
#[derive(Clone, Copy)]
pub struct TypeDef {
    type_id: TypeId,
    type_name: &'static str,
}

#[stable]
impl TypeDef {
    /// Create a TypeDef structure from a type parameter.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<int>();
    /// ```
    #[stable]
    pub fn of<T: 'static>() -> TypeDef {
        TypeDef {
            type_id: TypeId::of::<T>(),
            type_name: unsafe { (*get_tydesc::<T>()).name },
        }
    }

    /// Get `TypeId` for specified type directly.
    ///
    /// ```
    /// use std::intrinsics::{ TypeId };
    /// use typedef::{ TypeDef };
    ///
    /// assert!(TypeDef::id_of::<int>() == TypeId::of::<int>());
    /// ```
    #[stable]
    pub fn id_of<T: 'static>() -> TypeId {
        TypeId::of::<T>()
    }

    /// Get type name for specified type directly.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// assert_eq!(TypeDef::name_of::<int>(), "int");
    /// ```
    #[stable]
    pub fn name_of<T: 'static>() -> &'static str {
        unsafe { (*get_tydesc::<T>()).name }
    }

    /// Check if typedef instance matches type.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<int>();
    ///
    /// assert!(typedef.is::<int>());
    /// ```
    #[stable]
    pub fn is<T: 'static>(&self) -> bool {
        self.type_id == TypeId::of::<T>()
    }

    /// Get the static `&str` for typedef instance.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<int>();
    ///
    /// assert!(typedef.get_str() == "int");
    /// ```
    #[stable]
    pub fn get_str(&self) -> &'static str {
        self.type_name
    }
}

#[stable]
impl PartialEq for TypeDef {
    #[stable]
    fn eq(&self, other: &TypeDef) -> bool {
        self.type_id == other.type_id
    }
}

#[stable]
impl fmt::Show for TypeDef {
    #[stable]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.type_name)
    }
}

#[cfg(test)]
mod test {
    use super::{ TypeDef };

    #[test]
    fn should_match_type() {
        assert!(TypeDef::of::<i16>().is::<i16>());
    }

    #[test]
    #[should_fail]
    fn should_not_match_incorrect_type() {
        assert!(TypeDef::of::<i16>().is::<i32>());
    }

    #[test]
    fn should_return_type_name() {
        assert_eq!(TypeDef::of::<i16>().get_str(), "i16");
        assert_eq!(TypeDef::of::<int>().get_str(), "int");
    }

    #[test]
    fn should_be_equal_to_another_typedef_of_the_same_type() {
        assert_eq!(TypeDef::of::<i16>(), TypeDef::of::<i16>());
    }

    #[test]
    fn should_not_be_equal_to_another_typedef_of_different_type() {
        assert!(TypeDef::of::<i16>() != TypeDef::of::<i32>());
    }
}
<commit_msg>Fix type fallout.<commit_after>/*!

*/

//! TypeDef is used to identify and compare types, as well as print their names.
//!
//! If you do not need readable type name, you should use `TypeId`. This
//! wrapper re-implements `TypeId`.
//!
//! To get a name of a type:
//!
//! ```
//! use typedef::{ TypeDef };
//!
//! assert_eq!(TypeDef::name_of::<i64>(), "i64");
//! ```
//!
//! Type can also serve as type identifier and name container:
//!
//! ```
//! use typedef::{ TypeDef };
//!
//! let typedef = TypeDef::of::<i64>();
//!
//! assert!(typedef.is::<i64>());
//! assert_eq!(typedef.get_str(), "i64");
//! ```
//!
//! More common usage would be in a generic method:
//!
//! ```
//! use std::fmt::{ Show };
//! use typedef::{ TypeDef };
//!
//! fn foo<T: 'static + Show>(value: T) -> String {
//!     format!(
//!         "the value of {:?} type is {:?}",
//!         TypeDef::of::<T>(),
//!         value
//!     )
//! }
//!
//! fn main() {
//!     assert_eq!(foo(15), "the value of i32 type is 15i32");
//! }
//! ```

use std::any::TypeId;
use std::intrinsics::get_tydesc;
use std::fmt;

/// Create a TypeDef structure to identify a type and to print its name.
///
/// ```
/// use typedef::{ TypeDef };
///
/// let typedef = TypeDef::of::<i64>();
///
/// assert!(typedef.is::<i64>());
/// assert!(typedef.get_str() == "i64");
/// ```
#[stable]
#[derive(Clone, Copy)]
pub struct TypeDef {
    type_id: TypeId,
    type_name: &'static str,
}

#[stable]
impl TypeDef {
    /// Create a TypeDef structure from a type parameter.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<i64>();
    /// ```
    #[stable]
    pub fn of<T: 'static>() -> TypeDef {
        TypeDef {
            type_id: TypeId::of::<T>(),
            type_name: unsafe { (*get_tydesc::<T>()).name },
        }
    }

    /// Get `TypeId` for specified type directly.
    ///
    /// ```
    /// use std::any::{ TypeId };
    /// use typedef::{ TypeDef };
    ///
    /// assert!(TypeDef::id_of::<i64>() == TypeId::of::<i64>());
    /// ```
    #[stable]
    pub fn id_of<T: 'static>() -> TypeId {
        TypeId::of::<T>()
    }

    /// Get type name for specified type directly.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// assert_eq!(TypeDef::name_of::<i64>(), "i64");
    /// ```
    #[stable]
    pub fn name_of<T: 'static>() -> &'static str {
        unsafe { (*get_tydesc::<T>()).name }
    }

    /// Check if typedef instance matches type.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<i64>();
    ///
    /// assert!(typedef.is::<i64>());
    /// ```
    #[stable]
    pub fn is<T: 'static>(&self) -> bool {
        self.type_id == TypeId::of::<T>()
    }

    /// Get the static `&str` for typedef instance.
    ///
    /// ```
    /// use typedef::{ TypeDef };
    ///
    /// let typedef = TypeDef::of::<i64>();
    ///
    /// assert!(typedef.get_str() == "i64");
    /// ```
    #[stable]
    pub fn get_str(&self) -> &'static str {
        self.type_name
    }
}

#[stable]
impl PartialEq for TypeDef {
    #[stable]
    fn eq(&self, other: &TypeDef) -> bool {
        self.type_id == other.type_id
    }
}

#[stable]
impl fmt::Show for TypeDef {
    #[stable]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.type_name)
    }
}

#[cfg(test)]
mod test {
    use super::{ TypeDef };

    #[test]
    fn should_match_type() {
        assert!(TypeDef::of::<i16>().is::<i16>());
    }

    #[test]
    #[should_fail]
    fn should_not_match_incorrect_type() {
        assert!(TypeDef::of::<i16>().is::<i32>());
    }

    #[test]
    fn should_return_type_name() {
        assert_eq!(TypeDef::of::<i16>().get_str(), "i16");
        assert_eq!(TypeDef::of::<i64>().get_str(), "i64");
    }

    #[test]
    fn should_be_equal_to_another_typedef_of_the_same_type() {
        assert_eq!(TypeDef::of::<i16>(), TypeDef::of::<i16>());
    }

    #[test]
    fn should_not_be_equal_to_another_typedef_of_different_type() {
        assert!(TypeDef::of::<i16>() != TypeDef::of::<i32>());
    }
}
<|endoftext|>