<commit_before>#![crate_id = "logger"]
#![license = "MIT"]

//! Request logging middleware for Iron

extern crate iron;
extern crate time;

use iron::{Ingot, Alloy, Request, Response};
use iron::ingot::{Status, Continue};

use time::precise_time_ns;

use std::io::stdio::println;

/// `Ingot` for logging request and response info to the terminal.
/// `Logger` logs the request method, request URI, response status, and response
/// time in the format:
/// ```
/// {method} {uri} -> {status} ({response_time} ms)
/// ```
#[deriving(Clone)]
pub struct Logger {
    entry_time: u64
}

impl Logger {
    /// Create a new `Logger`.
    pub fn new() -> Logger {
        Logger { entry_time: 0u64 }
    }
}

enum Color {
    Red,
    Yellow,
    Green,
    Blue
}

fn colorize(string: String, color: Color) -> String {
    let color_str = match color {
        Red => "\x1B[31m",
        Yellow => "\x1B[33m",
        Green => "\x1B[32m",
        Blue => "\x1B[34m"
    };
    color_str.to_string().append(string.as_slice()).append("\x1B[39m")
}

impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for Logger {
    fn enter(&mut self, _req: &mut Rq, _res: &mut Rs, _alloy: &mut Alloy) -> Status {
        self.entry_time = precise_time_ns();
        Continue
    }
    fn exit(&mut self, req: &mut Rq, res: &mut Rs, _al: &mut Alloy) -> Status {
        let status = res.status();
        let status_color = match status.code() {
            _n @ 200..299 => Green, // Success
            _n @ 300..399 => Yellow, // Redirection
            _n @ 400..599 => Red, // Error
            _ => Blue // Information
        };
        let response_time_ms = (precise_time_ns() - self.entry_time) as f64 / 1000000.0;

        let mut output = String::new();
        output.push_str(format!("\x1B[1m{}\x1B[0m {} \x1B[1m->\x1B[0m ",
                                req.method(), req.uri()).as_slice());
        output.push_str(colorize(format!("{}", status), status_color).as_slice());
        output.push_str(format!(" ({} ms)", response_time_ms).as_slice());
        println(output.as_slice());

        Continue
    }
}
<commit_msg>(refactor) Refactored logging to use the term crate.<commit_after>#![crate_id = "logger"]
#![license = "MIT"]

//! Request logging middleware for Iron

extern crate iron;
extern crate time;
extern crate term;

use std::io::IoResult;

use iron::{Ingot, Alloy, Request, Response};
use iron::ingot::{Status, Continue};

use time::precise_time_ns;

use term::{Terminal, stdout, attr, color};

/// `Ingot` for logging request and response info to the terminal.
/// `Logger` logs the request method, request URI, response status, and response
/// time in the format:
/// ```
/// {method} {uri} -> {status} ({response_time} ms)
/// ```
#[deriving(Clone)]
pub struct Logger {
    entry_time: u64
}

impl Logger {
    /// Create a new `Logger`.
    pub fn new() -> Logger {
        Logger { entry_time: 0u64 }
    }
}

impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for Logger {
    fn enter(&mut self, _req: &mut Rq, _res: &mut Rs, _alloy: &mut Alloy) -> Status {
        self.entry_time = precise_time_ns();
        Continue
    }
    fn exit(&mut self, req: &mut Rq, res: &mut Rs, _al: &mut Alloy) -> Status {
        let status = res.status();
        let status_color = match status.code() / 100 {
            1 => color::BLUE, // Information
            2 => color::GREEN, // Success
            3 => color::YELLOW, // Redirection
            _ => color::RED, // Error
        };
        let response_time_ms = (precise_time_ns() - self.entry_time) as f64 / 1000000.0;

        // Log to terminal t in the format:
        // {method} {uri} -> {status} ({response_time} ms)
        let log = |mut t: Box<Terminal<Box<Writer + Send>> + Send>| -> IoResult<()> {
            try!(t.attr(attr::Bold));
            try!(write!(t, "{}", req.method()));
            try!(t.reset());
            try!(write!(t, " {} ", req.uri()));
            try!(t.attr(attr::Bold));
            try!(write!(t, "-> "));
            try!(t.reset());
            try!(t.fg(status_color));
            try!(write!(t, "{}", status));
            try!(t.reset());
            try!(writeln!(t, " ({} ms)", response_time_ms));
            Ok(())
        };
        match stdout() {
            Some(terminal) => {
                match log(terminal) {
                    Err(e) => { println!("Error logging to terminal: {}", e); },
                    Ok(_) => ()
                }
            }
            None => { println!("Logger could not open terminal"); }
        }
        Continue
    }
}
<|endoftext|>


<commit_before>#![crate_type="lib"]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(deprecated)]

#![deny(warnings)]

extern crate core;

pub static FONT: &'static [u8] = include_bytes!("../res/unifont.font");

pub use bmp::BmpFile;
pub use color::Color;
pub use event::*;
pub use point::Point;
pub use size::Size;
pub use window::Window;

pub mod bmp;
pub mod color;
pub mod event;
pub mod point;
pub mod size;

#[cfg(target_os = "redox")]
#[path="orbital/window.rs"]
pub mod window;

#[cfg(not(target_os = "redox"))]
#[path="sdl2/window.rs"]
pub mod window;
<commit_msg>Fix compile with rustc<commit_after>#![crate_name="orbclient"]
#![crate_type="lib"]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(deprecated)]

#![deny(warnings)]

extern crate core;

pub static FONT: &'static [u8] = include_bytes!("../res/unifont.font");

pub use bmp::BmpFile;
pub use color::Color;
pub use event::*;
pub use point::Point;
pub use size::Size;
pub use window::Window;

pub mod bmp;
pub mod color;
pub mod event;
pub mod point;
pub mod size;

#[cfg(target_os = "redox")]
#[path="orbital/window.rs"]
pub mod window;

#[cfg(not(target_os = "redox"))]
#[path="sdl2/window.rs"]
pub mod window;
<|endoftext|>


<commit_before>//! A contiguous region of bytes, useful for I/O operations.
//!
//! An Iobuf consists of:
//!
//!   - a buffer
//!   - limits   (a subrange of the buffer)
//!   - a window (a subrange of the limits)
//!
//! All iobuf operations are restricted to operate within the limits. Initially,
//! the window of an Iobuf is identical to the limits. If you have an `&mut` to
//! an Iobuf, you may change the window and limits. If you only have a `&`, you
//! may not. Similarly, if you have a `RWIobuf`, you may modify the data in the
//! buffer. If you have a `ROIobuf`, you may not.
//!
//! The limits can be `narrow`ed, but never widened. The window may be set to
//! any arbitrary subrange of the limits.
//!
//! Iobufs are cheap to `clone`, since the buffers are refcounted. Use this to
//! construct multiple views into the same data.
//!
//! To keep the struct small (24 bytes!), the maximum size of an Iobuf is 2 GB.
//! Please let me know if you need more than this. I have never before seen a
//! use case for Iobufs larger than 2 GB, and it gives us a 40% smaller struct
//! compared to supporting INT64_MAX bytes. The improved size allows much better
//! register/cache usage and faster moves, both of which are critical for
//! performance.
//!
//! Although this library is designed for efficiency, and hence gives you lots
//! of ways to omit bounds checks, that does not mean it's recommended you do.
//! They merely provide a way for you to manually bounds check a whole bunch
//! of data at once (with `check_range`), and then `peek` or `poke` out the data
//! you want. See the documentation for `check_range` for an example.
//!
//! To repeat: Do not omit bounds checks unless you've checked _very_ carefully
//! that they are redundant. This can cause terrifying security issues.
//!
//! Fun tidbit: Data allocated by `Iobuf` is guaranteed to be aligned to 16 bytes.
//! This may be abused to write efficient SIMD data processing code.
#![deny(missing_docs)]
#![deny(warnings)]

#![feature(plugin)]
#![feature(core_intrinsics)]
#![feature(nonzero)]
#![feature(allocator_api)]
#![feature(alloc)]
#![feature(unique)]

#![cfg_attr(test, feature(test))]

extern crate alloc;
extern crate core;

#[cfg(test)] extern crate test;
//#[cfg(test)] extern crate quickcheck;

pub use intlike::IntLike;
pub use raw::Allocator;
pub use iobuf::Iobuf;
pub use impls::{RWIobuf, ROIobuf, AROIobuf, UniqueIobuf};
pub use ringbuf::IORingbuf;
pub use bufspan::{BufSpan, ByteIter, SpanIter, SpanMoveIter};
pub use appendbuf::AppendBuf;

mod raw;
mod intlike;
mod iobuf;
mod impls;
mod ringbuf;
mod bufspan;
mod appendbuf;
<commit_msg>Silent warnings<commit_after>//! A contiguous region of bytes, useful for I/O operations.
//!
//! An Iobuf consists of:
//!
//!   - a buffer
//!   - limits   (a subrange of the buffer)
//!   - a window (a subrange of the limits)
//!
//! All iobuf operations are restricted to operate within the limits. Initially,
//! the window of an Iobuf is identical to the limits. If you have an `&mut` to
//! an Iobuf, you may change the window and limits. If you only have a `&`, you
//! may not. Similarly, if you have a `RWIobuf`, you may modify the data in the
//! buffer. If you have a `ROIobuf`, you may not.
//!
//! The limits can be `narrow`ed, but never widened. The window may be set to
//! any arbitrary subrange of the limits.
//!
//! Iobufs are cheap to `clone`, since the buffers are refcounted. Use this to
//! construct multiple views into the same data.
//!
//! To keep the struct small (24 bytes!), the maximum size of an Iobuf is 2 GB.
//! Please let me know if you need more than this. I have never before seen a
//! use case for Iobufs larger than 2 GB, and it gives us a 40% smaller struct
//! compared to supporting INT64_MAX bytes. The improved size allows much better
//! register/cache usage and faster moves, both of which are critical for
//! performance.
//!
//! Although this library is designed for efficiency, and hence gives you lots
//! of ways to omit bounds checks, that does not mean it's recommended you do.
//! They merely provide a way for you to manually bounds check a whole bunch
//! of data at once (with `check_range`), and then `peek` or `poke` out the data
//! you want. See the documentation for `check_range` for an example.
//!
//! To repeat: Do not omit bounds checks unless you've checked _very_ carefully
//! that they are redundant. This can cause terrifying security issues.
//!
//! Fun tidbit: Data allocated by `Iobuf` is guaranteed to be aligned to 16 bytes.
//! This may be abused to write efficient SIMD data processing code.
#![deny(missing_docs)]
#![deny(warnings)]

