<commit_before>#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

#![allow(unstable)]

extern crate "rustc-serialize" as rustc_serialize;

use std::io::{Buffer, MemWriter};
use rustc_serialize::{Encodable, Decodable};

pub use writer::{EncoderWriter, EncodingResult, EncodingError};
pub use reader::{DecoderReader, DecodingResult, DecodingError};
use writer::SizeChecker;

mod writer;
mod reader;
#[cfg(test)] mod test;

///! `bincode` is a crate for encoding and decoding using a tiny binary
///! serialization strategy.
///!
///! There are simple functions for encoding to `Vec<u8>` and decoding from
///! `&[u8]`, but the meat of the library is the `encode_into` and `decode_from`
///! functions which respectively allow encoding into a `std::io::Writer`
///! and decoding from a `std::io::Buffer`.
///!
///! ### Using Basic Functions
///!
///! ```rust
///! extern crate bincode;
///! fn main() {
///!     // The object that we will serialize.
///!     let target = Some("hello world".to_string());
///!     // The maximum size of the encoded message.
///!     let limit = bincode::SizeLimit::Bounded(20);
///!
///!     let encoded: Vec<u8>        = bincode::encode(&target, limit).unwrap();
///!     let decoded: Option<String> = bincode::decode(&encoded[]).unwrap();
///!     assert_eq!(target, decoded);
///! }
///! ```
///!
///! ### Using Into/From Functions
///!
///! ```rust
///! extern crate bincode;
///! use std::io::pipe::PipeStream;
///! use std::io::BufferedReader;
///! fn main() {
///!     // The pipes that we will be using to send values across.
///!     let streams = PipeStream::pair().unwrap();
///!     let (mut reader, mut writer) = (BufferedReader::new(streams.reader),
///!                                     streams.writer);
///!     // The object that we will send across.
///!     let target = Some(5u32);
///!     // The max-size of the encoded bytes.
///!     let limit = bincode::SizeLimit::Bounded(10);
///!
///!     // Do the actual encoding and decoding.
///!     bincode::encode_into(&target, &mut writer, limit);
///!     let out: Option<u32> = bincode::decode_from(&mut reader, limit).unwrap();
///!     assert_eq!(target, out);
///! }
///! ```
///!

/// A limit on the size of bytes to be read or written.
///
/// Size limits are an incredibly important part of both encoding and decoding.
///
/// In order to prevent DOS attacks on a decoder, it is important to limit the
/// amount of bytes that a single encoded message can be; otherwise, if you
/// are decoding bytes right off of a TCP stream for example, it would be
/// possible for an attacker to flood your server with a 3TB vec, causing the
/// decoder to run out of memory and crash your application!
/// Because of this, you can provide a maximum-number-of-bytes that can be read
/// during decoding, and the decoder will explicitly fail if it has to read
/// any more than that.
///
/// On the other side, you want to make sure that you aren't encoding a message
/// that is larger than your decoder expects.  By supplying a size limit to an
/// encoding function, the encoder will verify that the structure can be encoded
/// within that limit.  This verification occurs before any bytes are written to
/// the Writer, so recovering from an the error is possible.
#[derive(Clone, Copy, Show, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum SizeLimit {
    Infinite,
    Bounded(u64)
}

/// Encodes an encodable object into a `Vec` of bytes.
///
/// If the encoding would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn encode<T: Encodable>(t: &T, size_limit: SizeLimit) -> EncodingResult<Vec<u8>> {
    let mut w = MemWriter::new();
    match encode_into(t, &mut w, size_limit) {
        Ok(()) => Ok(w.into_inner()),
        Err(e) => Err(e)
    }
}

/// Decodes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn decode<T: Decodable>(b: &[u8]) -> DecodingResult<T> {
    let mut b = b;
    decode_from(&mut b, SizeLimit::Infinite)
}

/// Encodes an object directly into a `Writer`.
///
/// If the encoding would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `EncodingError` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// encoding.
pub fn encode_into<T: Encodable, W: Writer>(t: &T, w: &mut W, size_limit: SizeLimit) -> EncodingResult<()> {
    try!(match size_limit {
        SizeLimit::Infinite => Ok(()),
        SizeLimit::Bounded(x) => {
            let mut size_checker = SizeChecker::new(x);
            t.encode(&mut size_checker)
        }
    });

    t.encode(&mut writer::EncoderWriter::new(w, size_limit))
}

/// Decoes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the decode will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `DecodingError`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn decode_from<R: Buffer, T: Decodable>(r: &mut R, size_limit: SizeLimit) ->
DecodingResult<T> {
    Decodable::decode(&mut reader::DecoderReader::new(r, size_limit))
}

/// Returns the size that an object would be if encoded using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn encoded_size<T: Encodable>(t: &T) -> u64 {
    use std::u64::MAX;
    let mut size_checker = SizeChecker::new(MAX);
    t.encode(&mut size_checker).ok();
    size_checker.written
}
<commit_msg>Fix doc tests.<commit_after>#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

#![allow(unstable)]

extern crate "rustc-serialize" as rustc_serialize;

use std::io::{Buffer, MemWriter};
use rustc_serialize::{Encodable, Decodable};

pub use writer::{EncoderWriter, EncodingResult, EncodingError};
pub use reader::{DecoderReader, DecodingResult, DecodingError};
use writer::SizeChecker;

mod writer;
mod reader;
#[cfg(test)] mod test;

///! `bincode` is a crate for encoding and decoding using a tiny binary
///! serialization strategy.
///!
///! There are simple functions for encoding to `Vec<u8>` and decoding from
///! `&[u8]`, but the meat of the library is the `encode_into` and `decode_from`
///! functions which respectively allow encoding into a `std::io::Writer`
///! and decoding from a `std::io::Buffer`.
///!
///! ### Using Basic Functions
///!
///! ```rust
///! #![allow(unstable)]
///! extern crate bincode;
///! fn main() {
///!     // The object that we will serialize.
///!     let target = Some("hello world".to_string());
///!     // The maximum size of the encoded message.
///!     let limit = bincode::SizeLimit::Bounded(20);
///!
///!     let encoded: Vec<u8>        = bincode::encode(&target, limit).unwrap();
///!     let decoded: Option<String> = bincode::decode(&encoded[]).unwrap();
///!     assert_eq!(target, decoded);
///! }
///! ```
///!
///! ### Using Into/From Functions
///!
///! ```rust
///! #![allow(unstable)]
///! extern crate bincode;
///! use std::io::pipe::PipeStream;
///! use std::io::BufferedReader;
///! fn main() {
///!     // The pipes that we will be using to send values across.
///!     let streams = PipeStream::pair().unwrap();
///!     let (mut reader, mut writer) = (BufferedReader::new(streams.reader),
///!                                     streams.writer);
///!     // The object that we will send across.
///!     let target = Some(5u32);
///!     // The max-size of the encoded bytes.
///!     let limit = bincode::SizeLimit::Bounded(10);
///!
///!     // Do the actual encoding and decoding.
///!     bincode::encode_into(&target, &mut writer, limit).ok();
///!     let out: Option<u32> = bincode::decode_from(&mut reader, limit).unwrap();
///!     assert_eq!(target, out);
///! }
///! ```
///!

/// A limit on the size of bytes to be read or written.
///
/// Size limits are an incredibly important part of both encoding and decoding.
///
/// In order to prevent DOS attacks on a decoder, it is important to limit the
/// amount of bytes that a single encoded message can be; otherwise, if you
/// are decoding bytes right off of a TCP stream for example, it would be
/// possible for an attacker to flood your server with a 3TB vec, causing the
/// decoder to run out of memory and crash your application!
/// Because of this, you can provide a maximum-number-of-bytes that can be read
/// during decoding, and the decoder will explicitly fail if it has to read
/// any more than that.
///
/// On the other side, you want to make sure that you aren't encoding a message
/// that is larger than your decoder expects.  By supplying a size limit to an
/// encoding function, the encoder will verify that the structure can be encoded
/// within that limit.  This verification occurs before any bytes are written to
/// the Writer, so recovering from an the error is possible.
#[derive(Clone, Copy, Show, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum SizeLimit {
    Infinite,
    Bounded(u64)
}

/// Encodes an encodable object into a `Vec` of bytes.
///
/// If the encoding would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn encode<T: Encodable>(t: &T, size_limit: SizeLimit) -> EncodingResult<Vec<u8>> {
    let mut w = MemWriter::new();
    match encode_into(t, &mut w, size_limit) {
        Ok(()) => Ok(w.into_inner()),
        Err(e) => Err(e)
    }
}

/// Decodes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn decode<T: Decodable>(b: &[u8]) -> DecodingResult<T> {
    let mut b = b;
    decode_from(&mut b, SizeLimit::Infinite)
}

/// Encodes an object directly into a `Writer`.
///
/// If the encoding would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `EncodingError` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// encoding.
pub fn encode_into<T: Encodable, W: Writer>(t: &T, w: &mut W, size_limit: SizeLimit) -> EncodingResult<()> {
    try!(match size_limit {
        SizeLimit::Infinite => Ok(()),
        SizeLimit::Bounded(x) => {
            let mut size_checker = SizeChecker::new(x);
            t.encode(&mut size_checker)
        }
    });

    t.encode(&mut writer::EncoderWriter::new(w, size_limit))
}

/// Decoes an object directly from a `Buffer`ed Reader.
///
/// If the provided `SizeLimit` is reached, the decode will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `DecodingError`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn decode_from<R: Buffer, T: Decodable>(r: &mut R, size_limit: SizeLimit) ->
DecodingResult<T> {
    Decodable::decode(&mut reader::DecoderReader::new(r, size_limit))
}

/// Returns the size that an object would be if encoded using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn encoded_size<T: Encodable>(t: &T) -> u64 {
    use std::u64::MAX;
    let mut size_checker = SizeChecker::new(MAX);
    t.encode(&mut size_checker).ok();
    size_checker.written
}
<|endoftext|>


<commit_before>//! The `neon` crate provides the entire [Neon](https://www.neon-bindings.com/) API.

extern crate neon_runtime;
extern crate cslice;

pub mod mem;
pub mod vm;
pub mod scope;
pub mod js;
pub mod task;

#[doc(hidden)]
pub mod macro_internal;