#![feature(plugin)]
#![feature(core_intrinsics)]
#![feature(nonzero)]
#![feature(allocator_api)]
#![feature(alloc)]
#![feature(unique)]
#![feature(fn_must_use)]

#![cfg_attr(test, feature(test))]

extern crate alloc;
extern crate core;

#[cfg(test)] extern crate test;
//#[cfg(test)] extern crate quickcheck;

pub use intlike::IntLike;
pub use raw::Allocator;
pub use iobuf::Iobuf;
pub use impls::{RWIobuf, ROIobuf, AROIobuf, UniqueIobuf};
pub use ringbuf::IORingbuf;
pub use bufspan::{BufSpan, ByteIter, SpanIter, SpanMoveIter};
pub use appendbuf::AppendBuf;

mod raw;
mod intlike;
mod iobuf;
mod impls;
mod ringbuf;
mod bufspan;
mod appendbuf;
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![deny(missing_copy_implementations)]
#![deny(raw_pointer_derive)]

#![feature(libc)]

extern crate libc;

use libc::{
    c_char,
    c_int
};

#[allow(dead_code)]
enum Sass_Output_Style {
    SASS_STYLE_NESTED,
    SASS_STYLE_EXPANDED,
    SASS_STYLE_COMPACT,
    SASS_STYLE_COMPRESSED
}

extern "C" {
 pub fn sass2scss (sass: * const c_char , options: c_int) -> * const c_char;

 pub fn sass2scss_version() -> * const c_char;

}
<commit_msg>Using rust-bindgen<commit_after>#![feature(libc)]
#![allow(non_camel_case_types)]

extern crate libc;

/* automatically generated by rust-bindgen */

pub type ptrdiff_t = ::libc::c_long;
pub type size_t = ::libc::c_ulong;
pub type wchar_t = ::libc::c_int;
pub enum Union_Sass_Value { }
pub type Enum_Sass_Tag = ::libc::c_uint;
pub const SASS_BOOLEAN: ::libc::c_uint = 0;
pub const SASS_NUMBER: ::libc::c_uint = 1;
pub const SASS_COLOR: ::libc::c_uint = 2;
pub const SASS_STRING: ::libc::c_uint = 3;
pub const SASS_LIST: ::libc::c_uint = 4;
pub const SASS_MAP: ::libc::c_uint = 5;
pub const SASS_NULL: ::libc::c_uint = 6;
pub const SASS_ERROR: ::libc::c_uint = 7;
pub const SASS_WARNING: ::libc::c_uint = 8;
pub type Enum_Sass_Separator = ::libc::c_uint;
pub const SASS_COMMA: ::libc::c_uint = 0;
pub const SASS_SPACE: ::libc::c_uint = 1;
pub enum Struct_Sass_Import { }
pub enum Struct_Sass_C_Import_Descriptor { }
pub type Sass_C_Import_Callback = *mut ::libc::c_void;
pub type Sass_C_Import_Fn =
    ::std::option::Option<extern "C" fn
                              (url: *const ::libc::c_char,
                               prev: *const ::libc::c_char,
                               cookie: *mut ::libc::c_void)
                              -> *mut *mut Struct_Sass_Import>;
pub enum Struct_Sass_C_Function_Descriptor { }
pub type Sass_C_Function_List = *mut ::libc::c_void;
pub type Sass_C_Function_Callback = *mut ::libc::c_void;
pub type Sass_C_Function =
    ::std::option::Option<extern "C" fn
                              (arg1: *const Union_Sass_Value,
                               cookie: *mut ::libc::c_void)
                              -> *mut Union_Sass_Value>;
pub type Enum_Sass_Output_Style = ::libc::c_uint;
pub const SASS_STYLE_NESTED: ::libc::c_uint = 0;
pub const SASS_STYLE_EXPANDED: ::libc::c_uint = 1;
pub const SASS_STYLE_COMPACT: ::libc::c_uint = 2;
pub const SASS_STYLE_COMPRESSED: ::libc::c_uint = 3;
extern "C" {
    pub fn sass_value_get_tag(v: *const Union_Sass_Value) -> Enum_Sass_Tag;
    pub fn sass_value_is_null(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_number(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_string(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_boolean(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_color(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_list(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_map(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_error(v: *const Union_Sass_Value) -> u8;
    pub fn sass_value_is_warning(v: *const Union_Sass_Value) -> u8;
    pub fn sass_number_get_value(v: *const Union_Sass_Value)
     -> ::libc::c_double;
    pub fn sass_number_set_value(v: *mut Union_Sass_Value,
                                 value: ::libc::c_double) -> ();
    pub fn sass_number_get_unit(v: *const Union_Sass_Value)
     -> *const ::libc::c_char;
    pub fn sass_number_set_unit(v: *mut Union_Sass_Value,
                                unit: *mut ::libc::c_char) -> ();
    pub fn sass_string_get_value(v: *const Union_Sass_Value)
     -> *const ::libc::c_char;
    pub fn sass_string_set_value(v: *mut Union_Sass_Value,
                                 value: *mut ::libc::c_char) -> ();
    pub fn sass_boolean_get_value(v: *const Union_Sass_Value) -> u8;
    pub fn sass_boolean_set_value(v: *mut Union_Sass_Value, value: u8) -> ();
    pub fn sass_color_get_r(v: *const Union_Sass_Value) -> ::libc::c_double;
    pub fn sass_color_set_r(v: *mut Union_Sass_Value, r: ::libc::c_double)
     -> ();
    pub fn sass_color_get_g(v: *const Union_Sass_Value) -> ::libc::c_double;
    pub fn sass_color_set_g(v: *mut Union_Sass_Value, g: ::libc::c_double)
     -> ();
    pub fn sass_color_get_b(v: *const Union_Sass_Value) -> ::libc::c_double;
    pub fn sass_color_set_b(v: *mut Union_Sass_Value, b: ::libc::c_double)
     -> ();
    pub fn sass_color_get_a(v: *const Union_Sass_Value) -> ::libc::c_double;
    pub fn sass_color_set_a(v: *mut Union_Sass_Value, a: ::libc::c_double)
     -> ();
    pub fn sass_list_get_length(v: *const Union_Sass_Value) -> size_t;
    pub fn sass_list_get_separator(v: *const Union_Sass_Value)
     -> Enum_Sass_Separator;
    pub fn sass_list_set_separator(v: *mut Union_Sass_Value,
                                   value: Enum_Sass_Separator) -> ();
    pub fn sass_list_get_value(v: *const Union_Sass_Value, i: size_t)
     -> *mut Union_Sass_Value;
    pub fn sass_list_set_value(v: *mut Union_Sass_Value, i: size_t,
                               value: *mut Union_Sass_Value) -> ();
    pub fn sass_map_get_length(v: *const Union_Sass_Value) -> size_t;
    pub fn sass_map_get_key(v: *const Union_Sass_Value, i: size_t)
     -> *mut Union_Sass_Value;
    pub fn sass_map_set_key(v: *mut Union_Sass_Value, i: size_t,
                            arg1: *mut Union_Sass_Value) -> ();
    pub fn sass_map_get_value(v: *const Union_Sass_Value, i: size_t)
     -> *mut Union_Sass_Value;
    pub fn sass_map_set_value(v: *mut Union_Sass_Value, i: size_t,
                              arg1: *mut Union_Sass_Value) -> ();
    pub fn sass_error_get_message(v: *const Union_Sass_Value)
     -> *mut ::libc::c_char;
    pub fn sass_error_set_message(v: *mut Union_Sass_Value,
                                  msg: *mut ::libc::c_char) -> ();
    pub fn sass_warning_get_message(v: *const Union_Sass_Value)
     -> *mut ::libc::c_char;
    pub fn sass_warning_set_message(v: *mut Union_Sass_Value,
                                    msg: *mut ::libc::c_char) -> ();
    pub fn sass_make_null() -> *mut Union_Sass_Value;
    pub fn sass_make_boolean(val: u8) -> *mut Union_Sass_Value;
    pub fn sass_make_string(val: *const ::libc::c_char)
     -> *mut Union_Sass_Value;
    pub fn sass_make_number(val: ::libc::c_double,
                            unit: *const ::libc::c_char)
     -> *mut Union_Sass_Value;
    pub fn sass_make_color(r: ::libc::c_double, g: ::libc::c_double,
                           b: ::libc::c_double, a: ::libc::c_double)
     -> *mut Union_Sass_Value;
    pub fn sass_make_list(len: size_t, sep: Enum_Sass_Separator)
     -> *mut Union_Sass_Value;
    pub fn sass_make_map(len: size_t) -> *mut Union_Sass_Value;
    pub fn sass_make_error(msg: *const ::libc::c_char)
     -> *mut Union_Sass_Value;
    pub fn sass_make_warning(msg: *const ::libc::c_char)
     -> *mut Union_Sass_Value;
    pub fn sass_delete_value(val: *mut Union_Sass_Value) -> ();
    pub fn sass_clone_value(val: *const Union_Sass_Value)
     -> *mut Union_Sass_Value;
    pub fn sass_make_importer(arg1: Sass_C_Import_Fn,
                              cookie: *mut ::libc::c_void)
     -> Sass_C_Import_Callback;
    pub fn sass_import_get_function(_fn: Sass_C_Import_Callback)
     -> Sass_C_Import_Fn;
    pub fn sass_import_get_cookie(_fn: Sass_C_Import_Callback)
     -> *mut ::libc::c_void;
    pub fn sass_delete_importer(_fn: Sass_C_Import_Callback) -> ();
    pub fn sass_make_import_list(length: size_t)
     -> *mut *mut Struct_Sass_Import;
    pub fn sass_make_import_entry(path: *const ::libc::c_char,
                                  source: *mut ::libc::c_char,
                                  srcmap: *mut ::libc::c_char)
     -> *mut Struct_Sass_Import;
    pub fn sass_make_import(path: *const ::libc::c_char,
                            base: *const ::libc::c_char,
                            source: *mut ::libc::c_char,
                            srcmap: *mut ::libc::c_char)
     -> *mut Struct_Sass_Import;
    pub fn sass_import_set_list_entry(list: *mut *mut Struct_Sass_Import,
                                      idx: size_t,
                                      entry: *mut Struct_Sass_Import) -> ();
    pub fn sass_import_get_list_entry(list: *mut *mut Struct_Sass_Import,
                                      idx: size_t) -> *mut Struct_Sass_Import;
    pub fn sass_import_get_path(arg1: *mut Struct_Sass_Import)
     -> *const ::libc::c_char;
    pub fn sass_import_get_base(arg1: *mut Struct_Sass_Import)
     -> *const ::libc::c_char;
    pub fn sass_import_get_source(arg1: *mut Struct_Sass_Import)
     -> *const ::libc::c_char;
    pub fn sass_import_get_srcmap(arg1: *mut Struct_Sass_Import)
     -> *const ::libc::c_char;
    pub fn sass_import_take_source(arg1: *mut Struct_Sass_Import)
     -> *mut ::libc::c_char;
    pub fn sass_import_take_srcmap(arg1: *mut Struct_Sass_Import)
     -> *mut ::libc::c_char;
    pub fn sass_delete_import_list(arg1: *mut *mut Struct_Sass_Import) -> ();
    pub fn sass_delete_import(arg1: *mut Struct_Sass_Import) -> ();
    pub fn sass_make_function_list(length: size_t) -> Sass_C_Function_List;
    pub fn sass_make_function(signature: *const ::libc::c_char,
                              _fn: Sass_C_Function,
                              cookie: *mut ::libc::c_void)
     -> Sass_C_Function_Callback;
    pub fn sass_function_get_list_entry(list: Sass_C_Function_List,
                                        pos: size_t)
     -> Sass_C_Function_Callback;
    pub fn sass_function_set_list_entry(list: Sass_C_Function_List,
                                        pos: size_t,
                                        cb: Sass_C_Function_Callback) -> ();
    pub fn sass_function_get_signature(_fn: Sass_C_Function_Callback)
     -> *const ::libc::c_char;
    pub fn sass_function_get_function(_fn: Sass_C_Function_Callback)
     -> Sass_C_Function;
    pub fn sass_function_get_cookie(_fn: Sass_C_Function_Callback)
     -> *mut ::libc::c_void;
    pub fn sass_string_quote(str: *const ::libc::c_char,
                             quotemark: ::libc::c_char)
     -> *mut ::libc::c_char;
    pub fn sass_string_unquote(str: *const ::libc::c_char)
     -> *mut ::libc::c_char;
    pub fn libsass_version() -> *const ::libc::c_char;
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate regex;

use std::collections::HashMap;

use hyper::server::{Handler, Request, Response};
use regex::RegexSet;

use error::RouterError;

pub type RouterFn = fn(Request, Response);

pub struct Router {
    not_found: Option<RouterFn>,
    routes: RegexSet,
    route_list: Vec<String>,
    route_map: HashMap<String, RouterFn>
}

impl Handler for Router {
    // The handle method for the router simply tries to match the URI against
    // the first pattern that it can which in turn calls its associated handle
    // function passing the hyper Request and Response structures.
    fn handle(&self, req: Request, res: Response) {
        let uri = format!("{}", req.uri);
        let matches = self.routes.matches(&uri);
        let route = matches.iter().next();
        match route {
            Some(r) => {
                let key = &self.route_list[r];
                let handler = self.route_map.get(key).unwrap();
                handler(req, res);
            },
            None => self.not_found.unwrap()(req, res)
        }
    }
}

impl Router {
    /// Construct a new Router to maintain the routes and their handler
    /// functions.
    pub fn new() -> Router {
        Router {
            not_found: None,
            routes: RegexSet::new(&[""]).unwrap(),
            route_list: Vec::new(),
            route_map: HashMap::new(),
        }
    }

    /// Add a route to the router and give it a function to call when the route
    /// is matched against.
    pub fn add_route(&mut self, route: &str, handler: RouterFn) {
        self.route_list.push(route.to_owned());
        self.route_map.insert(route.to_owned(), handler);
    }

    /// This function ensures that a valid RegexSet could be made from the route
    /// vector that was built while using the `add_route` function. It also
    /// requires that there exist two or more routes so that the RegexSet can be
    /// successfully constructed.
    ///
    /// It will also ensure that there is a handler for routes that do not match
    /// any available in the set.
    pub fn finalize(&mut self) -> Result<(), RouterError> {
        if self.route_list.len() == 0  {
            return Err(RouterError::TooFewRoutes);
        }

        // Check if the user added a 404 handler, else use the default.
        match self.not_found {
            Some(_) => {},
            None => { self.not_found = Some(default_not_found); }
        }

        let re_routes = RegexSet::new(self.route_list.iter());
        match re_routes {
            Ok(r) => {
                self.routes = r;
                Ok(())
            }
            Err(_) => {
                Err(RouterError::BadSet)
            }
        }
    }

    /// Add a function to handle routes that get no matches.
    pub fn add_not_found(&mut self, not_found: RouterFn) {
        self.not_found = Some(not_found)
    }
}

fn default_not_found(req: Request, res: Response) {
    let message = format!("No route handler found for {}", req.uri);
    res.send(message.as_bytes()).unwrap();
}

mod error;

#[test]
#[should_panic]
fn less_than_two_routes() {
    fn test_handler(_: Request, _: Response) {}

    let mut router = Router::new();
    router.finalize().unwrap();
}
<commit_msg>use an Option instead for a cleaner implementation<commit_after>extern crate hyper;
extern crate regex;

use std::collections::HashMap;

use hyper::server::{Handler, Request, Response};
use regex::RegexSet;

use error::RouterError;

pub type RouterFn = fn(Request, Response);

pub struct Router {
    not_found: Option<RouterFn>,
    routes: Option<RegexSet>,
    route_list: Vec<String>,
    route_map: HashMap<String, RouterFn>
}

impl Handler for Router {
    // The handle method for the router simply tries to match the URI against
    // the first pattern that it can which in turn calls its associated handle
    // function passing the hyper Request and Response structures.
    fn handle(&self, req: Request, res: Response) {
        let uri = format!("{}", req.uri);
        let matches = self.routes.clone().unwrap().matches(&uri);
        let route = matches.iter().next();
        match route {
            Some(r) => {
                let key = &self.route_list[r];
                let handler = self.route_map.get(key).unwrap();
                handler(req, res);
            },
            None => self.not_found.unwrap()(req, res)
        }
    }
}

impl Router {
    /// Construct a new Router to maintain the routes and their handler
    /// functions.
    pub fn new() -> Router {
        Router {
            not_found: None,
            routes: None,
            route_list: Vec::new(),
            route_map: HashMap::new(),
        }
    }

    /// Add a route to the router and give it a function to call when the route
    /// is matched against.
    pub fn add_route(&mut self, route: &str, handler: RouterFn) {
        self.route_list.push(route.to_owned());
        self.route_map.insert(route.to_owned(), handler);
    }

    /// This function ensures that a valid RegexSet could be made from the route
    /// vector that was built while using the `add_route` function. It also
    /// requires that there exist two or more routes so that the RegexSet can be
    /// successfully constructed.
    ///
    /// It will also ensure that there is a handler for routes that do not match
    /// any available in the set.
    pub fn finalize(&mut self) -> Result<(), RouterError> {
        if self.route_list.len() == 0  {
            return Err(RouterError::TooFewRoutes);
        }

        // Check if the user added a 404 handler, else use the default.
        match self.not_found {
            Some(_) => {},
            None => { self.not_found = Some(default_not_found); }
        }

        let re_routes = RegexSet::new(self.route_list.iter());
        match re_routes {
            Ok(r) => {
                self.routes = Some(r);
                Ok(())
            }
            Err(_) => {
                Err(RouterError::BadSet)
            }
        }
    }

    /// Add a function to handle routes that get no matches.
    pub fn add_not_found(&mut self, not_found: RouterFn) {
        self.not_found = Some(not_found)
    }
}

fn default_not_found(req: Request, res: Response) {
    let message = format!("No route handler found for {}", req.uri);
    res.send(message.as_bytes()).unwrap();
}

mod error;

#[test]
#[should_panic]
fn less_than_two_routes() {
    fn test_handler(_: Request, _: Response) {}

    let mut router = Router::new();
    router.finalize().unwrap();
}
<|endoftext|>


<commit_before>#![cfg_attr(rustfmt, rustfmt_skip)]

// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A library that provides ASCII-only string and character types, equivalent to the `char`, `str`
//! and `String` types in the standard library.
//!
#![cfg_attr(feature = "std", doc="[The documentation for the `core` mode is here](https://tomprogrammer.github.io/rust-ascii/core/ascii/index.html).")]
#![cfg_attr(not(feature = "std"), doc="This is the documentation for `core` mode.")]
//! Please refer to the readme file to learn about the different feature modes of this crate.
//!
//! # Requirements
//!
//! - The minimum supported Rust version is 1.9.0
//! - Enabling the quickcheck feature requires Rust 1.12.0
//! - Enabling the serde feature requires Rust 1.13.0
//!
//! # History
//!
//! This package included the Ascii types that were removed from the Rust standard library by the
//! 2014-12 [reform of the `std::ascii` module](https://github.com/rust-lang/rfcs/pull/486). The
//! API changed significantly since then.

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "std")]
extern crate core;

#[cfg(feature = "quickcheck")]
extern crate quickcheck;

#[cfg(feature = "serde")]
extern crate serde;

#[cfg(all(test, feature = "serde_test"))]
extern crate serde_test;

mod ascii_char;
mod ascii_str;
#[cfg(feature = "std")]
mod ascii_string;
mod free_functions;
#[cfg(feature = "serde")]
mod serialization;

pub use ascii_char::{AsciiChar, ToAsciiChar, ToAsciiCharError};
pub use ascii_str::{AsciiStr, AsAsciiStr, AsMutAsciiStr, AsAsciiStrError, Chars, CharsMut, Lines};
#[cfg(feature = "std")]
pub use ascii_string::{AsciiString, IntoAsciiString, FromAsciiError};
pub use free_functions::{caret_encode, caret_decode};
<commit_msg>Remove no_std docs link<commit_after>#![cfg_attr(rustfmt, rustfmt_skip)]

// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A library that provides ASCII-only string and character types, equivalent to the `char`, `str`
//! and `String` types in the standard library.
//!
//! Please refer to the readme file to learn about the different feature modes of this crate.
//!
//! # Requirements
//!
//! - The minimum supported Rust version is 1.9.0
//! - Enabling the quickcheck feature requires Rust 1.12.0
//! - Enabling the serde feature requires Rust 1.13.0
//!
//! # History
//!
//! This package included the Ascii types that were removed from the Rust standard library by the
//! 2014-12 [reform of the `std::ascii` module](https://github.com/rust-lang/rfcs/pull/486). The
//! API changed significantly since then.

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "std")]
extern crate core;

#[cfg(feature = "quickcheck")]
extern crate quickcheck;

#[cfg(feature = "serde")]
extern crate serde;

#[cfg(all(test, feature = "serde_test"))]
extern crate serde_test;

mod ascii_char;
mod ascii_str;
#[cfg(feature = "std")]
mod ascii_string;
mod free_functions;
#[cfg(feature = "serde")]
mod serialization;

pub use ascii_char::{AsciiChar, ToAsciiChar, ToAsciiCharError};
pub use ascii_str::{AsciiStr, AsAsciiStr, AsMutAsciiStr, AsAsciiStrError, Chars, CharsMut, Lines};
#[cfg(feature = "std")]
pub use ascii_string::{AsciiString, IntoAsciiString, FromAsciiError};
pub use free_functions::{caret_encode, caret_decode};
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use glib::translate::*;
use ffi;

use surface::Surface;

pub struct XCBDrawable(pub u32);

impl XCBDrawable {
    fn to_glib_none(&self) -> u32 {
        self.0
    }
}

pub struct XCBPixmap(pub u32);

impl XCBPixmap {
    fn to_glib_none(&self) -> u32 {
        self.0
    }
}

pub struct XCBConnection(pub *mut ffi::xcb_connection_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_connection_t> for &'a XCBConnection {
    type Storage = &'a XCBConnection;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_connection_t, &'a XCBConnection> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_connection_t> for XCBConnection {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_connection_t) -> XCBConnection {
        assert!(!ptr.is_null());
        XCBConnection(ptr)
    }

    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_connection_t) -> XCBConnection {
        assert!(!ptr.is_null());
        XCBConnection(ptr)
    }
}

impl AsRef<XCBConnection> for XCBConnection {
    fn as_ref(&self) -> &XCBConnection {
        self
    }
}

impl Clone for XCBConnection {
    fn clone(&self) -> XCBConnection {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct XCBRenderPictFormInfo(pub *mut ffi::xcb_render_pictforminfo_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_render_pictforminfo_t> for &'a XCBRenderPictFormInfo {
    type Storage = &'a XCBRenderPictFormInfo;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_render_pictforminfo_t, &'a XCBRenderPictFormInfo> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo {
        assert!(!ptr.is_null());
        XCBRenderPictFormInfo(ptr)
    }

    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo {
        assert!(!ptr.is_null());
        XCBRenderPictFormInfo(ptr)
    }
}

impl AsRef<XCBRenderPictFormInfo> for XCBRenderPictFormInfo {
    fn as_ref(&self) -> &XCBRenderPictFormInfo {
        self
    }
}

impl Clone for XCBRenderPictFormInfo {
    fn clone(&self) -> XCBRenderPictFormInfo {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct XCBScreen(pub *mut ffi::xcb_screen_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_screen_t> for &'a XCBScreen {
    type Storage = &'a XCBScreen;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_screen_t, &'a XCBScreen> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_screen_t> for XCBScreen {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_screen_t) -> XCBScreen {
        assert!(!ptr.is_null());
        XCBScreen(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_screen_t> for XCBScreen {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_screen_t) -> XCBScreen {
        assert!(!ptr.is_null());
        XCBScreen(ptr)
    }
}

impl AsRef<XCBScreen> for XCBScreen {
    fn as_ref(&self) -> &XCBScreen {
        self
    }
}

impl Clone for XCBScreen {
    fn clone(&self) -> XCBScreen {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub trait XCBSurface {
    fn create(connection: &XCBConnection, drawable: &XCBDrawable, visual: &XCBVisualType,
              width: i32, height: i32) -> Surface;
    fn create_for_bitmap(connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap,
                         width: i32, height: i32) -> Surface;
    fn create_with_xrender_format(connection: &XCBConnection, screen: &XCBScreen,
                                  bitmap: &XCBPixmap, format: &XCBRenderPictFormInfo,
                                  width: i32, height: i32) -> Surface;
    fn set_size(&self, width: i32, height: i32);
    fn set_drawable(&self, drawable: &XCBDrawable, width: i32, height: i32);
}

impl XCBSurface for Surface {
    fn create(connection: &XCBConnection, drawable: &XCBDrawable, visual: &XCBVisualType,
              width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create(connection.to_glib_none().0,
                                                         drawable.to_glib_none(),
                                                         visual.to_glib_none().0,
                                                         width,
                                                         height))
        }
    }

    fn create_for_bitmap(connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap,
                         width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create_for_bitmap(connection.to_glib_none().0,
                                                                    screen.to_glib_none().0,
                                                                    bitmap.to_glib_none(),
                                                                    width,
                                                                    height))
        }
    }

    fn create_with_xrender_format(connection: &XCBConnection, screen: &XCBScreen,
                                  bitmap: &XCBPixmap, format: &XCBRenderPictFormInfo,
                                  width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create_with_xrender_format(connection.to_glib_none().0,
                                                                             screen.to_glib_none().0,
                                                                             bitmap.to_glib_none(),
                                                                             format.to_glib_none().0,
                                                                             width,
                                                                             height))
        }
    }

    fn set_size(self: &Surface, width: i32, height: i32) {
        unsafe {
            ffi::cairo_xcb_surface_set_size(self.to_glib_none().0, width, height)
        }
    }

    fn set_drawable(self: &Surface, drawable: &XCBDrawable, width: i32, height: i32) {
        unsafe {
            ffi::cairo_xcb_surface_set_drawable(self.to_glib_none().0, drawable.to_glib_none(),
                                                width, height)
        }
    }
}

pub struct XCBVisualType(pub *mut ffi::xcb_visualtype_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_visualtype_t> for &'a XCBVisualType {
    type Storage = &'a XCBVisualType;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_visualtype_t, &'a XCBVisualType> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_visualtype_t> for XCBVisualType {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType {
        assert!(!ptr.is_null());
        XCBVisualType(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_visualtype_t> for XCBVisualType {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType {
        assert!(!ptr.is_null());
        XCBVisualType(ptr)
    }
}

impl AsRef<XCBVisualType> for XCBVisualType {
    fn as_ref(&self) -> &XCBVisualType {
        self
    }
}

impl Clone for XCBVisualType {
    fn clone(&self) -> XCBVisualType {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct Device(pub *mut ffi::cairo_device_t);

impl<'a> ToGlibPtr<'a, *mut ffi::cairo_device_t> for &'a Device {
    type Storage = &'a Device;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_device_t, &'a Device> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::cairo_device_t> for Device {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::cairo_device_t) -> Device {
        assert!(!ptr.is_null());
        Device(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::cairo_device_t> for Device {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::cairo_device_t) -> Device {
        assert!(!ptr.is_null());
        Device(ptr)
    }
}

impl AsRef<Device> for Device {
    fn as_ref(&self) -> &Device {
        self
    }
}

impl Clone for Device {
    fn clone(&self) -> Device {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

impl Device {
    pub fn get_connection(&self) -> XCBConnection {
        unsafe {
            from_glib_full(ffi::cairo_xcb_device_get_connection(self.to_glib_none().0))
        }
    }

    pub fn debug_cap_xrender_version(&self, major_version: i32, minor_version: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_cap_xrender_version(self.to_glib_none().0,
                                                            major_version,
                                                            minor_version)
        }
    }

    pub fn debug_cap_xshm_version(&self, major_version: i32, minor_version: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_cap_xshm_version(self.to_glib_none().0,
                                                         major_version,
                                                         minor_version)
        }
    }

    pub fn debug_get_precision(&self) -> i32 {
        unsafe {
            ffi::cairo_xcb_device_debug_get_precision(self.to_glib_none().0)
        }
    }

    pub fn debug_set_precision(&self, precision: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_set_precision(self.to_glib_none().0, precision)
        }
    }
}
<commit_msg>fix xcb features<commit_after>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use glib::translate::*;
use ffi;

use surface::Surface;

pub struct XCBDrawable(pub u32);

impl XCBDrawable {
    fn to_glib_none(&self) -> u32 {
        self.0
    }
}

pub struct XCBPixmap(pub u32);

impl XCBPixmap {
    fn to_glib_none(&self) -> u32 {
        self.0
    }
}

pub struct XCBConnection(pub *mut ffi::xcb_connection_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_connection_t> for &'a XCBConnection {
    type Storage = &'a XCBConnection;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_connection_t, &'a XCBConnection> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_connection_t> for XCBConnection {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_connection_t) -> XCBConnection {
        assert!(!ptr.is_null());
        XCBConnection(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_connection_t> for XCBConnection {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_connection_t) -> XCBConnection {
        assert!(!ptr.is_null());
        XCBConnection(ptr)
    }
}

impl AsRef<XCBConnection> for XCBConnection {
    fn as_ref(&self) -> &XCBConnection {
        self
    }
}

impl Clone for XCBConnection {
    fn clone(&self) -> XCBConnection {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct XCBRenderPictFormInfo(pub *mut ffi::xcb_render_pictforminfo_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_render_pictforminfo_t> for &'a XCBRenderPictFormInfo {
    type Storage = &'a XCBRenderPictFormInfo;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_render_pictforminfo_t, &'a XCBRenderPictFormInfo> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo {
        assert!(!ptr.is_null());
        XCBRenderPictFormInfo(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_render_pictforminfo_t> for XCBRenderPictFormInfo {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_render_pictforminfo_t) -> XCBRenderPictFormInfo {
        assert!(!ptr.is_null());
        XCBRenderPictFormInfo(ptr)
    }
}

impl AsRef<XCBRenderPictFormInfo> for XCBRenderPictFormInfo {
    fn as_ref(&self) -> &XCBRenderPictFormInfo {
        self
    }
}

impl Clone for XCBRenderPictFormInfo {
    fn clone(&self) -> XCBRenderPictFormInfo {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct XCBScreen(pub *mut ffi::xcb_screen_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_screen_t> for &'a XCBScreen {
    type Storage = &'a XCBScreen;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_screen_t, &'a XCBScreen> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_screen_t> for XCBScreen {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_screen_t) -> XCBScreen {
        assert!(!ptr.is_null());
        XCBScreen(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_screen_t> for XCBScreen {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_screen_t) -> XCBScreen {
        assert!(!ptr.is_null());
        XCBScreen(ptr)
    }
}

impl AsRef<XCBScreen> for XCBScreen {
    fn as_ref(&self) -> &XCBScreen {
        self
    }
}

impl Clone for XCBScreen {
    fn clone(&self) -> XCBScreen {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub trait XCBSurface {
    fn create(connection: &XCBConnection, drawable: &XCBDrawable, visual: &XCBVisualType,
              width: i32, height: i32) -> Surface;
    fn create_for_bitmap(connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap,
                         width: i32, height: i32) -> Surface;
    fn create_with_xrender_format(connection: &XCBConnection, screen: &XCBScreen,
                                  bitmap: &XCBPixmap, format: &XCBRenderPictFormInfo,
                                  width: i32, height: i32) -> Surface;
    fn set_size(&self, width: i32, height: i32);
    fn set_drawable(&self, drawable: &XCBDrawable, width: i32, height: i32);
}

impl XCBSurface for Surface {
    fn create(connection: &XCBConnection, drawable: &XCBDrawable, visual: &XCBVisualType,
              width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create(connection.to_glib_none().0,
                                                         drawable.to_glib_none(),
                                                         visual.to_glib_none().0,
                                                         width,
                                                         height))
        }
    }

    fn create_for_bitmap(connection: &XCBConnection, screen: &XCBScreen, bitmap: &XCBPixmap,
                         width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create_for_bitmap(connection.to_glib_none().0,
                                                                    screen.to_glib_none().0,
                                                                    bitmap.to_glib_none(),
                                                                    width,
                                                                    height))
        }
    }

    fn create_with_xrender_format(connection: &XCBConnection, screen: &XCBScreen,
                                  bitmap: &XCBPixmap, format: &XCBRenderPictFormInfo,
                                  width: i32, height: i32) -> Surface {
        unsafe {
            from_glib_full(ffi::cairo_xcb_surface_create_with_xrender_format(connection.to_glib_none().0,
                                                                             screen.to_glib_none().0,
                                                                             bitmap.to_glib_none(),
                                                                             format.to_glib_none().0,
                                                                             width,
                                                                             height))
        }
    }

    fn set_size(self: &Surface, width: i32, height: i32) {
        unsafe {
            ffi::cairo_xcb_surface_set_size(self.to_glib_none().0, width, height)
        }
    }

    fn set_drawable(self: &Surface, drawable: &XCBDrawable, width: i32, height: i32) {
        unsafe {
            ffi::cairo_xcb_surface_set_drawable(self.to_glib_none().0, drawable.to_glib_none(),
                                                width, height)
        }
    }
}

pub struct XCBVisualType(pub *mut ffi::xcb_visualtype_t);

impl<'a> ToGlibPtr<'a, *mut ffi::xcb_visualtype_t> for &'a XCBVisualType {
    type Storage = &'a XCBVisualType;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::xcb_visualtype_t, &'a XCBVisualType> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::xcb_visualtype_t> for XCBVisualType {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType {
        assert!(!ptr.is_null());
        XCBVisualType(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::xcb_visualtype_t> for XCBVisualType {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::xcb_visualtype_t) -> XCBVisualType {
        assert!(!ptr.is_null());
        XCBVisualType(ptr)
    }
}

impl AsRef<XCBVisualType> for XCBVisualType {
    fn as_ref(&self) -> &XCBVisualType {
        self
    }
}

impl Clone for XCBVisualType {
    fn clone(&self) -> XCBVisualType {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

pub struct Device(pub *mut ffi::cairo_device_t);

impl<'a> ToGlibPtr<'a, *mut ffi::cairo_device_t> for &'a Device {
    type Storage = &'a Device;

    #[inline]
    fn to_glib_none(&self) -> Stash<'a, *mut ffi::cairo_device_t, &'a Device> {
        Stash(self.0, *self)
    }
}

impl FromGlibPtrNone<*mut ffi::cairo_device_t> for Device {
    #[inline]
    unsafe fn from_glib_none(ptr: *mut ffi::cairo_device_t) -> Device {
        assert!(!ptr.is_null());
        Device(ptr)
    }
}

impl FromGlibPtrFull<*mut ffi::cairo_device_t> for Device {
    #[inline]
    unsafe fn from_glib_full(ptr: *mut ffi::cairo_device_t) -> Device {
        assert!(!ptr.is_null());
        Device(ptr)
    }
}

impl AsRef<Device> for Device {
    fn as_ref(&self) -> &Device {
        self
    }
}

impl Clone for Device {
    fn clone(&self) -> Device {
        unsafe { from_glib_none(self.to_glib_none().0) }
    }
}

impl Device {
    pub fn get_connection(&self) -> XCBConnection {
        unsafe {
            from_glib_full(ffi::cairo_xcb_device_get_connection(self.to_glib_none().0))
        }
    }

    pub fn debug_cap_xrender_version(&self, major_version: i32, minor_version: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_cap_xrender_version(self.to_glib_none().0,
                                                            major_version,
                                                            minor_version)
        }
    }

    pub fn debug_cap_xshm_version(&self, major_version: i32, minor_version: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_cap_xshm_version(self.to_glib_none().0,
                                                         major_version,
                                                         minor_version)
        }
    }

    pub fn debug_get_precision(&self) -> i32 {
        unsafe {
            ffi::cairo_xcb_device_debug_get_precision(self.to_glib_none().0)
        }
    }

    pub fn debug_set_precision(&self, precision: i32) {
        unsafe {
            ffi::cairo_xcb_device_debug_set_precision(self.to_glib_none().0, precision)
        }
    }
}
<|endoftext|>


<commit_before>/*!
  This moule contain XDR encoder and decoder
 */

use std::io;
use std::fmt;
use std::error;
use std::vec::Vec;
use byteorder;
use byteorder::{BigEndian,ReadBytesExt,WriteBytesExt};

const PADDING : usize = 4;

#[derive(Debug)]
pub enum Error {
	Io(byteorder::Error),
	InvalidValue,
	InvalidType,
}

impl From<byteorder::Error> for Error {
	fn from(err: byteorder::Error) -> Error { Error::Io(err) }
}

impl From<Error> for byteorder::Error {
	fn from(err: Error) -> byteorder::Error {
		match err {
			Error::Io(err) => err,
			Error::InvalidValue => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid value")),
			Error::InvalidType => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid type")),
		}
	}
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match *self {
			Error::InvalidValue => write!(f, "Invalid value."),
			Error::InvalidType => write!(f, "Invalid type."),
			Error::Io(ref err) => err.fmt(f),
		}
	}
}

impl error::Error for Error {
	fn description(&self) -> &str {
		match *self {
			Error::InvalidValue => "Invalid value.",
			Error::InvalidType => "Invalid type.",
			Error::Io(ref err) => error::Error::description(err),
		}
	}

	fn cause(&self) -> Option<&error::Error> {
		match *self {
			Error::InvalidValue => None,
			Error::InvalidType => None,
			Error::Io(ref err) => err.cause(),
		}
	}
}

pub struct XdrReader<'a> {
	reader : io::Cursor<&'a [u8]>
}

pub struct XdrWriter {
	writer : io::Cursor<Vec<u8>>
}

impl XdrWriter {
	pub fn new() -> XdrWriter {
		let v : Vec<u8>= Vec::new();
		XdrWriter{ writer: io::Cursor::new(v)}
	}

	pub fn into_buffer(self) -> Vec<u8> {
		self.writer.into_inner()
	}

	pub fn pack<T:XdrPrimitive>(&mut self, x:T) {
		XdrPrimitive::write_to_xdr(self, x)
	}

	pub fn pack_array<T:XdrPrimitive>(&mut self, x:Vec<T>) {
		for t in x {
			XdrPrimitive::write_to_xdr(self,t);
		};
	}
	pub fn pack_opaque_var_len(&mut self, x:Vec<u8>) {
		XdrPrimitive::write_to_xdr(self,x.len() as u32);
		for t in x {
			let _ = self.writer.write_u8(t);
		}
	}
	pub fn pack_opaque_fixed_len(&mut self, x:Vec<u8>) {
		for t in x {
			let _ = self.writer.write_u8(t);
		}
	}
	pub fn pad(&mut self, len : usize) {
		for _ in 0..len {
			let _ = self.writer.write_u8(0);
		}
	}

}
impl<'a> XdrReader<'a> {
	pub fn new(x:&'a Vec<u8>) -> XdrReader<'a> {
		XdrReader{ reader : io::Cursor::new(&x) }
	}

	pub fn from_array(x: &'a [u8]) -> XdrReader<'a> {
		XdrReader{ reader: io::Cursor::new(x) }
	}

	pub fn unpack<T: XdrPrimitive>(&mut self) -> Result<T,Error> {
		T::read_from_xdr(self)
	}

	pub fn unpack_array<T:XdrPrimitive>(&mut self, n : usize) -> Result<Vec<T>,Error> {
		let mut result : Vec<T> = Vec::with_capacity(n);

		for _ in 0..n {
			let t =  T::read_from_xdr(self).unwrap();
			result.push(t)
		};
		Ok(result)
	}
	pub fn unpack_opaque_var_len(&mut self) -> Result<Vec<u8>, Error> {
		let len = self.unpack::<u32>().unwrap() as usize;
		let mut v : Vec<u8>= Vec::with_capacity(len);

		for _ in 0..len {
			v.push(self.reader.read_u8().unwrap())
		}
		Ok(v)
	}
	pub fn unpack_opaque_fixed_len(&mut self, len : usize) -> Result<Vec<u8>, Error> {
		let mut v : Vec<u8>= Vec::with_capacity(len);

		for _ in 0..len {
			v.push(self.reader.read_u8().unwrap())
		}
		Ok(v)
	}
}

pub trait XdrPrimitive {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>;
	fn write_to_xdr(x: &mut XdrWriter, v: Self);
}

impl<T:XdrPrimitive> XdrPrimitive for Vec<T> {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let count = x.unpack::<u32>().unwrap() as usize;
		let mut result : Vec<T> = Vec::with_capacity(count);

		for _ in 0..count {
			result.push(x.unpack::<T>().unwrap());
		};
		Ok(result)
	}
	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		x.pack( v.len() as u32 );
		for t in v {
			x.pack(t);
		};
	}
}

impl XdrPrimitive for String {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let len = x.unpack::<u32>().unwrap() as usize;
		let pad = PADDING - (len % PADDING);
		let bytes = x.unpack_opaque_fixed_len(len).unwrap();

		if pad != 0 {
			let _ = x.unpack_opaque_fixed_len(pad);
		};
		match String::from_utf8(bytes) {
			Ok(s) => Ok(s),
			Err(_) => Err(Error::InvalidValue)
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		let bytes = v.into_bytes();
		let bytes_len = bytes.len();
		let pad = PADDING - (bytes_len % PADDING);
		x.pack_opaque_var_len(bytes);

		x.pad(pad);
	}
}

impl XdrPrimitive for u32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u32, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u16, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u16),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for u8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u8, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u8),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u32::<byteorder::BigEndian>(v as u32).unwrap();
	}
}
impl XdrPrimitive for i8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i8, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i8),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i16, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i16),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v as i32).unwrap();
	}
}
impl XdrPrimitive for i32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i32, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for i64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i64, Error>{
		match x.reader.read_i64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_i64::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for u64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u64, Error>{
		match x.reader.read_u64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_u64::<byteorder::BigEndian>(v).unwrap();
	}
}

impl XdrPrimitive for f32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f32, Error>{
		match x.reader.read_f32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f32::<byteorder::BigEndian>(v).unwrap();
	}
}
impl XdrPrimitive for f64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f64, Error>{
		match x.reader.read_f64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		x.writer.write_f64::<byteorder::BigEndian>(v).unwrap();
	}
}

impl XdrPrimitive for bool {
	fn read_from_xdr(x: &mut XdrReader) -> Result<bool, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(0) => Ok(false),
			Ok(1) => Ok(true),
			Ok(_) => Err(Error::InvalidValue),
			Err(v) => Err(Error::Io(v))
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		match v {
			true => x.writer.write_u32::<byteorder::BigEndian>(1).unwrap(),
			false => x.writer.write_u32::<byteorder::BigEndian>(0).unwrap(),
		}
	}
}
<commit_msg>Remove unwrap calls<commit_after>/*!
  This moule contain XDR encoder and decoder
 */

use std::io;
use std::fmt;
use std::error;
use std::vec::Vec;
use byteorder;
use byteorder::{BigEndian,ReadBytesExt,WriteBytesExt};

const PADDING : usize = 4;

#[derive(Debug)]
pub enum Error {
	Io(byteorder::Error),
	InvalidValue,
	InvalidType,
}

impl From<byteorder::Error> for Error {
	fn from(err: byteorder::Error) -> Error { Error::Io(err) }
}

impl From<Error> for byteorder::Error {
	fn from(err: Error) -> byteorder::Error {
		match err {
			Error::Io(err) => err,
			Error::InvalidValue => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid value")),
			Error::InvalidType => byteorder::Error::Io(io::Error::new(io::ErrorKind::Other, "Invalid type")),
		}
	}
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match *self {
			Error::InvalidValue => write!(f, "Invalid value."),
			Error::InvalidType => write!(f, "Invalid type."),
			Error::Io(ref err) => err.fmt(f),
		}
	}
}

impl error::Error for Error {
	fn description(&self) -> &str {
		match *self {
			Error::InvalidValue => "Invalid value.",
			Error::InvalidType => "Invalid type.",
			Error::Io(ref err) => error::Error::description(err),
		}
	}

	fn cause(&self) -> Option<&error::Error> {
		match *self {
			Error::InvalidValue => None,
			Error::InvalidType => None,
			Error::Io(ref err) => err.cause(),
		}
	}
}

pub struct XdrReader<'a> {
	reader : io::Cursor<&'a [u8]>
}

pub struct XdrWriter {
	writer : io::Cursor<Vec<u8>>
}

impl XdrWriter {
	pub fn new() -> XdrWriter {
		let v : Vec<u8>= Vec::new();
		XdrWriter{ writer: io::Cursor::new(v)}
	}

	pub fn into_buffer(self) -> Vec<u8> {
		self.writer.into_inner()
	}

	pub fn pack<T:XdrPrimitive>(&mut self, x:T) {
		XdrPrimitive::write_to_xdr(self, x)
	}

	pub fn pack_array<T:XdrPrimitive>(&mut self, x:Vec<T>) {
		for t in x {
			XdrPrimitive::write_to_xdr(self,t);
		};
	}
	pub fn pack_opaque_var_len(&mut self, x:Vec<u8>) {
		XdrPrimitive::write_to_xdr(self,x.len() as u32);
		for t in x {
			let _ = self.writer.write_u8(t);
		}
	}
	pub fn pack_opaque_fixed_len(&mut self, x:Vec<u8>) {
		for t in x {
			let _ = self.writer.write_u8(t);
		}
	}
	pub fn pad(&mut self, len : usize) {
		for _ in 0..len {
			let _ = self.writer.write_u8(0);
		}
	}

}
impl<'a> XdrReader<'a> {
	pub fn new(x:&'a Vec<u8>) -> XdrReader<'a> {
		XdrReader{ reader : io::Cursor::new(&x) }
	}

	pub fn from_array(x: &'a [u8]) -> XdrReader<'a> {
		XdrReader{ reader: io::Cursor::new(x) }
	}

	pub fn unpack<T: XdrPrimitive>(&mut self) -> Result<T,Error> {
		T::read_from_xdr(self)
	}

	pub fn unpack_array<T:XdrPrimitive>(&mut self, n : usize) -> Result<Vec<T>,Error> {
		let mut result : Vec<T> = Vec::with_capacity(n);

		for _ in 0..n {
			let t =  T::read_from_xdr(self);
			match t {
				Ok(v) => result.push(v),
				Err(v) => return Err(v),
			}
		};
		Ok(result)
	}
	pub fn unpack_opaque_var_len(&mut self) -> Result<Vec<u8>, Error> {
		let len = match self.unpack::<u32>() {
			Ok(t) => t as usize,
			Err(t) => return Err(t),
		};
		let mut v : Vec<u8>= Vec::with_capacity(len);

		for _ in 0..len {
			match self.reader.read_u8() {
				Ok(t) => v.push(t),
				Err(t) => return Err(Error::Io(t))
			}
		}
		Ok(v)
	}
	pub fn unpack_opaque_fixed_len(&mut self, len : usize) -> Result<Vec<u8>, Error> {
		let mut v : Vec<u8>= Vec::with_capacity(len);

		for _ in 0..len {
			match self.reader.read_u8() {
				Ok(t) => v.push(t),
				Err(t) => return Err(Error::Io(t))
			}
		}
		Ok(v)
	}
}

pub trait XdrPrimitive {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>;
	fn write_to_xdr(x: &mut XdrWriter, v: Self);
}

impl<T:XdrPrimitive> XdrPrimitive for Vec<T> {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let count = match x.unpack::<u32>() {
						Ok(t) => t as usize,
						Err(t) => return Err(t),
		};
		let mut result : Vec<T> = Vec::with_capacity(count);

		for _ in 0..count {
			match x.unpack::<T>() {
				Ok(t) => result.push(t),
				Err(t) => return Err(t),
			}
		};
		Ok(result)
	}
	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		x.pack( v.len() as u32 );
		for t in v {
			x.pack(t);
		};
	}
}

impl XdrPrimitive for String {
	fn read_from_xdr(x: &mut XdrReader) -> Result<Self, Error>{
		let len = match x.unpack::<u32>() {
					Ok(t) => t as usize,
					Err(t) => return Err(t),
		};
		let pad = PADDING - (len % PADDING);
		let bytes = match x.unpack_opaque_fixed_len(len) {
			Ok(t) => t,
			Err(t) => return Err(t),
		};

		if pad != 0 {
			let _ = x.unpack_opaque_fixed_len(pad);
		};
		match String::from_utf8(bytes) {
			Ok(s) => Ok(s),
			Err(_) => Err(Error::InvalidValue)
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v: Self) {
		let bytes = v.into_bytes();
		let bytes_len = bytes.len();
		let pad = PADDING - (bytes_len % PADDING);
		x.pack_opaque_var_len(bytes);

		x.pad(pad);
	}
}

impl XdrPrimitive for u32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u32, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_u32::<byteorder::BigEndian>(v);
	}
}
impl XdrPrimitive for u16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u16, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u16),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_u32::<byteorder::BigEndian>(v as u32);
	}
}
impl XdrPrimitive for u8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u8, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as u8),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_u32::<byteorder::BigEndian>(v as u32);
	}
}
impl XdrPrimitive for i8 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i8, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i8),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_i32::<byteorder::BigEndian>(v as i32);
	}
}
impl XdrPrimitive for i16 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i16, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v as i16),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_i32::<byteorder::BigEndian>(v as i32);
	}
}
impl XdrPrimitive for i32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i32, Error>{
		match x.reader.read_i32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_i32::<byteorder::BigEndian>(v);
	}
}
impl XdrPrimitive for i64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<i64, Error>{
		match x.reader.read_i64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_i64::<byteorder::BigEndian>(v);
	}
}
impl XdrPrimitive for u64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<u64, Error>{
		match x.reader.read_u64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_u64::<byteorder::BigEndian>(v);
	}
}