/// Register the current crate as a Node module, providing startup
/// logic for initializing the module object at runtime.
///
/// Example:
///
/// ```rust,ignore
/// register_module!(m, {
///     try!(m.export("foo", foo));
///     try!(m.export("bar", bar));
///     try!(m.export("baz", baz));
///     Ok(())
/// });
/// ```
#[macro_export]
macro_rules! register_module {
    ($module:ident, $init:block) => {
        // Mark this function as a global constructor (like C++).
        #[allow(improper_ctypes)]
        #[cfg_attr(target_os = "linux", link_section = ".ctors")]
        #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
        #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
        pub static __LOAD_NEON_MODULE: extern "C" fn() = {
            fn __init_neon_module(mut $module: $crate::vm::Module) -> $crate::vm::VmResult<()> $init

            extern "C" fn __load_neon_module() {
                // Put everything else in the ctor fn so the user fn can't see it.
                #[repr(C)]
                struct __NodeModule {
                    version: i32,
                    flags: u32,
                    dso_handle: *mut u8,
                    filename: *const u8,
                    register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8)>,
                    context_register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8, *mut u8)>,
                    modname: *const u8,
                    priv_data: *mut u8,
                    link: *mut __NodeModule
                }

                static mut __NODE_MODULE: __NodeModule = __NodeModule {
                    version: 0,
                    flags: 0,
                    dso_handle: 0 as *mut _,
                    filename: b"neon_source.rs\0" as *const u8,
                    register_func: Some(__register_neon_module),
                    context_register_func: None,
                    modname: b"neon_module\0" as *const u8,
                    priv_data: 0 as *mut _,
                    link: 0 as *mut _
                };

                extern "C" fn __register_neon_module(
                        m: $crate::mem::Handle<$crate::js::JsObject>, _: *mut u8, _: *mut u8) {
                    $crate::vm::Module::initialize(m, __init_neon_module);
                }

                extern "C" {
                    fn node_module_register(module: *mut __NodeModule);
                }

                // Suppress the default Rust panic hook, which prints diagnostics to stderr.
                ::std::panic::set_hook(::std::boxed::Box::new(|_| { }));

                unsafe {
                    // Set the ABI version based on the NODE_MODULE_VERSION constant provided by the current node headers.
                    __NODE_MODULE.version = $crate::macro_internal::runtime::module::get_version();
                    node_module_register(&mut __NODE_MODULE);
                }
            }

            __load_neon_module
        };
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! class_definition {
    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; init($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          {
                              fn _______allocator_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$crate::js::JsUndefined>) -> $crate::vm::VmResult<$typ> {
                                  $body
                              }

                              $crate::macro_internal::AllocateKernel::new(_______allocator_rust_y_u_no_hygienic_items_______)
                          } ;
                          $call_ctor ;
                          $new_ctor ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; ($($mname:tt)*) ; ($($mdef:tt)*) ; method $name:ident($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          $call_ctor ;
                          $new_ctor ;
                          ($($mname)* $name) ;
                          ($($mdef)* {
                              fn _______method_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$cls>) -> $crate::vm::JsResult<$crate::js::JsValue> {
                                  $body
                              }

                              $crate::macro_internal::MethodKernel::new(_______method_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; constructor($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          $call_ctor ;
                          ({
                              fn _______constructor_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$cls>) -> $crate::vm::VmResult<Option<$crate::mem::Handle<$crate::js::JsObject>>> {
                                  $body
                              }

                              $crate::macro_internal::ConstructKernel::new(_______constructor_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; call($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          ({
                              fn _______call_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$crate::js::JsValue>) -> $crate::vm::JsResult<$crate::js::JsValue> {
                                  $body
                              }

                              $crate::macro_internal::ConstructorCallKernel::new(_______call_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $new_ctor ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:block ; ($($call_ctor:block)*) ; ($($new_ctor:block)*) ; ($($mname:ident)*) ; ($($mdef:block)*) ; $($rest:tt)* ) => {
        impl $crate::js::class::Class for $cls {
            type Internals = $typ;

            fn setup<'a, T: $crate::scope::Scope<'a>>(_: &mut T) -> $crate::vm::VmResult<$crate::js::class::ClassDescriptor<'a, Self>> {
                ::std::result::Result::Ok(Self::describe(stringify!($cname), $allocator)
                                             $(.construct($new_ctor))*
                                             $(.call($call_ctor))*
                                             $(.method(stringify!($mname), $mdef))*)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_managed {
    ($cls:ident) => {
        impl $crate::mem::Managed for $cls {
            fn to_raw(self) -> $crate::macro_internal::runtime::raw::Local {
                let $cls(raw) = self;
                raw
            }

            fn from_raw(raw: $crate::macro_internal::runtime::raw::Local) -> Self {
                $cls(raw)
            }
        }
    }
}

/// Declare custom native JavaScript types with Rust implementations.
///
/// Example:
///
/// ```rust,ignore
/// pub struct Greeter {
///     greeting: String
/// }
///
/// declare_types! {
///
///     /// A class for generating greeting strings.
///     pub class JsGreeter for Greeter {
///         init(call) {
///             let scope = call.scope;
///             let greeting = try!(try!(call.arguments.require(scope, 0)).to_string(scope)).value();
///             Ok(Greeter {
///                 greeting: greeting
///             })
///         }
///
///         method hello(call) {
///             let scope = call.scope;
///             let name = try!(try!(call.arguments.require(scope, 0)).to_string(scope)).value();
///             let msg = vm::lock(call.arguments.this(scope), |greeter| {
///                 format!("{}, {}!", greeter.greeting, name)
///             });
///             Ok(try!(JsString::new_or_throw(scope, &msg[..])).upcast())
///         }
///     }
///
/// }
/// ```
#[macro_export]
macro_rules! declare_types {
    { $(#[$attr:meta])* pub class $cls:ident for $typ:ident { $($body:tt)* } $($rest:tt)* } => {
        declare_types! { $(#[$attr])* pub class $cls as $typ for $typ { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident for $typ:ident { $($body:tt)* } $($rest:tt)* } => {
        declare_types! { $(#[$attr])* class $cls as $typ for $typ { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* pub class $cls:ident as $cname:ident for $typ:ty { $($body:tt)* } $($rest:tt)* } => {
        #[derive(Copy, Clone)]
        #[repr(C)]
        $(#[$attr])*
        pub struct $cls($crate::macro_internal::runtime::raw::Local);

        impl_managed!($cls);

        class_definition!($cls ; $cname ; $typ ; () ; () ; () ; () ; () ; $($body)*);

        declare_types! { $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident as $cname:ident for $typ:ty { $($body:tt)* } $($rest:tt)* } => {
        #[derive(Copy, Clone)]
        #[repr(C)]
        $(#[$attr])*
        struct $cls($crate::macro_internal::runtime::raw::Local);

        impl_managed!($cls);

        class_definition!($cls ; $cname ; $typ ; () ; () ; () ; () ; () ; $($body)*);

        declare_types! { $($rest)* }
    };

    { } => { };
}
<commit_msg>Fix declare_types! doc string for grab closes #170<commit_after>//! The `neon` crate provides the entire [Neon](https://www.neon-bindings.com/) API.

extern crate neon_runtime;
extern crate cslice;

pub mod mem;
pub mod vm;
pub mod scope;
pub mod js;
pub mod task;

#[doc(hidden)]
pub mod macro_internal;

/// Register the current crate as a Node module, providing startup
/// logic for initializing the module object at runtime.
///
/// Example:
///
/// ```rust,ignore
/// register_module!(m, {
///     try!(m.export("foo", foo));
///     try!(m.export("bar", bar));
///     try!(m.export("baz", baz));
///     Ok(())
/// });
/// ```
#[macro_export]
macro_rules! register_module {
    ($module:ident, $init:block) => {
        // Mark this function as a global constructor (like C++).
        #[allow(improper_ctypes)]
        #[cfg_attr(target_os = "linux", link_section = ".ctors")]
        #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
        #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
        pub static __LOAD_NEON_MODULE: extern "C" fn() = {
            fn __init_neon_module(mut $module: $crate::vm::Module) -> $crate::vm::VmResult<()> $init

            extern "C" fn __load_neon_module() {
                // Put everything else in the ctor fn so the user fn can't see it.
                #[repr(C)]
                struct __NodeModule {
                    version: i32,
                    flags: u32,
                    dso_handle: *mut u8,
                    filename: *const u8,
                    register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8)>,
                    context_register_func: Option<extern "C" fn(
                        $crate::mem::Handle<$crate::js::JsObject>, *mut u8, *mut u8, *mut u8)>,
                    modname: *const u8,
                    priv_data: *mut u8,
                    link: *mut __NodeModule
                }

                static mut __NODE_MODULE: __NodeModule = __NodeModule {
                    version: 0,
                    flags: 0,
                    dso_handle: 0 as *mut _,
                    filename: b"neon_source.rs\0" as *const u8,
                    register_func: Some(__register_neon_module),
                    context_register_func: None,
                    modname: b"neon_module\0" as *const u8,
                    priv_data: 0 as *mut _,
                    link: 0 as *mut _
                };

                extern "C" fn __register_neon_module(
                        m: $crate::mem::Handle<$crate::js::JsObject>, _: *mut u8, _: *mut u8) {
                    $crate::vm::Module::initialize(m, __init_neon_module);
                }

                extern "C" {
                    fn node_module_register(module: *mut __NodeModule);
                }

                // Suppress the default Rust panic hook, which prints diagnostics to stderr.
                ::std::panic::set_hook(::std::boxed::Box::new(|_| { }));

                unsafe {
                    // Set the ABI version based on the NODE_MODULE_VERSION constant provided by the current node headers.
                    __NODE_MODULE.version = $crate::macro_internal::runtime::module::get_version();
                    node_module_register(&mut __NODE_MODULE);
                }
            }

            __load_neon_module
        };
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! class_definition {
    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; init($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          {
                              fn _______allocator_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$crate::js::JsUndefined>) -> $crate::vm::VmResult<$typ> {
                                  $body
                              }

                              $crate::macro_internal::AllocateKernel::new(_______allocator_rust_y_u_no_hygienic_items_______)
                          } ;
                          $call_ctor ;
                          $new_ctor ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; ($($mname:tt)*) ; ($($mdef:tt)*) ; method $name:ident($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          $call_ctor ;
                          $new_ctor ;
                          ($($mname)* $name) ;
                          ($($mdef)* {
                              fn _______method_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$cls>) -> $crate::vm::JsResult<$crate::js::JsValue> {
                                  $body
                              }

                              $crate::macro_internal::MethodKernel::new(_______method_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; constructor($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          $call_ctor ;
                          ({
                              fn _______constructor_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$cls>) -> $crate::vm::VmResult<Option<$crate::mem::Handle<$crate::js::JsObject>>> {
                                  $body
                              }

                              $crate::macro_internal::ConstructKernel::new(_______constructor_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:tt ; $call_ctor:tt ; $new_ctor:tt ; $mnames:tt ; $mdefs:tt ; call($call:pat) $body:block $($rest:tt)* ) => {
        class_definition!($cls ;
                          $cname ;
                          $typ ;
                          $allocator ;
                          ({
                              fn _______call_rust_y_u_no_hygienic_items_______($call: $crate::vm::FunctionCall<$crate::js::JsValue>) -> $crate::vm::JsResult<$crate::js::JsValue> {
                                  $body
                              }

                              $crate::macro_internal::ConstructorCallKernel::new(_______call_rust_y_u_no_hygienic_items_______)
                          }) ;
                          $new_ctor ;
                          $mnames ;
                          $mdefs ;
                          $($rest)*);
    };

    ( $cls:ident ; $cname:ident ; $typ:ty ; $allocator:block ; ($($call_ctor:block)*) ; ($($new_ctor:block)*) ; ($($mname:ident)*) ; ($($mdef:block)*) ; $($rest:tt)* ) => {
        impl $crate::js::class::Class for $cls {
            type Internals = $typ;

            fn setup<'a, T: $crate::scope::Scope<'a>>(_: &mut T) -> $crate::vm::VmResult<$crate::js::class::ClassDescriptor<'a, Self>> {
                ::std::result::Result::Ok(Self::describe(stringify!($cname), $allocator)
                                             $(.construct($new_ctor))*
                                             $(.call($call_ctor))*
                                             $(.method(stringify!($mname), $mdef))*)
            }
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_managed {
    ($cls:ident) => {
        impl $crate::mem::Managed for $cls {
            fn to_raw(self) -> $crate::macro_internal::runtime::raw::Local {
                let $cls(raw) = self;
                raw
            }

            fn from_raw(raw: $crate::macro_internal::runtime::raw::Local) -> Self {
                $cls(raw)
            }
        }
    }
}

/// Declare custom native JavaScript types with Rust implementations.
///
/// Example:
///
/// ```rust,ignore
/// pub struct Greeter {
///     greeting: String
/// }
///
/// declare_types! {
///
///     /// A class for generating greeting strings.
///     pub class JsGreeter for Greeter {
///         init(call) {
///             let scope = call.scope;
///             let greeting = try!(try!(call.arguments.require(scope, 0)).to_string(scope)).value();
///             Ok(Greeter {
///                 greeting: greeting
///             })
///         }
///
///         method hello(call) {
///             let scope = call.scope;
///             let name = try!(try!(call.arguments.require(scope, 0)).to_string(scope)).value();
///             let msg = call.arguments.this(call.scope).grab(|x| {
///                 format!("{}, {}!", greeter.greeting, name)
///             });
///             Ok(try!(JsString::new_or_throw(scope, &msg[..])).upcast())
///         }
///     }
///
/// }
/// ```
#[macro_export]
macro_rules! declare_types {
    { $(#[$attr:meta])* pub class $cls:ident for $typ:ident { $($body:tt)* } $($rest:tt)* } => {
        declare_types! { $(#[$attr])* pub class $cls as $typ for $typ { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident for $typ:ident { $($body:tt)* } $($rest:tt)* } => {
        declare_types! { $(#[$attr])* class $cls as $typ for $typ { $($body)* } $($rest)* }
    };

    { $(#[$attr:meta])* pub class $cls:ident as $cname:ident for $typ:ty { $($body:tt)* } $($rest:tt)* } => {
        #[derive(Copy, Clone)]
        #[repr(C)]
        $(#[$attr])*
        pub struct $cls($crate::macro_internal::runtime::raw::Local);

        impl_managed!($cls);

        class_definition!($cls ; $cname ; $typ ; () ; () ; () ; () ; () ; $($body)*);

        declare_types! { $($rest)* }
    };

    { $(#[$attr:meta])* class $cls:ident as $cname:ident for $typ:ty { $($body:tt)* } $($rest:tt)* } => {
        #[derive(Copy, Clone)]
        #[repr(C)]
        $(#[$attr])*
        struct $cls($crate::macro_internal::runtime::raw::Local);

        impl_managed!($cls);

        class_definition!($cls ; $cname ; $typ ; () ; () ; () ; () ; () ; $($body)*);

        declare_types! { $($rest)* }
    };

    { } => { };
}
<|endoftext|>


<commit_before>//! # Sqlite support for the `r2d2` connection pool.
//!
//! Library crate: [r2d2-sqlite](https://crates.io/crates/r2d2-sqlite/)
//!
//! Integrated with: [r2d2](https://crates.io/crates/r2d2)
//! and [rusqlite](https://crates.io/crates/rusqlite)
//!
//! ## Example
//!
//! ```rust,no_run
//! extern crate r2d2;
//! extern crate r2d2_sqlite;
//! extern crate rusqlite;
//!
//! use std::thread;
//! use r2d2_sqlite::SqliteConnectionManager;
//!
//! fn main() {
//!     let config = r2d2::Config::default();
//!     let manager = SqliteConnectionManager::new("file.db");
//!     let pool = r2d2::Pool::new(config, manager).unwrap();
//!
//!     for i in 0..10i32 {
//!         let pool = pool.clone();
//!         thread::spawn(move || {
//!             let conn = pool.get().unwrap();
//!             conn.execute("INSERT INTO foo (bar) VALUES (?)", &[&i]).unwrap();
//!         });
//!     }
//! }
//! ```
extern crate r2d2;
extern crate rusqlite;

use std::error::{self, Error as StdError};
use std::fmt;
use std::convert;

use rusqlite::{Connection, Error as RusqliteError, OpenFlags};

/// A unified enum of errors returned by `rusqlite::Connection`
#[derive(Debug)]
pub enum Error {
    Connect(RusqliteError),
}

impl convert::From<RusqliteError> for Error {
    fn from(e: RusqliteError) -> Error {
        Error::Connect(e)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}: {}", self.description(), self.cause().unwrap())
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Connect(_) => "Error opening a connection",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Connect(ref err) => Some(err as &error::Error),
        }
    }
}

enum ConnectionConfig {
    File(String, OpenFlags),
}

/// An `r2d2::ManageConnection` for `rusqlite::Connection`s.
pub struct SqliteConnectionManager {
    config: ConnectionConfig,
}

impl SqliteConnectionManager {
    /// Creates a new `SqliteConnectionManager` from file.
    ///
    /// See `rusqlite::Connection::open`
    pub fn new(database: &str) -> Self {
        Self::new_with_flags(database, OpenFlags::default())
    }

    /// Creates a new `SqliteConnectionManager` from file with open flags.
    ///
    /// See `rusqlite::Connection::open_with_flags`
    pub fn new_with_flags(database: &str, flags: OpenFlags) -> Self {
        SqliteConnectionManager { config: ConnectionConfig::File(database.to_string(), flags) }
    }
}

impl r2d2::ManageConnection for SqliteConnectionManager {
    type Connection = Connection;
    type Error = Error;

    fn connect(&self) -> Result<Connection, Error> {
        match self.config {
                ConnectionConfig::File(ref path, flags) => Connection::open_with_flags(path, flags),
            }
            .map_err(Into::into)
    }

    fn is_valid(&self, conn: &mut Connection) -> Result<(), Error> {
        conn.execute_batch("").map_err(Into::into)
    }

    fn has_broken(&self, _: &mut Connection) -> bool {
        false
    }
}
<commit_msg>Just use Rusqlite Error, instead of wrapping it https://github.com/ivanceras/r2d2-sqlite/issues/9<commit_after>#![deny(warnings)]
//! # Sqlite support for the `r2d2` connection pool.
//!
//! Library crate: [r2d2-sqlite](https://crates.io/crates/r2d2-sqlite/)
//!
//! Integrated with: [r2d2](https://crates.io/crates/r2d2)
//! and [rusqlite](https://crates.io/crates/rusqlite)
//!
//! ## Example
//!
//! ```rust,no_run
//! extern crate r2d2;
//! extern crate r2d2_sqlite;
//! extern crate rusqlite;
//!
//! use std::thread;
//! use r2d2_sqlite::SqliteConnectionManager;
//!
//! fn main() {
//!     let config = r2d2::Config::default();
//!     let manager = SqliteConnectionManager::new("file.db");
//!     let pool = r2d2::Pool::new(config, manager).unwrap();
//!
//!     for i in 0..10i32 {
//!         let pool = pool.clone();
//!         thread::spawn(move || {
//!             let conn = pool.get().unwrap();
//!             conn.execute("INSERT INTO foo (bar) VALUES (?)", &[&i]).unwrap();
//!         });
//!     }
//! }
//! ```
extern crate r2d2;
extern crate rusqlite;

use rusqlite::{Connection, Error as RusqliteError, OpenFlags};

enum ConnectionConfig {
    File(String, OpenFlags),
}

/// An `r2d2::ManageConnection` for `rusqlite::Connection`s.
pub struct SqliteConnectionManager {
    config: ConnectionConfig,
}

impl SqliteConnectionManager {
    /// Creates a new `SqliteConnectionManager` from file.
    ///
    /// See `rusqlite::Connection::open`
    pub fn new(database: &str) -> Self {
        Self::new_with_flags(database, OpenFlags::default())
    }

    /// Creates a new `SqliteConnectionManager` from file with open flags.
    ///
    /// See `rusqlite::Connection::open_with_flags`
    pub fn new_with_flags(database: &str, flags: OpenFlags) -> Self {
        SqliteConnectionManager { config: ConnectionConfig::File(database.to_string(), flags) }
    }
}

impl r2d2::ManageConnection for SqliteConnectionManager {
    type Connection = Connection;
    type Error = RusqliteError;

    fn connect(&self) -> Result<Connection, RusqliteError> {
        match self.config {
                ConnectionConfig::File(ref path, flags) => Connection::open_with_flags(path, flags),
            }
            .map_err(Into::into)
    }

    fn is_valid(&self, conn: &mut Connection) -> Result<(), RusqliteError> {
        conn.execute_batch("").map_err(Into::into)
    }

    fn has_broken(&self, _: &mut Connection) -> bool {
        false
    }
}
<|endoftext|>


<commit_before>#![crate_name = "nickel"]
#![comment = "A expressjs inspired web framework for Rust"]
#![license = "MIT"]
#![crate_type = "rlib"]
#![feature(macro_rules, phase)]

//!Nickel is supposed to be a simple and lightweight foundation for web applications written in Rust. Its API is inspired by the popular express framework for JavaScript.
//!
//!Some of the features are:
//!
//!* Easy handlers: A handler is just a function that takes a `Request` and `ResponseWriter`
//!* Variables in routes. Just write `my/route/:someid`
//!* Easy parameter access: `request.params.get(&"someid")`
//!* simple wildcard routes: `/some/*/route`
//!* double wildcard routes: `/a/**/route`
//!* middleware

extern crate time;
extern crate http;
extern crate serialize;
extern crate regex;
extern crate anymap;
extern crate url;
extern crate mustache;
extern crate groupable;
#[phase(plugin)]
extern crate regex_macros;
#[phase(plugin, link)]
extern crate log;

pub use nickel::Nickel;
pub use request::Request;
pub use response::Response;
pub use middleware::{Action, Continue, Halt, Middleware, ErrorHandler, MiddlewareResult};
pub use static_files_handler::StaticFilesHandler;
pub use favicon_handler::FaviconHandler;
pub use default_error_handler::DefaultErrorHandler;
pub use json_body_parser::{JsonBodyParser, JsonBody};
pub use query_string::{QueryStringParser, QueryString};
pub use router::{Router, Route, RouteResult, RequestHandler, HttpRouter};
pub use nickel_error::{ NickelError, NickelErrorKind, ErrorWithStatusCode, UserDefinedError, Other };
pub use mimes::get_media_type;

mod router;
mod server;
mod nickel;
mod request;
mod response;
mod middleware;
mod favicon_handler;
mod static_files_handler;
mod json_body_parser;
mod mimes;
mod query_string;
mod urlencoded;
mod nickel_error;
mod default_error_handler;
<commit_msg>fix(slicing_syntax): allow slicing_syntax. fixes #95<commit_after>#![crate_name = "nickel"]
#![comment = "A expressjs inspired web framework for Rust"]
#![license = "MIT"]
#![crate_type = "rlib"]
#![feature(macro_rules, phase, slicing_syntax)]

//!Nickel is supposed to be a simple and lightweight foundation for web applications written in Rust. Its API is inspired by the popular express framework for JavaScript.
//!
//!Some of the features are:
//!
//!* Easy handlers: A handler is just a function that takes a `Request` and `ResponseWriter`
//!* Variables in routes. Just write `my/route/:someid`
//!* Easy parameter access: `request.params.get(&"someid")`
//!* simple wildcard routes: `/some/*/route`
//!* double wildcard routes: `/a/**/route`
//!* middleware

extern crate time;
extern crate http;
extern crate serialize;
extern crate regex;
extern crate anymap;
extern crate url;
extern crate mustache;
extern crate groupable;
#[phase(plugin)]
extern crate regex_macros;
#[phase(plugin, link)]
extern crate log;

pub use nickel::Nickel;
pub use request::Request;
pub use response::Response;
pub use middleware::{Action, Continue, Halt, Middleware, ErrorHandler, MiddlewareResult};
pub use static_files_handler::StaticFilesHandler;
pub use favicon_handler::FaviconHandler;
pub use default_error_handler::DefaultErrorHandler;
pub use json_body_parser::{JsonBodyParser, JsonBody};
pub use query_string::{QueryStringParser, QueryString};
pub use router::{Router, Route, RouteResult, RequestHandler, HttpRouter};
pub use nickel_error::{ NickelError, NickelErrorKind, ErrorWithStatusCode, UserDefinedError, Other };
pub use mimes::get_media_type;

mod router;
mod server;
mod nickel;
mod request;
mod response;
mod middleware;
mod favicon_handler;
mod static_files_handler;
mod json_body_parser;
mod mimes;
mod query_string;
mod urlencoded;
mod nickel_error;
mod default_error_handler;
<|endoftext|>


<commit_before>//! A minimal implementation of SHA1 for rust.
//!
//! Example:
//!
//! ```rust
//! extern crate sha1;
//! # fn main() {
//!
//! let mut m = sha1::Sha1::new();
//! m.update(b"Hello World!");
//! assert_eq!(m.digest().to_string(),
//!            "2ef7bde608ce5404e97d5f042f95f89f1c232871");
//! # }
//! ```

#![no_std]
#![deny(missing_docs)]

use core::cmp;
use core::fmt;

/// Represents a Sha1 hash object in memory.
#[derive(Clone)]
pub struct Sha1 {
    state: Sha1State,
    blocks: Blocks,
    len: u64,
}

struct Blocks {
    len: u32,
    block: [u8; 64],
}

#[derive(Copy, Clone)]
struct Sha1State {
    state: [u32; 5],
}

/// Digest generated from a `Sha1` instance.
///
/// A digest can be formatted to view the digest as a hex string, or the bytes
/// can be extracted for later processing.
pub struct Digest {
    data: Sha1State,
}

const DEFAULT_STATE: Sha1State =
    Sha1State { state: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] };

impl Sha1 {
    /// Creates an fresh sha1 hash object.
    pub fn new() -> Sha1 {
        Sha1 {
            state: DEFAULT_STATE,
            len: 0,
            blocks: Blocks {
                len: 0,
                block: [0; 64],
            },
        }
    }

    /// Resets the hash object to it's initial state.
    pub fn reset(&mut self) {
        self.state = DEFAULT_STATE;
        self.len = 0;
        self.blocks.len = 0;
    }

    /// Update hash with input data.
    pub fn update(&mut self, data: &[u8]) {
        let len = &mut self.len;
        let state = &mut self.state;
        self.blocks.input(data, |chunk| {
            *len += 64;
            state.process(chunk);
        })
    }

    /// Retrieve digest result.
    pub fn digest(&self) -> Digest {
        let mut state = self.state;
        let bits = (self.len + (self.blocks.len as u64)) * 8;
        let extra = [(bits >> 56) as u8,
                     (bits >> 48) as u8,
                     (bits >> 40) as u8,
                     (bits >> 32) as u8,
                     (bits >> 24) as u8,
                     (bits >> 16) as u8,
                     (bits >> 8) as u8,
                     (bits >> 0) as u8];
        let mut last = [0; 128];
        let blocklen = self.blocks.len as usize;
        last[..blocklen].clone_from_slice(&self.blocks.block[..blocklen]);
        last[blocklen] = 0x80;

        if blocklen < 56 {
            last[56..64].clone_from_slice(&extra);
            state.process(&last[0..64]);
        } else {
            last[120..128].clone_from_slice(&extra);
            state.process(&last[0..64]);
            state.process(&last[64..128]);
        }

        Digest { data: state }
    }
}

impl Digest {
    /// Returns the 160 bit (20 byte) digest as a byte array.
    pub fn bytes(&self) -> [u8; 20] {
        [(self.data.state[0] >> 24) as u8,
         (self.data.state[0] >> 16) as u8,
         (self.data.state[0] >> 8) as u8,
         (self.data.state[0] >> 0) as u8,
         (self.data.state[1] >> 24) as u8,
         (self.data.state[1] >> 16) as u8,
         (self.data.state[1] >> 8) as u8,
         (self.data.state[1] >> 0) as u8,
         (self.data.state[2] >> 24) as u8,
         (self.data.state[2] >> 16) as u8,
         (self.data.state[2] >> 8) as u8,
         (self.data.state[2] >> 0) as u8,
         (self.data.state[3] >> 24) as u8,
         (self.data.state[3] >> 16) as u8,
         (self.data.state[3] >> 8) as u8,
         (self.data.state[3] >> 0) as u8,
         (self.data.state[4] >> 24) as u8,
         (self.data.state[4] >> 16) as u8,
         (self.data.state[4] >> 8) as u8,
         (self.data.state[4] >> 0) as u8]
    }
}

impl Blocks {
    fn input<F>(&mut self, mut input: &[u8], mut f: F)
        where F: FnMut(&[u8])
    {
        if self.len > 0 {
            let len = self.len as usize;
            let amt = cmp::min(input.len(), self.block.len() - len);
            self.block[len..len + amt].clone_from_slice(&input[..amt]);
            if len + amt == self.block.len() {
                f(&self.block);
                self.len = 0;
                input = &input[amt..];
            } else {
                self.len += amt as u32;
                return;
            }
        }
        assert_eq!(self.len, 0);
        for chunk in input.chunks(64) {
            if chunk.len() == 64 {
                f(chunk)
            } else {
                self.block[..chunk.len()].clone_from_slice(chunk);
                self.len = chunk.len() as u32;
            }
        }
    }
}

impl Sha1State {
    fn process(&mut self, block: &[u8]) {
        let mut words = [0u32; 80];
        for (i, chunk) in block.chunks(4).enumerate() {
            words[i] = (chunk[3] as u32) | ((chunk[2] as u32) << 8) | ((chunk[1] as u32) << 16) |
                       ((chunk[0] as u32) << 24);
        }

        fn ff(b: u32, c: u32, d: u32) -> u32 {
            d ^ (b & (c ^ d))
        }
        fn gg(b: u32, c: u32, d: u32) -> u32 {
            b ^ c ^ d
        }
        fn hh(b: u32, c: u32, d: u32) -> u32 {
            (b & c) | (d & (b | c))
        }
        fn ii(b: u32, c: u32, d: u32) -> u32 {
            b ^ c ^ d
        }

        for i in 16..80 {
            let n = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
            words[i] = n.rotate_left(1);
        }

        let mut a = self.state[0];
        let mut b = self.state[1];
        let mut c = self.state[2];
        let mut d = self.state[3];
        let mut e = self.state[4];

        for i in 0..80 {
            let (f, k) = match i {
                0...19 => (ff(b, c, d), 0x5a827999),
                20...39 => (gg(b, c, d), 0x6ed9eba1),
                40...59 => (hh(b, c, d), 0x8f1bbcdc),
                60...79 => (ii(b, c, d), 0xca62c1d6),
                _ => (0, 0),
            };

            let tmp = a.rotate_left(5)
                .wrapping_add(f)
                .wrapping_add(e)
                .wrapping_add(k)
                .wrapping_add(words[i]);
            e = d;
            d = c;
            c = b.rotate_left(30);
            b = a;
            a = tmp;
        }

        self.state[0] = self.state[0].wrapping_add(a);
        self.state[1] = self.state[1].wrapping_add(b);
        self.state[2] = self.state[2].wrapping_add(c);
        self.state[3] = self.state[3].wrapping_add(d);
        self.state[4] = self.state[4].wrapping_add(e);
    }
}

impl Clone for Blocks {
    fn clone(&self) -> Blocks {
        Blocks { ..*self }
    }
}

impl fmt::Display for Digest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in self.data.state.iter() {
            try!(write!(f, "{:08x}", i));
        }
        Ok(())
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[cfg(test)]
mod tests {
    extern crate std;
    extern crate rand;
    extern crate openssl;

    use self::std::prelude::v1::*;
    use self::std::io::Write;

    use Sha1;

    #[test]
    fn test_simple() {
        let mut m = Sha1::new();

        let tests = [
            ("The quick brown fox jumps over the lazy dog",
             "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"),
            ("The quick brown fox jumps over the lazy cog",
             "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"),
            ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
            ("testing\n", "9801739daae44ec5293d4e1f53d3f4d2d426d91c"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "025ecbd5d70f8fb3c5457cd96bab13fda305dc59"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "4300320394f7ee239bcdce7d3b8bcee173a0cd5c"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "cef734ba81a024479e09eb5a75b6ddae62e6abf1"),
        ];

        for &(s, ref h) in tests.iter() {
            let data = s.as_bytes();

            m.reset();
            m.update(data);
            let hh = m.digest().to_string();

            assert_eq!(hh.len(), h.len());
            assert_eq!(hh, *h);
        }
    }

    #[test]
    fn test_multiple_updates() {
        let mut m = Sha1::new();

        m.reset();
        m.update("The quick brown ".as_bytes());
        m.update("fox jumps over ".as_bytes());
        m.update("the lazy dog".as_bytes());
        let hh = m.digest().to_string();

        let h = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12";
        assert_eq!(hh.len(), h.len());
        assert_eq!(hh, &*h);
    }

    #[test]
    fn test_sha1_loop() {
        let mut m = Sha1::new();
        let s = "The quick brown fox jumps over the lazy dog.";
        let n = 1000u64;

        for _ in 0..3 {
            m.reset();
            for _ in 0..n {
                m.update(s.as_bytes());
            }
            assert_eq!(m.digest().to_string(),
                       "7ca27655f67fceaa78ed2e645a81c7f1d6e249d2");
        }
    }

    #[test]
    fn spray_and_pray() {
        use self::rand::Rng;

        let mut rng = rand::thread_rng();
        let mut m = Sha1::new();
        let mut bytes = [0; 512];

        for _ in 0..20 {
            let ty = openssl::crypto::hash::Type::SHA1;
            let mut r = openssl::crypto::hash::Hasher::new(ty);
            m.reset();
            for _ in 0..50 {
                let len = rng.gen::<usize>() % bytes.len();
                rng.fill_bytes(&mut bytes[..len]);
                m.update(&bytes[..len]);
                r.write(&bytes[..len]).unwrap();
            }
            assert_eq!(r.finish(), m.digest().bytes());
        }
    }
}
<commit_msg>Small performance improvements. Refs #18<commit_after>//! A minimal implementation of SHA1 for rust.
//!
//! Example:
//!
//! ```rust
//! extern crate sha1;
//! # fn main() {
//!
//! let mut m = sha1::Sha1::new();
//! m.update(b"Hello World!");
//! assert_eq!(m.digest().to_string(),
//!            "2ef7bde608ce5404e97d5f042f95f89f1c232871");
//! # }
//! ```

#![no_std]
#![deny(missing_docs)]

use core::cmp;
use core::fmt;
use core::mem;

/// Represents a Sha1 hash object in memory.
#[derive(Clone)]
pub struct Sha1 {
    state: Sha1State,
    blocks: Blocks,
    len: u64,
}

struct Blocks {
    len: u32,
    block: [u8; 64],
}

#[derive(Copy, Clone)]
struct Sha1State {
    state: [u32; 5],
}

/// Digest generated from a `Sha1` instance.
///
/// A digest can be formatted to view the digest as a hex string, or the bytes
/// can be extracted for later processing.
pub struct Digest {
    data: Sha1State,
}

const DEFAULT_STATE: Sha1State =
    Sha1State { state: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0] };

#[inline(always)]
fn as_block(input: &[u8]) -> &[u8; 64] {
    unsafe {
        assert!(input.len() == 64);
        let arr: &[u8; 64] = mem::transmute(input.as_ptr());
        arr
    }
}

impl Sha1 {
    /// Creates an fresh sha1 hash object.
    pub fn new() -> Sha1 {
        Sha1 {
            state: DEFAULT_STATE,
            len: 0,
            blocks: Blocks {
                len: 0,
                block: [0; 64],
            },
        }
    }

    /// Resets the hash object to it's initial state.
    pub fn reset(&mut self) {
        self.state = DEFAULT_STATE;
        self.len = 0;
        self.blocks.len = 0;
    }

    /// Update hash with input data.
    pub fn update(&mut self, data: &[u8]) {
        let len = &mut self.len;
        let state = &mut self.state;
        self.blocks.input(data, |block| {
            *len += block.len() as u64;
            state.process(block);
        })
    }

    /// Retrieve digest result.
    pub fn digest(&self) -> Digest {
        let mut state = self.state;
        let bits = (self.len + (self.blocks.len as u64)) * 8;
        let extra = [(bits >> 56) as u8,
                     (bits >> 48) as u8,
                     (bits >> 40) as u8,
                     (bits >> 32) as u8,
                     (bits >> 24) as u8,
                     (bits >> 16) as u8,
                     (bits >> 8) as u8,
                     (bits >> 0) as u8];
        let mut last = [0; 128];
        let blocklen = self.blocks.len as usize;
        last[..blocklen].clone_from_slice(&self.blocks.block[..blocklen]);
        last[blocklen] = 0x80;

        if blocklen < 56 {
            last[56..64].clone_from_slice(&extra);
            state.process(as_block(&last[0..64]));
        } else {
            last[120..128].clone_from_slice(&extra);
            state.process(as_block(&last[0..64]));
            state.process(as_block(&last[64..128]));
        }

        Digest { data: state }
    }
}

impl Digest {
    /// Returns the 160 bit (20 byte) digest as a byte array.
    pub fn bytes(&self) -> [u8; 20] {
        [(self.data.state[0] >> 24) as u8,
         (self.data.state[0] >> 16) as u8,
         (self.data.state[0] >> 8) as u8,
         (self.data.state[0] >> 0) as u8,
         (self.data.state[1] >> 24) as u8,
         (self.data.state[1] >> 16) as u8,
         (self.data.state[1] >> 8) as u8,
         (self.data.state[1] >> 0) as u8,
         (self.data.state[2] >> 24) as u8,
         (self.data.state[2] >> 16) as u8,
         (self.data.state[2] >> 8) as u8,
         (self.data.state[2] >> 0) as u8,
         (self.data.state[3] >> 24) as u8,
         (self.data.state[3] >> 16) as u8,
         (self.data.state[3] >> 8) as u8,
         (self.data.state[3] >> 0) as u8,
         (self.data.state[4] >> 24) as u8,
         (self.data.state[4] >> 16) as u8,
         (self.data.state[4] >> 8) as u8,
         (self.data.state[4] >> 0) as u8]
    }
}

impl Blocks {
    fn input<F>(&mut self, mut input: &[u8], mut f: F)
        where F: FnMut(&[u8; 64])
    {
        if self.len > 0 {
            let len = self.len as usize;
            let amt = cmp::min(input.len(), self.block.len() - len);
            self.block[len..len + amt].clone_from_slice(&input[..amt]);
            if len + amt == self.block.len() {
                f(&self.block);
                self.len = 0;
                input = &input[amt..];
            } else {
                self.len += amt as u32;
                return;
            }
        }
        assert_eq!(self.len, 0);
        for chunk in input.chunks(64) {
            if chunk.len() == 64 {
                f(as_block(chunk))
            } else {
                self.block[..chunk.len()].clone_from_slice(chunk);
                self.len = chunk.len() as u32;
            }
        }
    }
}

impl Sha1State {
    fn process(&mut self, block: &[u8; 64]) {
        let mut words = [0u32; 80];

        for i in 0..16 {
            let off = i * 4;
            words[i] = (block[off + 3] as u32) | ((block[off + 2] as u32) << 8) |
                       ((block[off + 1] as u32) << 16) |
                       ((block[off] as u32) << 24);
        }

        fn ff(b: u32, c: u32, d: u32) -> u32 {
            d ^ (b & (c ^ d))
        }
        fn gg(b: u32, c: u32, d: u32) -> u32 {
            b ^ c ^ d
        }
        fn hh(b: u32, c: u32, d: u32) -> u32 {
            (b & c) | (d & (b | c))
        }
        fn ii(b: u32, c: u32, d: u32) -> u32 {
            b ^ c ^ d
        }

        for i in 16..80 {
            let n = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
            words[i] = n.rotate_left(1);
        }

        let mut a = self.state[0];
        let mut b = self.state[1];
        let mut c = self.state[2];
        let mut d = self.state[3];
        let mut e = self.state[4];

        for i in 0..80 {
            let (f, k) = match i {
                0...19 => (ff(b, c, d), 0x5a827999),
                20...39 => (gg(b, c, d), 0x6ed9eba1),
                40...59 => (hh(b, c, d), 0x8f1bbcdc),
                60...79 => (ii(b, c, d), 0xca62c1d6),
                _ => (0, 0),
            };

            let tmp = a.rotate_left(5)
                .wrapping_add(f)
                .wrapping_add(e)
                .wrapping_add(k)
                .wrapping_add(words[i]);
            e = d;
            d = c;
            c = b.rotate_left(30);
            b = a;
            a = tmp;
        }

        self.state[0] = self.state[0].wrapping_add(a);
        self.state[1] = self.state[1].wrapping_add(b);
        self.state[2] = self.state[2].wrapping_add(c);
        self.state[3] = self.state[3].wrapping_add(d);
        self.state[4] = self.state[4].wrapping_add(e);
    }
}

impl Clone for Blocks {
    fn clone(&self) -> Blocks {
        Blocks { ..*self }
    }
}

impl fmt::Display for Digest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in self.data.state.iter() {
            try!(write!(f, "{:08x}", i));
        }
        Ok(())
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[cfg(test)]
mod tests {
    extern crate std;
    extern crate rand;
    extern crate openssl;

    use self::std::prelude::v1::*;
    use self::std::io::Write;

    use Sha1;

    #[test]
    fn test_simple() {
        let mut m = Sha1::new();

        let tests = [
            ("The quick brown fox jumps over the lazy dog",
             "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"),
            ("The quick brown fox jumps over the lazy cog",
             "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3"),
            ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
            ("testing\n", "9801739daae44ec5293d4e1f53d3f4d2d426d91c"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "025ecbd5d70f8fb3c5457cd96bab13fda305dc59"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "4300320394f7ee239bcdce7d3b8bcee173a0cd5c"),
            ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
             "cef734ba81a024479e09eb5a75b6ddae62e6abf1"),
        ];

        for &(s, ref h) in tests.iter() {
            let data = s.as_bytes();

            m.reset();
            m.update(data);
            let hh = m.digest().to_string();

            assert_eq!(hh.len(), h.len());
            assert_eq!(hh, *h);
        }
    }

    #[test]
    fn test_multiple_updates() {
        let mut m = Sha1::new();

        m.reset();
        m.update("The quick brown ".as_bytes());
        m.update("fox jumps over ".as_bytes());
        m.update("the lazy dog".as_bytes());
        let hh = m.digest().to_string();

        let h = "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12";
        assert_eq!(hh.len(), h.len());
        assert_eq!(hh, &*h);
    }

    #[test]
    fn test_sha1_loop() {
        let mut m = Sha1::new();
        let s = "The quick brown fox jumps over the lazy dog.";
        let n = 1000u64;

        for _ in 0..3 {
            m.reset();
            for _ in 0..n {
                m.update(s.as_bytes());
            }
            assert_eq!(m.digest().to_string(),
                       "7ca27655f67fceaa78ed2e645a81c7f1d6e249d2");
        }
    }

    #[test]
    fn spray_and_pray() {
        use self::rand::Rng;

        let mut rng = rand::thread_rng();
        let mut m = Sha1::new();
        let mut bytes = [0; 512];

        for _ in 0..20 {
            let ty = openssl::crypto::hash::Type::SHA1;
            let mut r = openssl::crypto::hash::Hasher::new(ty);
            m.reset();
            for _ in 0..50 {
                let len = rng.gen::<usize>() % bytes.len();
                rng.fill_bytes(&mut bytes[..len]);
                m.update(&bytes[..len]);
                r.write(&bytes[..len]).unwrap();
            }
            assert_eq!(r.finish(), m.digest().bytes());
        }
    }
}
<|endoftext|>


<commit_before>//! Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
//!
//! ## Example
//!
//! ```no_run
//! use actix_web::{get, web, App, HttpServer, Responder};
//!
//! #[get("/{id}/{name}/index.html")]
//! async fn index(path: web::Path<(u32, String)>) -> impl Responder {
//!     let (id, name) = path.into_inner();
//!     format!("Hello {}! id:{}", name, id)
//! }
//!
//! #[actix_web::main]
//! async fn main() -> std::io::Result<()> {
//!     HttpServer::new(|| App::new().service(index))
//!         .bind("127.0.0.1:8080")?
//!         .run()
//!         .await
//! }
//! ```
//!
//! ## Documentation & Community Resources
//!
//! In addition to this API documentation, several other resources are available:
//!
//! * [Website & User Guide](https://actix.rs/)
//! * [Examples Repository](https://github.com/actix/examples)
//! * [Community Chat on Gitter](https://gitter.im/actix/actix-web)
//!
//! To get started navigating the API docs, you may consider looking at the following pages first:
//!
//! * [App]: This struct represents an Actix Web application and is used to
//!   configure routes and other common application settings.
//!
//! * [HttpServer]: This struct represents an HTTP server instance and is
//!   used to instantiate and configure servers.
//!
//! * [web]: This module provides essential types for route registration as well as
//!   common utilities for request handlers.
//!
//! * [HttpRequest] and [HttpResponse]: These
//!   structs represent HTTP requests and responses and expose methods for creating, inspecting,
//!   and otherwise utilizing them.
//!
//! ## Features
//!
//! * Supports *HTTP/1.x* and *HTTP/2*
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * Client/server [WebSockets](https://actix.rs/docs/websockets/) support
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Powerful [request routing](https://actix.rs/docs/url-dispatch/)
//! * Multipart streams
//! * Static assets
//! * SSL support using OpenSSL or Rustls
//! * Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
//! * Includes an async [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html)
//! * Runs on stable Rust 1.46+
//!
//! ## Crate Features
//!
//! * `compress` - content encoding compression support (enabled by default)
//! * `cookies` - cookies support (enabled by default)
//! * `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
//! * `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
//! * `secure-cookies` - secure cookies support

#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::needless_doctest_main, clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

mod app;
mod app_service;
mod config;
mod data;
pub mod error;
mod extract;
pub mod guard;
mod handler;
pub mod http;
mod info;
pub mod middleware;
mod request;
mod request_data;
mod resource;
mod responder;
mod rmap;
mod route;
mod scope;
mod server;
mod service;
pub mod test;
pub(crate) mod types;
pub mod web;

#[cfg(feature = "cookies")]
pub use actix_http::cookie;
pub use actix_http::Response as HttpResponse;
pub use actix_http::{body, Error, HttpMessage, ResponseError, Result};
pub use actix_rt as rt;
pub use actix_web_codegen::*;

pub use crate::app::App;
pub use crate::extract::FromRequest;
pub use crate::request::HttpRequest;
pub use crate::resource::Resource;
pub use crate::responder::Responder;
pub use crate::route::Route;
pub use crate::scope::Scope;
pub use crate::server::HttpServer;
// TODO: is exposing the error directly really needed
pub use crate::types::{Either, EitherExtractError};

pub mod dev {
    //! The `actix-web` prelude for library developers
    //!
    //! The purpose of this module is to alleviate imports of many common actix
    //! traits by adding a glob import to the top of actix heavy modules:
    //!
    //! ```
    //! # #![allow(unused_imports)]
    //! use actix_web::dev::*;
    //! ```

    pub use crate::config::{AppConfig, AppService};
    #[doc(hidden)]
    pub use crate::handler::Handler;
    pub use crate::info::ConnectionInfo;
    pub use crate::rmap::ResourceMap;
    pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService};

    pub use crate::types::form::UrlEncoded;
    pub use crate::types::json::JsonBody;
    pub use crate::types::readlines::Readlines;

    pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream};
    #[cfg(feature = "compress")]
    pub use actix_http::encoding::Decoder as Decompress;
    pub use actix_http::ResponseBuilder as HttpResponseBuilder;
    pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
    pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
    pub use actix_server::Server;
    pub use actix_service::{Service, Transform};

    pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
        for path in &mut patterns {
            if !path.is_empty() && !path.starts_with('/') {
                path.insert(0, '/');
            };
        }
        patterns
    }

    use crate::http::header::ContentEncoding;
    use actix_http::{Response, ResponseBuilder};

    struct Enc(ContentEncoding);

    /// Helper trait that allows to set specific encoding for response.
    pub trait BodyEncoding {
        /// Get content encoding
        fn get_encoding(&self) -> Option<ContentEncoding>;

        /// Set content encoding
        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self;
    }

    impl BodyEncoding for ResponseBuilder {
        fn get_encoding(&self) -> Option<ContentEncoding> {
            self.extensions().get::<Enc>().map(|enc| enc.0)
        }

        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
            self.extensions_mut().insert(Enc(encoding));
            self
        }
    }

    impl<B> BodyEncoding for Response<B> {
        fn get_encoding(&self) -> Option<ContentEncoding> {
            self.extensions().get::<Enc>().map(|enc| enc.0)
        }

        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
            self.extensions_mut().insert(Enc(encoding));
            self
        }
    }
}
<commit_msg>make module/crate re-exports doc inline (#2141)<commit_after>//! Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
//!
//! ## Example
//!
//! ```no_run
//! use actix_web::{get, web, App, HttpServer, Responder};
//!
//! #[get("/{id}/{name}/index.html")]
//! async fn index(path: web::Path<(u32, String)>) -> impl Responder {
//!     let (id, name) = path.into_inner();
//!     format!("Hello {}! id:{}", name, id)
//! }
//!
//! #[actix_web::main]
//! async fn main() -> std::io::Result<()> {
//!     HttpServer::new(|| App::new().service(index))
//!         .bind("127.0.0.1:8080")?
//!         .run()
//!         .await
//! }
//! ```
//!
//! ## Documentation & Community Resources
//!
//! In addition to this API documentation, several other resources are available:
//!
//! * [Website & User Guide](https://actix.rs/)
//! * [Examples Repository](https://github.com/actix/examples)
//! * [Community Chat on Gitter](https://gitter.im/actix/actix-web)
//!
//! To get started navigating the API docs, you may consider looking at the following pages first:
//!
//! * [App]: This struct represents an Actix Web application and is used to
//!   configure routes and other common application settings.
//!
//! * [HttpServer]: This struct represents an HTTP server instance and is
//!   used to instantiate and configure servers.
//!
//! * [web]: This module provides essential types for route registration as well as
//!   common utilities for request handlers.
//!
//! * [HttpRequest] and [HttpResponse]: These
//!   structs represent HTTP requests and responses and expose methods for creating, inspecting,
//!   and otherwise utilizing them.
//!
//! ## Features
//!
//! * Supports *HTTP/1.x* and *HTTP/2*
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * Client/server [WebSockets](https://actix.rs/docs/websockets/) support
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Powerful [request routing](https://actix.rs/docs/url-dispatch/)
//! * Multipart streams
//! * Static assets
//! * SSL support using OpenSSL or Rustls
//! * Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
//! * Includes an async [HTTP client](https://actix.rs/actix-web/actix_web/client/index.html)
//! * Runs on stable Rust 1.46+
//!
//! ## Crate Features
//!
//! * `compress` - content encoding compression support (enabled by default)
//! * `cookies` - cookies support (enabled by default)
//! * `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
//! * `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
//! * `secure-cookies` - secure cookies support

#![deny(rust_2018_idioms, nonstandard_style)]
#![allow(clippy::needless_doctest_main, clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

mod app;
mod app_service;
mod config;
mod data;
pub mod error;
mod extract;
pub mod guard;
mod handler;
pub mod http;
mod info;
pub mod middleware;
mod request;
mod request_data;
mod resource;
mod responder;
mod rmap;
mod route;
mod scope;
mod server;
mod service;
pub mod test;
pub(crate) mod types;
pub mod web;

#[cfg(feature = "cookies")]
pub use actix_http::cookie;
pub use actix_http::Response as HttpResponse;
pub use actix_http::{body, Error, HttpMessage, ResponseError, Result};
#[doc(inline)]
pub use actix_rt as rt;
pub use actix_web_codegen::*;

pub use crate::app::App;
pub use crate::extract::FromRequest;
pub use crate::request::HttpRequest;
pub use crate::resource::Resource;
pub use crate::responder::Responder;
pub use crate::route::Route;
pub use crate::scope::Scope;
pub use crate::server::HttpServer;
// TODO: is exposing the error directly really needed
pub use crate::types::{Either, EitherExtractError};

pub mod dev {
    //! The `actix-web` prelude for library developers
    //!
    //! The purpose of this module is to alleviate imports of many common actix
    //! traits by adding a glob import to the top of actix heavy modules:
    //!
    //! ```
    //! # #![allow(unused_imports)]
    //! use actix_web::dev::*;
    //! ```

    pub use crate::config::{AppConfig, AppService};
    #[doc(hidden)]
    pub use crate::handler::Handler;
    pub use crate::info::ConnectionInfo;
    pub use crate::rmap::ResourceMap;
    pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService};

    pub use crate::types::form::UrlEncoded;
    pub use crate::types::json::JsonBody;
    pub use crate::types::readlines::Readlines;

    pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream};
    #[cfg(feature = "compress")]
    pub use actix_http::encoding::Decoder as Decompress;
    pub use actix_http::ResponseBuilder as HttpResponseBuilder;
    pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, ResponseHead};
    pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
    pub use actix_server::Server;
    pub use actix_service::{Service, Transform};

    pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
        for path in &mut patterns {
            if !path.is_empty() && !path.starts_with('/') {
                path.insert(0, '/');
            };
        }
        patterns
    }

    use crate::http::header::ContentEncoding;
    use actix_http::{Response, ResponseBuilder};

    struct Enc(ContentEncoding);

    /// Helper trait that allows to set specific encoding for response.
    pub trait BodyEncoding {
        /// Get content encoding
        fn get_encoding(&self) -> Option<ContentEncoding>;

        /// Set content encoding
        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self;
    }

    impl BodyEncoding for ResponseBuilder {
        fn get_encoding(&self) -> Option<ContentEncoding> {
            self.extensions().get::<Enc>().map(|enc| enc.0)
        }

        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
            self.extensions_mut().insert(Enc(encoding));
            self
        }
    }

    impl<B> BodyEncoding for Response<B> {
        fn get_encoding(&self) -> Option<ContentEncoding> {
            self.extensions().get::<Enc>().map(|enc| enc.0)
        }

        fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
            self.extensions_mut().insert(Enc(encoding));
            self
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name="nock"]

#![feature(box_syntax, box_patterns)]

use std::fmt;
use std::str;

/// A Nock noun, the basic unit of representation.
///
/// The noun is either an atom a that's a positive integer or a pair of two
/// nouns, [a b].
#[derive(Clone, PartialEq, Eq)]
pub enum Noun {
    Atom(u64), // TODO: Need bigints?
    Cell(Box<Noun>, Box<Noun>),
}

impl Noun {
    pub fn new<T: Into<Noun>>(val: T) -> Noun {
        val.into()
    }
}

impl Into<Noun> for u64 {
    fn into(self) -> Noun { Noun::Atom(self) }
}

impl fmt::Display for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Atom(ref n) => write!(f, "{}", n),
            &Cell(ref a, ref b) => {
                try!(write!(f, "[{} ", a));
                // List pretty-printer.
                let mut cur = b;
                loop {
                    match cur {
                        &box Cell(ref a, ref b) => {
                            try!(write!(f, "{} ", a));
                            cur = &b;
                        }
                        &box Atom(ref n) => {
                            return write!(f, "{}]", n);
                        }
                    }
                }
            }
        }
    }
}

impl fmt::Debug for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ParseNockError;

impl str::FromStr for Noun {
    type Err = ParseNockError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        unimplemented!();
    }
}

/// An operator for a Nock formula.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Op {
    Wut, // ?
    Lus, // +
    Tis, // =
    Fas, // /
    Tar, // *
}

impl fmt::Display for Op {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Op::*;
        write!(f, "{}",
               match self {
                   &Wut => '?',
                   &Lus => '+',
                   &Tis => '=',
                   &Fas => '/',
                   &Tar => '*',
               })
    }
}

#[derive(Clone, PartialEq, Eq)]
pub struct Formula(pub Op, pub Noun);

impl str::FromStr for Formula {
    type Err = ParseNockError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        unimplemented!();
    }
}

impl fmt::Display for Formula {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.0, self.1)
    }
}

impl fmt::Debug for Formula {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) }
}

use Op::*;
use Noun::*;

// Nock(a)          *a
// [a b c]          [a [b c]]
//
// ?[a b]           0
// ?a               1
// +[a b]           +[a b]
// +a               1 + a
// =[a a]           0
// =[a b]           1
// =a               =a
//
// /[1 a]           a
// /[2 a b]         a
// /[3 a b]         b
// /[(a + a) b]     /[2 /[a b]]
// /[(a + a + 1) b] /[3 /[a b]]
// /a               /a
//
// *[a [b c] d]     [*[a b c] *[a d]]
//
// *[a 0 b]         /[b a]
// *[a 1 b]         b
// *[a 2 b c]       *[*[a b] *[a c]]
// *[a 3 b]         ?*[a b]
// *[a 4 b]         +*[a b]
// *[a 5 b]         =*[a b]
//
// *[a 6 b c d]     *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
// *[a 7 b c]       *[a 2 b 1 c]
// *[a 8 b c]       *[a 7 [[7 [0 1] b] 0 1] c]
// *[a 9 b c]       *[a 7 c 2 [0 1] 0 b]
// *[a 10 [b c] d]  *[a 8 c 7 [0 3] d]
// *[a 10 b c]      *[a c]
//
// *a               *a

impl Formula {
    pub fn eval(self) -> Result<Noun, Formula> {
        match (self.0, self.1) {
            (Wut, Cell(_, _)) => Ok(Atom(0)),
            (Wut, Atom(_)) => Ok(Atom(1)),
            (Lus, Atom(a)) => Ok(Atom(1 + a)),
            (Lus, a) => Err(Formula(Lus, a)),
            (Tis, Cell(a, b)) => Ok(Atom(if a == b { 0 } else { 1 })),
            (Tis, a) => Err(Formula(Tis, a)),

            (Fas, Cell(box Atom(1), box a)) => Ok(a),
            (Fas, Cell(box Atom(2), box Cell(box a, _))) => Ok(a),
            (Fas, Cell(box Atom(3), box Cell(_, box b))) => Ok(b),
            (Fas, Cell(box Atom(a), b)) => {
                let x = try!(eval(Fas, Cell(box Atom(a / 2), b)));
                eval(Fas, Cell(box Atom(if a % 2 == 0 { 2 } else { 3 }), box x))
            }
            (Fas, a) => Err(Formula(Fas, a)),

            (Tar, Cell(a, box Cell(box Cell(b, c), d))) => {
                let x = try!(Formula(Tar, Cell(a.clone(), box Cell(b, c))).eval());
                let y = try!(Formula(Tar, Cell(a, d)).eval());
                Ok(Cell(box x, box y))
            }

            // TODO: Numbered tar ops.

            (Tar, a) => Err(Formula(Tar, a))
        }
    }
}

pub fn eval(op: Op, noun: Noun) -> Result<Noun, Formula> {
    Formula(op, noun).eval()
}

pub fn nock(noun: Noun) -> Result<Noun, Formula> { eval(Wut, noun) }

pub fn a(val: u64) -> Noun { Noun::Atom(val) }

macro_rules! n {
    [$x:expr, $y:expr] => { ::nock::Noun::Cell(box ::nock::Noun::new($x), box ::nock::Noun::new($y)) };
    [$x:expr, $y:expr, $($ys:expr),+] => { ::nock::Noun::Cell(box ::nock::Noun::new($x), box n![$y, $($ys),+]) };
}

// Re-export hack for testing macros.
mod nock {
    pub use Noun;
}

#[cfg(test)]
mod test {
#[test]
    fn test_macro() {
        use super::Noun::*;

        assert_eq!(n![1, 2], Cell(box Atom(1), box Atom(2)));
        assert_eq!(n![1, n![2, 3]], Cell(box Atom(1), box Cell(box Atom(2), box Atom(3))));
        assert_eq!(n![1, 2, 3], Cell(box Atom(1), box Cell(box Atom(2), box Atom(3))));
        assert_eq!(n![n![1, 2], 3], Cell(box Cell(box Atom(1), box Atom(2)), box Atom(3)));
        assert_eq!(n![n![1, 2], n![3, 4]], Cell(box Cell(box Atom(1), box Atom(2)), box Cell(box Atom(3), box Atom(4))));
        assert_eq!(n![n![1, 2], n![3, 4], n![5, 6]],
                   Cell(box Cell(box Atom(1), box Atom(2)),
                   box Cell(box Cell(box Atom(3), box Atom(4)),
                   box Cell(box Atom(5), box Atom(6)))));
    }
#[test]
    fn test_eval() {
        use super::Op::*;
        use super::{a, eval, Formula};

        // Examples from https://github.com/cgyarvin/urbit/blob/master/doc/book/1-nock.markdown
        assert_eq!(eval(Tis, n![0, 0]), Ok(a(0)));
        assert_eq!(eval(Tis, n![2, 2]), Ok(a(0)));
        assert_eq!(eval(Tis, n![0, 1]), Ok(a(1)));

        assert_eq!(eval(Fas, n![1, n![n![4, 5], n![6, 14, 15]]]), Ok(n![n![4, 5], n![6, 14, 15]]));
        assert_eq!(eval(Fas, n![2, n![n![4, 5], n![6, 14, 15]]]), Ok(n![4, 5]));
        assert_eq!(eval(Fas, n![3, n![n![4, 5], n![6, 14, 15]]]), Ok(n![6, 14, 15]));
        assert_eq!(eval(Fas, n![7, n![n![4, 5], n![6, 14, 15]]]), Ok(n![14, 15]));

        assert_eq!(eval(Lus, n![1, 2]), Err(Formula(Lus, n![1, 2])));
    }

#[test]
    fn test_parse_noun() {
        use super::Noun;

        assert!("".parse::<Noun>().is_err());
        assert!("[]".parse::<Noun>().is_err());
        assert!("[1]".parse::<Noun>().is_err());
        assert!("[x y]".parse::<Noun>().is_err());
        assert_eq!("[1 2]".parse::<Noun>(), Ok(n![1, 2]));
        assert_eq!("[1 2 3]".parse::<Noun>(), Ok(n![1, 2, 3]));
        assert_eq!("[[1 2] 3]".parse::<Noun>(), Ok(n![n![1, 2], 3]));
        assert_eq!("[1 [2 3]]".parse::<Noun>(), Ok(n![1, n![2, 3]]));

    }

#[test]
    fn test_parse_formula() {
        use super::Op::*;
        use super::Formula;

        assert_eq!("+[1 2]".parse::<Formula>(), Ok(Formula(Lus, n![1, 2])));
    }
}
<commit_msg>WIP Remaining tar ops<commit_after>#![crate_name="nock"]

#![feature(box_syntax, box_patterns)]

use std::fmt;
use std::str;

/// A Nock noun, the basic unit of representation.
///
/// The noun is either an atom a that's a positive integer or a pair of two
/// nouns, [a b].
#[derive(Clone, PartialEq, Eq)]
pub enum Noun {
    Atom(u64), // TODO: Need bigints?
    Cell(Box<Noun>, Box<Noun>),
}

impl Noun {
    pub fn new<T: Into<Noun>>(val: T) -> Noun {
        val.into()
    }
}

impl Into<Noun> for u64 {
    fn into(self) -> Noun { Noun::Atom(self) }
}

impl fmt::Display for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Atom(ref n) => write!(f, "{}", n),
            &Cell(ref a, ref b) => {
                try!(write!(f, "[{} ", a));
                // List pretty-printer.
                let mut cur = b;
                loop {
                    match cur {
                        &box Cell(ref a, ref b) => {
                            try!(write!(f, "{} ", a));
                            cur = &b;
                        }
                        &box Atom(ref n) => {
                            return write!(f, "{}]", n);
                        }
                    }
                }
            }
        }
    }
}

impl fmt::Debug for Noun {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ParseNockError;

impl str::FromStr for Noun {
    type Err = ParseNockError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        unimplemented!();
    }
}

/// An operator for a Nock formula.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Op {
    Wut, // ?
    Lus, // +
    Tis, // =
    Fas, // /
    Tar, // *
}

impl fmt::Display for Op {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Op::*;
        write!(f, "{}",
               match self {
                   &Wut => '?',
                   &Lus => '+',
                   &Tis => '=',
                   &Fas => '/',
                   &Tar => '*',
               })
    }
}

#[derive(Clone, PartialEq, Eq)]
pub struct Formula(pub Op, pub Noun);

impl str::FromStr for Formula {
    type Err = ParseNockError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        unimplemented!();
    }
}

impl fmt::Display for Formula {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}", self.0, self.1)
    }
}

impl fmt::Debug for Formula {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) }
}

use Op::*;
use Noun::*;

// Nock(a)          *a
// [a b c]          [a [b c]]
//
// ?[a b]           0
// ?a               1
// +[a b]           +[a b]
// +a               1 + a
// =[a a]           0
// =[a b]           1
// =a               =a
//
// /[1 a]           a
// /[2 a b]         a
// /[3 a b]         b
// /[(a + a) b]     /[2 /[a b]]
// /[(a + a + 1) b] /[3 /[a b]]
// /a               /a
//
// *[a [b c] d]     [*[a b c] *[a d]]
//
// *[a 0 b]         /[b a]
// *[a 1 b]         b
// *[a 2 b c]       *[*[a b] *[a c]]
// *[a 3 b]         ?*[a b]
// *[a 4 b]         +*[a b]
// *[a 5 b]         =*[a b]
//
// *[a 6 b c d]     *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
// *[a 7 b c]       *[a 2 b 1 c]
// *[a 8 b c]       *[a 7 [[7 [0 1] b] 0 1] c]
// *[a 9 b c]       *[a 7 c 2 [0 1] 0 b]
// *[a 10 [b c] d]  *[a 8 c 7 [0 3] d]
// *[a 10 b c]      *[a c]
//
// *a               *a

impl Formula {
    pub fn eval(self) -> Result<Noun, Formula> {
        match (self.0, self.1) {
            (Wut, Cell(_, _)) => Ok(Atom(0)),
            (Wut, Atom(_)) => Ok(Atom(1)),

            // Math
            (Lus, Atom(a)) => Ok(Atom(1 + a)),

            (Lus, a) => Err(Formula(Lus, a)),
            (Tis, Cell(a, b)) => Ok(Atom(if a == b { 0 } else { 1 })),
            (Tis, a) => Err(Formula(Tis, a)),

            (Fas, Cell(box Atom(1), box a)) => Ok(a),
            (Fas, Cell(box Atom(2), box Cell(box a, _))) => Ok(a),
            (Fas, Cell(box Atom(3), box Cell(_, box b))) => Ok(b),

            // Math
            (Fas, Cell(box Atom(a), b)) => {
                let x = try!(Formula(Fas, Cell(box Atom(a / 2), b)).eval());
                eval(Fas, Cell(box Atom(if a % 2 == 0 { 2 } else { 3 }), box x))
            }

            (Fas, a) => Err(Formula(Fas, a)),

            (Tar, Cell(a, box Cell(box Cell(b, c), d))) => {
                let x = try!(Formula(Tar, Cell(a.clone(), box Cell(b, c))).eval());
                let y = try!(Formula(Tar, Cell(a, d)).eval());
                Ok(Cell(box x, box y))
            }

            (Tar, Cell(a, box Cell(box Atom(0), b))) =>
                Formula(Fas, Cell(b, a)).eval(),

            (Tar, Cell(a, box Cell(box Atom(1), box b))) => Ok(b),

            (Tar, Cell(a, box Cell(box Atom(2), box Cell(b, c)))) => {
                let x = try!(Formula(Tar, Cell(a.clone(), b)).eval());
                let y = try!(Formula(Tar, Cell(a, c)).eval());
                Formula(Tar, Cell(box x, box y)).eval()
            }

            (Tar, Cell(a, box Cell(box Atom(3), b))) => {
                let x = try!(Formula(Tar, Cell(a, b)).eval());
                Formula(Wut, x).eval()
            }

            (Tar, a) => Err(Formula(Tar, a))
        }
    }
}

pub fn eval(op: Op, noun: Noun) -> Result<Noun, Formula> {
    Formula(op, noun).eval()
}

pub fn nock(noun: Noun) -> Result<Noun, Formula> { eval(Wut, noun) }

pub fn a(val: u64) -> Noun { Noun::Atom(val) }

macro_rules! n {
    [$x:expr, $y:expr] => { ::nock::Noun::Cell(box ::nock::Noun::new($x), box ::nock::Noun::new($y)) };
    [$x:expr, $y:expr, $($ys:expr),+] => { ::nock::Noun::Cell(box ::nock::Noun::new($x), box n![$y, $($ys),+]) };
}

// Re-export hack for testing macros.
mod nock {
    pub use Noun;
}

#[cfg(test)]
mod test {
#[test]
    fn test_macro() {
        use super::Noun::*;

        assert_eq!(n![1, 2], Cell(box Atom(1), box Atom(2)));
        assert_eq!(n![1, n![2, 3]], Cell(box Atom(1), box Cell(box Atom(2), box Atom(3))));
        assert_eq!(n![1, 2, 3], Cell(box Atom(1), box Cell(box Atom(2), box Atom(3))));
        assert_eq!(n![n![1, 2], 3], Cell(box Cell(box Atom(1), box Atom(2)), box Atom(3)));
        assert_eq!(n![n![1, 2], n![3, 4]], Cell(box Cell(box Atom(1), box Atom(2)), box Cell(box Atom(3), box Atom(4))));
        assert_eq!(n![n![1, 2], n![3, 4], n![5, 6]],
                   Cell(box Cell(box Atom(1), box Atom(2)),
                   box Cell(box Cell(box Atom(3), box Atom(4)),
                   box Cell(box Atom(5), box Atom(6)))));
    }
#[test]
    fn test_eval() {
        use super::Op::*;
        use super::{a, eval, Formula};

        // Examples from https://github.com/cgyarvin/urbit/blob/master/doc/book/1-nock.markdown
        assert_eq!(eval(Tis, n![0, 0]), Ok(a(0)));
        assert_eq!(eval(Tis, n![2, 2]), Ok(a(0)));
        assert_eq!(eval(Tis, n![0, 1]), Ok(a(1)));

        assert_eq!(eval(Fas, n![1, n![n![4, 5], n![6, 14, 15]]]), Ok(n![n![4, 5], n![6, 14, 15]]));
        assert_eq!(eval(Fas, n![2, n![n![4, 5], n![6, 14, 15]]]), Ok(n![4, 5]));
        assert_eq!(eval(Fas, n![3, n![n![4, 5], n![6, 14, 15]]]), Ok(n![6, 14, 15]));
        assert_eq!(eval(Fas, n![7, n![n![4, 5], n![6, 14, 15]]]), Ok(n![14, 15]));

        assert_eq!(eval(Lus, n![1, 2]), Err(Formula(Lus, n![1, 2])));
    }

#[test]
    fn test_parse_noun() {
        use super::Noun;

        assert!("".parse::<Noun>().is_err());
        assert!("[]".parse::<Noun>().is_err());
        assert!("[1]".parse::<Noun>().is_err());
        assert!("[x y]".parse::<Noun>().is_err());
        assert_eq!("[1 2]".parse::<Noun>(), Ok(n![1, 2]));
        assert_eq!("[1 2 3]".parse::<Noun>(), Ok(n![1, 2, 3]));
        assert_eq!("[[1 2] 3]".parse::<Noun>(), Ok(n![n![1, 2], 3]));
        assert_eq!("[1 [2 3]]".parse::<Noun>(), Ok(n![1, n![2, 3]]));

    }

#[test]
    fn test_parse_formula() {
        use super::Op::*;
        use super::Formula;

        assert_eq!("+[1 2]".parse::<Formula>(), Ok(Formula(Lus, n![1, 2])));
    }
}
<|endoftext|>


<commit_before>#![crate_id = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate iron;
#[phase(plugin, link)]
extern crate log;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::{GetUrl, Serve};
use iron::middleware::{Status, Continue, Unwind};

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        match req.url() {
            Some(path) => {
                // Check for requested file
                match res.serve_file(&self.root_path.join(
                    Path::new(
                        // Coerce to relative path, see http://is.gd/yz9p0B
                        "./".to_string().append(path.as_slice())))) {
                    Ok(()) => {
                        debug!("Serving static file at {}.",
                            &self.root_path.join("./".to_string().append(path.as_slice())).display());
                        return Unwind
                    },
                    Err(_) => ()
                }
                // Check for index.html
                // Do not serve index.html as directory
            },
            None => ()
        }
        Continue
    }
}
<commit_msg>(feat) 303 when attempting to serve files as dir.<commit_after>#![crate_id = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate url;
#[phase(plugin, link)]
extern crate log;
extern crate http;
extern crate iron;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::{GetUrl, Serve};
use iron::middleware::{Status, Continue, Unwind};

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        match req.url() {
            Some(path) => {
                // Check for requested file
                match res.serve_file(&self.root_path.join(
                    Path::new(
                        // Coerce to relative path.
                        // We include the slash to ensure that you never have a path like ".index.html"
                        // when you meant "./index.html", see http://is.gd/yz9p0B for an example.
                        "./".to_string().append(path.as_slice())))) {
                    Ok(()) => {
                        debug!("Serving static file at {}.",
                            &self.root_path.join("./".to_string().append(path.as_slice())).display());
                        return Unwind
                    },
                    Err(_) => ()
                }

                // Check for index.html
                let index_path = self.root_path.join(
                    Path::new("./".to_string().append(path.as_slice()))
                        .join("./index.html".to_string()));
                if index_path.is_file() {
                    // Avoid serving as a directory
                    match path.as_slice().char_at_reverse(path.len()) {
                        '/' => {
                            match res.serve_file(&index_path) {
                                Ok(()) => {
                                    debug!("Serving static file at {}.",
                                        &index_path.display());
                                    return Unwind
                                },
                                Err(err) => debug!("Failed while trying to serve index.html: {}", err)
                            }
                        },
                        // 303:
                        _   => {
                            res.headers.location = Some(::url::Url {
                                path: path.clone().append("/"),
                                scheme: "".to_string(),
                                user: None,
                                host: "".to_string(),
                                port: None,
                                query: vec![],
                                fragment: None
                            });
                            let _ = res.serve(::http::status::SeeOther,
                                format!("Redirecting to {}/", path).as_slice());
                            return Unwind
                        }
                    }
                }
            },
            None => ()
        }
        Continue
    }
}
<|endoftext|>