impl XdrPrimitive for f32 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f32, Error>{
		match x.reader.read_f32::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_f32::<byteorder::BigEndian>(v);
	}
}
impl XdrPrimitive for f64 {
	fn read_from_xdr(x: &mut XdrReader) -> Result<f64, Error>{
		match x.reader.read_f64::<byteorder::BigEndian>() {
			Ok(v) => Ok(v),
			Err(v) => Err(Error::Io(v))
		}
	}
	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = x.writer.write_f64::<byteorder::BigEndian>(v);
	}
}

impl XdrPrimitive for bool {
	fn read_from_xdr(x: &mut XdrReader) -> Result<bool, Error>{
		match x.reader.read_u32::<byteorder::BigEndian>() {
			Ok(0) => Ok(false),
			Ok(1) => Ok(true),
			Ok(_) => Err(Error::InvalidValue),
			Err(v) => Err(Error::Io(v))
		}
	}

	fn write_to_xdr(x: &mut XdrWriter, v:Self) {
		let _ = match v {
			true => x.writer.write_u32::<byteorder::BigEndian>(1),
			false => x.writer.write_u32::<byteorder::BigEndian>(0),
		};
	}
}
<|endoftext|>


<commit_before>use glam::f32::Vec2;
use serde::{Deserialize, Serialize};

use crate::components::*;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum PlayerUpdate {
    Move(PlayerMoveInputEvent),
    Shoot(PlayerShootInputEvent),
    Use(GameEntityId),
    // The player wants to exit the current game session
    Exit,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ClientMessage {
    JoinGame(GameEntityId),
    LeaveGame,
    PlayerInputEvent(PlayerInputEvent),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum PlayerInputEvent {
    Move(PlayerMoveInputEvent),
    Shoot(PlayerShootInputEvent),
    Use(GameEntityId),
    // The player wants to exit the current game session
    Exit,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PlayerMoveInputEvent {
    pub direction: Vec2,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PlayerShootInputEvent {
    pub direction: Vec2,
}
<commit_msg>Remove Exit variant from PlayerUpdate<commit_after>use glam::f32::Vec2;
use serde::{Deserialize, Serialize};

use crate::components::*;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum PlayerUpdate {
    Move(PlayerMoveInputEvent),
    Shoot(PlayerShootInputEvent),
    Use(GameEntityId),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ClientMessage {
    JoinGame(GameEntityId),
    LeaveGame,
    PlayerInputEvent(PlayerInputEvent),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum PlayerInputEvent {
    Move(PlayerMoveInputEvent),
    Shoot(PlayerShootInputEvent),
    Use(GameEntityId),
    // The player wants to exit the current game session
    Exit,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PlayerMoveInputEvent {
    pub direction: Vec2,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PlayerShootInputEvent {
    pub direction: Vec2,
}
<|endoftext|>


<commit_before>extern crate file_dialog;
extern crate glfw_window;
extern crate shader_version;
extern crate opengl_graphics;

use file_dialog::FileDialog;
use glfw_window::GlfwWindow;
use opengl_graphics::glyph_cache::GlyphCache as Font;
use shader_version::opengl::OpenGL;

use std::io::fs::PathExtensions;

fn main() {
    let font = Font::new(&Path::new("./assets/Dense-Regular.otf")).unwrap();

    let promise = FileDialog::new("File Dialog Test", font)
        .show(GlfwWindow::new, OpenGL::OpenGL_3_2);

    println!("Selected file: {}", promise.unwrap().display());
}
<commit_msg>Add file save example<commit_after>extern crate file_dialog;
extern crate sdl2_window;
extern crate shader_version;
extern crate opengl_graphics;

use file_dialog::{FileDialog, SelectType};
use sdl2_window::Sdl2Window;
use opengl_graphics::glyph_cache::GlyphCache as Font;
use shader_version::opengl::OpenGL;

fn main() {
    let promise = FileDialog::new("File Dialog Test", font())
        .show(Sdl2Window::new, OpenGL::OpenGL_3_2);

    println!("Selected file: {}", promise.unwrap().display());

    let promise = FileDialog::new("File Save Test", font())
        .set_select(SelectType::SaveFile(Some("filename.txt".into_string())))
        .show(Sdl2Window::new, OpenGL::OpenGL_3_2);

    println!("Selected file: {}", promise.unwrap().display());
}

fn font() -> Font {
    Font::new(&Path::new("./assets/Dense-Regular.otf")).unwrap()
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use anyhow::{ensure, format_err, Context as _, Result};
use libra_config::config::RoleType;
use libra_crypto::x25519;
use libra_logger::prelude::*;
use libra_network_address::NetworkAddress;
use libra_types::{
    account_config,
    account_state::AccountState,
    account_state_blob::AccountStateWithProof,
    epoch_change::EpochChangeProof,
    ledger_info::LedgerInfoWithSignatures,
    on_chain_config::ValidatorSet,
    proof::AccumulatorConsistencyProof,
    trusted_state::{TrustedState, TrustedStateChange},
    validator_info::ValidatorInfo,
    PeerId,
};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, convert::TryFrom};

/// OnchainDiscovery LibraNet message types. These are sent over-the-wire.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OnchainDiscoveryMsg {
    QueryDiscoverySetRequest(QueryDiscoverySetRequest),
    QueryDiscoverySetResponse(Box<QueryDiscoverySetResponse>),
}

/// A request for another peer's latest validator set and a validator change proof
/// to get the client up-to-date if they're behind.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct QueryDiscoverySetRequest {
    pub known_version: u64,
    // TODO(philiphayes): split sets into separate V and VFN sets. add enum to
    // select by discovery set type.
}

/// A response to a [`QueryDiscoverySetRequest`]. The server will include an
/// epoch change proof if the client is behind.
///
/// The validator set only changes when there is a new epoch. To minimize
/// wire overhead, the server will include the validator set account's
/// [`AccountStateWithProof`] _if and only if_ the server also presents a
/// non-empty epoch change proof.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct QueryDiscoverySetResponse {
    pub latest_li: LedgerInfoWithSignatures,
    pub epoch_change_proof: EpochChangeProof,
    pub accumulator_proof: AccumulatorConsistencyProof,
    pub account_state: Option<AccountStateWithProof>,
}

impl QueryDiscoverySetResponse {
    /// Verify and ratchet the given trusted state, returning the verified trusted
    /// state change and latest validator set (if present).
    ///
    /// 1. Verify and ratchet trusted state using epoch changes and latest ledger info
    /// 2. (If present) Verify validator set account state proof
    /// 3. (If present) Deserialize `ValidatorSet` from validator set resource in account blob
    pub fn verify_and_ratchet<'a>(
        &'a self,
        req_msg: &QueryDiscoverySetRequest,
        trusted_state: &'a TrustedState,
    ) -> Result<(TrustedStateChange<'a>, Option<ValidatorSet>)> {
        // TODO(philiphayes): how to deal with partial epoch change proofs?
        // should probably not return discovery set until at head?

        let has_epoch_change = !self.epoch_change_proof.ledger_info_with_sigs.is_empty();
        let has_validator_set = self.account_state.is_some();

        // enforce property: epoch change <==> some validator set in response
        ensure!(
            has_epoch_change == has_validator_set,
            "mismatch between epoch change and validator set. \
             has_epoch_change iff has_validator_set: \
             has_epoch_change: {}, has_validator_set: {}",
            has_epoch_change,
            has_validator_set,
        );

        // check response is not stale
        let ledger_version = self.latest_li.ledger_info().version();
        ensure!(
            ledger_version >= req_msg.known_version,
            "received stale ledger_info: ledger_version: {}, request known_version: {}",
            ledger_version,
            req_msg.known_version,
        );

        // try to ratchet trusted state
        let trusted_state_change = trusted_state
            .verify_and_ratchet(&self.latest_li, &self.epoch_change_proof)
            .context("failed to ratchet trusted_state")?;

        // if the response contains the validator set account, then verify
        // account_state_proof and pull out the validator set
        let opt_validator_set = self
            .account_state
            .as_ref()
            .map(|account_state| -> Result<ValidatorSet> {
                account_state
                    .verify(
                        self.latest_li.ledger_info(),
                        ledger_version,
                        account_config::validator_set_address(),
                    )
                    .context("failed to verify account state proof for validator set resource")?;

                let blob = account_state
                    .blob
                    .as_ref()
                    .ok_or_else(|| format_err!("validator set account blob cannot be missing"))?;

                let validator_set = AccountState::try_from(blob)?
                    .get_validator_set()?
                    .ok_or_else(|| format_err!("validator set resource cannot be missing"))?;
                Ok(validator_set)
            })
            .transpose()?;

        // TODO(philiphayes): do something with accumulator_proof?
        // self.query_res.accumulator_proof.

        Ok((trusted_state_change, opt_validator_set))
    }
}

/// An internal representation of the DiscoverySet.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DiscoverySetInternal(pub HashMap<PeerId, DiscoveryInfoInternal>);

impl DiscoverySetInternal {
    pub fn from_validator_set(role_filter: RoleType, validator_set: ValidatorSet) -> Self {
        Self(
            validator_set
                .into_iter()
                .filter_map(|validator_info| {
                    let peer_id = *validator_info.account_address();
                    let res_info =
                        DiscoveryInfoInternal::try_from_validator_info(role_filter, validator_info);

                    // ignore network addresses that fail to deserialize
                    res_info
                        .map_err(|err| {
                            debug!(
                                "failed to deserialize addresses from validator: {}, err: {}",
                                peer_id.short_str(),
                                err
                            )
                        })
                        .map(|info| (peer_id, info))
                        .ok()
                })
                .collect::<HashMap<_, _>>(),
        )
    }

    pub fn empty() -> Self {
        Self(HashMap::new())
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DiscoveryInfoInternal(pub x25519::PublicKey, pub Vec<NetworkAddress>);

impl DiscoveryInfoInternal {
    pub fn try_from_validator_info(
        role_filter: RoleType,
        validator_info: ValidatorInfo,
    ) -> Result<Self> {
        let info = match role_filter {
            RoleType::Validator => Self(
                validator_info
                    .config()
                    .validator_network_identity_public_key,
                vec![NetworkAddress::try_from(
                    &validator_info.config().validator_network_address,
                )?],
            ),
            RoleType::FullNode => Self(
                validator_info
                    .config()
                    .full_node_network_identity_public_key,
                vec![NetworkAddress::try_from(
                    &validator_info.config().full_node_network_address,
                )?],
            ),
        };
        Ok(info)
    }
}
<commit_msg>Removing is_empty from network/onchain-discovery/src/types.rs<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use anyhow::{ensure, format_err, Context as _, Result};
use libra_config::config::RoleType;
use libra_crypto::x25519;
use libra_logger::prelude::*;
use libra_network_address::NetworkAddress;
use libra_types::{
    account_config,
    account_state::AccountState,
    account_state_blob::AccountStateWithProof,
    epoch_change::EpochChangeProof,
    ledger_info::LedgerInfoWithSignatures,
    on_chain_config::ValidatorSet,
    proof::AccumulatorConsistencyProof,
    trusted_state::{TrustedState, TrustedStateChange},
    validator_info::ValidatorInfo,
    PeerId,
};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, convert::TryFrom};

/// OnchainDiscovery LibraNet message types. These are sent over-the-wire.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OnchainDiscoveryMsg {
    QueryDiscoverySetRequest(QueryDiscoverySetRequest),
    QueryDiscoverySetResponse(Box<QueryDiscoverySetResponse>),
}

/// A request for another peer's latest validator set and a validator change proof
/// to get the client up-to-date if they're behind.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct QueryDiscoverySetRequest {
    pub known_version: u64,
    // TODO(philiphayes): split sets into separate V and VFN sets. add enum to
    // select by discovery set type.
}

/// A response to a [`QueryDiscoverySetRequest`]. The server will include an
/// epoch change proof if the client is behind.
///
/// The validator set only changes when there is a new epoch. To minimize
/// wire overhead, the server will include the validator set account's
/// [`AccountStateWithProof`] _if and only if_ the server also presents a
/// non-empty epoch change proof.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct QueryDiscoverySetResponse {
    pub latest_li: LedgerInfoWithSignatures,
    pub epoch_change_proof: EpochChangeProof,
    pub accumulator_proof: AccumulatorConsistencyProof,
    pub account_state: Option<AccountStateWithProof>,
}

impl QueryDiscoverySetResponse {
    /// Verify and ratchet the given trusted state, returning the verified trusted
    /// state change and latest validator set (if present).
    ///
    /// 1. Verify and ratchet trusted state using epoch changes and latest ledger info
    /// 2. (If present) Verify validator set account state proof
    /// 3. (If present) Deserialize `ValidatorSet` from validator set resource in account blob
    pub fn verify_and_ratchet<'a>(
        &'a self,
        req_msg: &QueryDiscoverySetRequest,
        trusted_state: &'a TrustedState,
    ) -> Result<(TrustedStateChange<'a>, Option<ValidatorSet>)> {
        // TODO(philiphayes): how to deal with partial epoch change proofs?
        // should probably not return discovery set until at head?

        let has_epoch_change = !self.epoch_change_proof.ledger_info_with_sigs.is_empty();
        let has_validator_set = self.account_state.is_some();

        // enforce property: epoch change <==> some validator set in response
        ensure!(
            has_epoch_change == has_validator_set,
            "mismatch between epoch change and validator set. \
             has_epoch_change iff has_validator_set: \
             has_epoch_change: {}, has_validator_set: {}",
            has_epoch_change,
            has_validator_set,
        );

        // check response is not stale
        let ledger_version = self.latest_li.ledger_info().version();
        ensure!(
            ledger_version >= req_msg.known_version,
            "received stale ledger_info: ledger_version: {}, request known_version: {}",
            ledger_version,
            req_msg.known_version,
        );

        // try to ratchet trusted state
        let trusted_state_change = trusted_state
            .verify_and_ratchet(&self.latest_li, &self.epoch_change_proof)
            .context("failed to ratchet trusted_state")?;

        // if the response contains the validator set account, then verify
        // account_state_proof and pull out the validator set
        let opt_validator_set = self
            .account_state
            .as_ref()
            .map(|account_state| -> Result<ValidatorSet> {
                account_state
                    .verify(
                        self.latest_li.ledger_info(),
                        ledger_version,
                        account_config::validator_set_address(),
                    )
                    .context("failed to verify account state proof for validator set resource")?;

                let blob = account_state
                    .blob
                    .as_ref()
                    .ok_or_else(|| format_err!("validator set account blob cannot be missing"))?;

                let validator_set = AccountState::try_from(blob)?
                    .get_validator_set()?
                    .ok_or_else(|| format_err!("validator set resource cannot be missing"))?;
                Ok(validator_set)
            })
            .transpose()?;

        // TODO(philiphayes): do something with accumulator_proof?
        // self.query_res.accumulator_proof.

        Ok((trusted_state_change, opt_validator_set))
    }
}

/// An internal representation of the DiscoverySet.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DiscoverySetInternal(pub HashMap<PeerId, DiscoveryInfoInternal>);

impl DiscoverySetInternal {
    pub fn from_validator_set(role_filter: RoleType, validator_set: ValidatorSet) -> Self {
        Self(
            validator_set
                .into_iter()
                .filter_map(|validator_info| {
                    let peer_id = *validator_info.account_address();
                    let res_info =
                        DiscoveryInfoInternal::try_from_validator_info(role_filter, validator_info);

                    // ignore network addresses that fail to deserialize
                    res_info
                        .map_err(|err| {
                            debug!(
                                "failed to deserialize addresses from validator: {}, err: {}",
                                peer_id.short_str(),
                                err
                            )
                        })
                        .map(|info| (peer_id, info))
                        .ok()
                })
                .collect::<HashMap<_, _>>(),
        )
    }

    pub fn empty() -> Self {
        Self(HashMap::new())
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DiscoveryInfoInternal(pub x25519::PublicKey, pub Vec<NetworkAddress>);

impl DiscoveryInfoInternal {
    pub fn try_from_validator_info(
        role_filter: RoleType,
        validator_info: ValidatorInfo,
    ) -> Result<Self> {
        let info = match role_filter {
            RoleType::Validator => Self(
                validator_info
                    .config()
                    .validator_network_identity_public_key,
                vec![NetworkAddress::try_from(
                    &validator_info.config().validator_network_address,
                )?],
            ),
            RoleType::FullNode => Self(
                validator_info
                    .config()
                    .full_node_network_identity_public_key,
                vec![NetworkAddress::try_from(
                    &validator_info.config().full_node_network_address,
                )?],
            ),
        };
        Ok(info)
    }
}
<|endoftext|>