<commit_before>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(missing_docs)]

//! glTF 2.0 loader
//!
//! This crate is intended to load [glTF 2.0], a file format designed for the
//! efficient runtime transmission of 3D scenes. The crate aims to provide
//! rustic utilities that make working with glTF simple and intuitive.
//!
//! [glTF 2.0]: https://www.khronos.org/gltf
//!
//! ## Installation
//!
//! Add `gltf` version 0.8 to your `Cargo.toml`.
//!
//! ```toml
//! [dependencies.gltf]
//! version = "0.8"
//! ```
//!
//! ## Examples
//!
//! ### Walking the node hierarchy
//!
//! Below demonstates visiting the root [`Node`]s of every [`Scene`], printing the
//! number of children each node has.
//!
//! [`Node`]: scene/struct.Node.html
//! [`Scene`]: scene/struct.Scene.html
//! ```
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! let file = std::fs::File::open("examples/Box.gltf")?;
//! let reader = std::io::BufReader::new(file);
//! let json = gltf::json::from_reader(reader)?;
//! let gltf = gltf::Gltf::from_json(json);
//! for scene in gltf.scenes() {
//!     for node in scene.nodes() {
//!         // Do something with this node.
//!         println!(
//!             "Node {} has {} children",
//!             node.index(),
//!             node.children().count(),
//!         );
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```
//!
//! ### Providing `Gltf` with external buffer data
//!
//! The [`Source`] trait provides `glTF` objects with their buffer data. This allows
//! the crate to provide more abstractions such as iterating over the positions of
//! a `Primitive`. See the documentation of [`Loaded`] for all the methods available
//! for loaded `glTF`.
//!
//! The `gltf-importer` crate contains the reference implementation of the
//! `Source` trait and may be used to read buffer data from the file system.
//!
//! [`Source`]: trait.Source.html
//! [`Loaded`]: struct.Loaded.html
//! ```
//! # use gltf::json;
//! # use gltf::Gltf;
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! # let path = "./glTF-Sample-Models/2.0/Box/glTF/Box.gltf";
//! # let file = std::fs::File::open(path)?;
//! # let reader = std::io::BufReader::new(file);
//! # let json = json::from_reader(reader)?;
//! # let gltf = Gltf::from_json(json);
//! #[derive(Debug)]
//! struct BoxExampleData(&'static [u8]);
//!
//! impl gltf::Source for BoxExampleData {
//!     fn source_buffer(&self, _: &gltf::Buffer) -> &[u8] {
//!         // In a real implementation, the `Source` must provide all the data
//!         // necessary to load the object, and must not fail.
//!         //
//!         // This example meets the above criteria, since it provides all the data
//!         // for the 'Box' sample model, which has exactly one external buffer.
//!         self.0
//!     }
//! }
//!
//! let data = BoxExampleData(include_bytes!("examples/Box0.bin"));
//! let loaded_gltf = gltf.loaded(&data);
//! for mesh in loaded_gltf.meshes() {
//!     for primitive in mesh.primitives() {
//!         if let Some(iter) = primitive.indices_u32() {
//!             // Do something with the primitive data.
//!             let indices: Vec<u32> = iter.collect();
//!             println!("{:?}", indices);
//!         }
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```

#[macro_use]
extern crate lazy_static;

/// Contains (de)serializable data structures that match the glTF JSON text.
pub extern crate gltf_json as json;

/// Contains `Accessor` and other related data structures.
pub mod accessor;

/// Contains `Animation` and other related data structures.
pub mod animation;

/// Contains `Buffer`, `View`, and other related data structures.
pub mod buffer;

/// Contains `Camera` and other related data structures.
pub mod camera;

/// Contains `Gltf`, and other related data structures.
pub mod gltf;

/// Contains `Image` and other related data structures.
pub mod image;

/// Contains `Material` and other related data structures.
pub mod material;

/// Contains `Mesh` and other related data structures.
pub mod mesh;

/// Contains `Root`.
pub mod root;

/// Contains `Scene`, `Node`, and other related data structures.
pub mod scene;

/// Contains `Skin` and other related data structures.
pub mod skin;

/// Contains `Texture`, `Sampler`, and other related data structures.
pub mod texture;

pub use self::animation::Animation;
pub use self::accessor::Accessor;
pub use self::buffer::Buffer;
pub use self::camera::Camera;
pub use self::gltf::Gltf;
pub use self::image::Image;
pub use self::material::Material;
pub use self::mesh::{Mesh, Primitive};
pub use self::scene::{Node, Scene};
pub use self::skin::Skin;
pub use self::texture::Texture;

/// Represents sources of buffer data.
///
/// The user is expected to implement this trait in order to unlock the abstractions
/// provided by the [`Loaded`] type. The `gltf-importer` crate provides a useable
/// reference implementation.
///
/// [`Loaded`]: struct.Loaded.html
pub trait Source: std::fmt::Debug {
    /// Return the buffer data referenced by the given `Buffer`.
    ///
    /// This method must not fail.
    fn source_buffer(&self, buffer: &Buffer) -> &[u8];
}

/// Wrapper type representing a `glTF` object whose data is immediately ready for
/// use.
#[derive(Clone, Debug)]
pub struct Loaded<'a, T> {
    /// The wrapped item.
    item: T,

    /// The data source for this item and all of its children.
    source: &'a Source,
}

impl<'a, T> std::ops::Deref for Loaded<'a, T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.item
    }
}
<commit_msg>Update doc tests<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(missing_docs)]

//! glTF 2.0 loader
//!
//! This crate is intended to load [glTF 2.0], a file format designed for the
//! efficient runtime transmission of 3D scenes. The crate aims to provide
//! rustic utilities that make working with glTF simple and intuitive.
//!
//! [glTF 2.0]: https://www.khronos.org/gltf
//!
//! ## Installation
//!
//! Add `gltf` version 0.8 to your `Cargo.toml`.
//!
//! ```toml
//! [dependencies.gltf]
//! version = "0.8"
//! ```
//!
//! ## Examples
//!
//! ### Walking the node hierarchy
//!
//! Below demonstates visiting the root [`Node`]s of every [`Scene`], printing the
//! number of children each node has.
//!
//! [`Node`]: scene/struct.Node.html
//! [`Scene`]: scene/struct.Scene.html
//! ```
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! let file = std::fs::File::open("examples/Box.gltf")?;
//! let reader = std::io::BufReader::new(file);
//! let json = gltf::json::from_reader(reader)?;
//! let gltf = gltf::Gltf::from_json(json);
//! for scene in gltf.scenes() {
//!     for node in scene.nodes() {
//!         // Do something with this node.
//!         println!(
//!             "Node {} has {} children",
//!             node.index(),
//!             node.children().count(),
//!         );
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```
//!
//! ### Providing `Gltf` with external buffer data
//!
//! The [`Source`] trait provides `glTF` objects with their buffer data. This allows
//! the crate to provide more abstractions such as iterating over the positions of
//! a `Primitive`. See the documentation of [`Loaded`] for all the methods available
//! for loaded `glTF`.
//!
//! The `gltf-importer` crate contains the reference implementation of the
//! `Source` trait and may be used to read buffer data from the file system.
//!
//! [`Source`]: trait.Source.html
//! [`Loaded`]: struct.Loaded.html
//! ```
//! # use gltf::json;
//! # use gltf::Gltf;
//! # fn run() -> Result<(), Box<std::error::Error>> {
//! # let path = "./glTF-Sample-Models/2.0/Box/glTF/Box.gltf";
//! # let file = std::fs::File::open(path)?;
//! # let reader = std::io::BufReader::new(file);
//! # let json = json::from_reader(reader)?;
//! # let gltf = Gltf::from_json(json);
//! #[derive(Debug)]
//! struct BoxExampleData(&'static [u8]);
//!
//! impl gltf::Source for BoxExampleData {
//!     fn source_buffer(&self, _: &gltf::Buffer) -> &[u8] {
//!         // In a real implementation, the `Source` must provide all the data
//!         // necessary to load the object, and must not fail.
//!         //
//!         // This example meets the above criteria, since it provides all the data
//!         // for the 'Box' sample model, which has exactly one external buffer.
//!         self.0
//!     }
//! }
//!
//! let buffer_data = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/examples/Box0.bin"));
//! let data = BoxExampleData(buffer_data);
//! let loaded_gltf = gltf.loaded(&data);
//! for mesh in loaded_gltf.meshes() {
//!     for primitive in mesh.primitives() {
//!         if let Some(iter) = primitive.indices_u32() {
//!             // Do something with the primitive data.
//!             let indices: Vec<u32> = iter.collect();
//!             println!("{:?}", indices);
//!         }
//!     }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! #    let _ = run().expect("No runtime errors");
//! # }
//! ```

#[macro_use]
extern crate lazy_static;

/// Contains (de)serializable data structures that match the glTF JSON text.
pub extern crate gltf_json as json;

/// Contains `Accessor` and other related data structures.
pub mod accessor;

/// Contains `Animation` and other related data structures.
pub mod animation;

/// Contains `Buffer`, `View`, and other related data structures.
pub mod buffer;

/// Contains `Camera` and other related data structures.
pub mod camera;

/// Contains `Gltf`, and other related data structures.
pub mod gltf;

/// Contains `Image` and other related data structures.
pub mod image;

/// Contains `Material` and other related data structures.
pub mod material;

/// Contains `Mesh` and other related data structures.
pub mod mesh;

/// Contains `Root`.
pub mod root;

/// Contains `Scene`, `Node`, and other related data structures.
pub mod scene;

/// Contains `Skin` and other related data structures.
pub mod skin;

/// Contains `Texture`, `Sampler`, and other related data structures.
pub mod texture;

pub use self::animation::Animation;
pub use self::accessor::Accessor;
pub use self::buffer::Buffer;
pub use self::camera::Camera;
pub use self::gltf::Gltf;
pub use self::image::Image;
pub use self::material::Material;
pub use self::mesh::{Mesh, Primitive};
pub use self::scene::{Node, Scene};
pub use self::skin::Skin;
pub use self::texture::Texture;

/// Represents sources of buffer data.
///
/// The user is expected to implement this trait in order to unlock the abstractions
/// provided by the [`Loaded`] type. The `gltf-importer` crate provides a useable
/// reference implementation.
///
/// [`Loaded`]: struct.Loaded.html
pub trait Source: std::fmt::Debug {
    /// Return the buffer data referenced by the given `Buffer`.
    ///
    /// This method must not fail.
    fn source_buffer(&self, buffer: &Buffer) -> &[u8];
}

/// Wrapper type representing a `glTF` object whose data is immediately ready for
/// use.
#[derive(Clone, Debug)]
pub struct Loaded<'a, T> {
    /// The wrapped item.
    item: T,

    /// The data source for this item and all of its children.
    source: &'a Source,
}

impl<'a, T> std::ops::Deref for Loaded<'a, T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.item
    }
}
<|endoftext|>


<commit_before>trait DOMNode {}
impl<'a, T: DOMNode> DOMNode for &'a T {}

trait DOMLevel {
    type NodeType: DOMNode;
    type ChildrenType: DOMChildren;
}
impl<T: DOMNode> DOMLevel for T {
    type NodeType = T;
    type ChildrenType = ();
}

trait DOMChildrenProcessor {
    type State;
    fn get_processor<T: DOMLevel>() -> fn(&mut Self::State, &T) -> ();
}

trait DOMChildren {
    fn process_all<P: DOMChildrenProcessor>(&self, processor: &mut P::State) -> ();
}
impl DOMChildren for () {
    fn process_all<P: DOMChildrenProcessor>(&self, _processor: &mut P::State) -> () {}
}

// Credit to @shepmaster for structure of recursive tuple macro
macro_rules! tuple_impls {
    () => {};

    // Copywrite @shepmaster
    (($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
        /*
         * Invoke recursive reversal of list that ends in the macro expansion implementation
         * of the reversed list
        */
        tuple_impls!([($idx, $typ);] $( ($nidx => $ntyp), )*);
        tuple_impls!($( ($nidx => $ntyp), )*); // invoke macro on tail
    };

    /*
     * ([accumulatedList], listToReverse); recursively calls tuple_impls until the list to reverse
     + is empty (see next pattern)
    */
    ([$(($accIdx: tt, $accTyp: ident);)+]  ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
      tuple_impls!([($idx, $typ); $(($accIdx, $accTyp); )*] $( ($nidx => $ntyp), ) *);
    };

    // Finally expand into the implementation
    ([($idx:tt, $typ:ident); $( ($nidx:tt, $ntyp:ident); )*]) => {
        impl<$typ, $( $ntyp ),*> DOMChildren for ($typ, $( $ntyp ),*)
            where $typ: DOMLevel + Copy,
                  $( $ntyp: DOMLevel + Copy ),*
        {
            fn process_all<P>(&self, state: &mut P::State) -> ()
                    where P: DOMChildrenProcessor {
                P::get_processor()(state, &self.$idx);
                $(
                    P::get_processor()(state, &self.$nidx);
                )*
            }
        }
    }
}

tuple_impls!(
    (9 => J),
    (8 => I),
    (7 => H),
    (6 => G),
    (5 => F),
    (4 => E),
    (3 => D),
    (2 => C),
    (1 => B),
    (0 => A),
);

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

    #[derive(Copy, Clone)]
    struct BogusOne;
    impl DOMNode for BogusOne {}

    struct BogusTwo;
    impl DOMNode for BogusTwo {}

    struct ChildCounter;
    impl DOMChildrenProcessor for ChildCounter {
        type State = usize;

        fn get_processor<T: DOMLevel>() -> fn(&mut Self::State, &T) -> () {
            fn incr<T: DOMLevel>(state: &mut usize, _level: &T) {
                *state += 1;
            }
            incr
        }
    }

    #[test]
    fn counts_children() {
        let mut count = 0;
        (BogusOne, &BogusOne, &BogusTwo).process_all::<ChildCounter>(&mut count);
        assert_eq!(3, count);
    }
}
<commit_msg>Add support for arrays and recursive child structures<commit_after>trait DOMNode {}
impl<'a, T: DOMNode> DOMNode for &'a T {}

trait DOMLevel {
    type NodeType: DOMNode;
    type ChildrenType: DOMChildren;
}
impl<T: DOMNode> DOMLevel for T {
    type NodeType = T;
    type ChildrenType = ();
}

/// Processor that can fold over all the members of a `DOMLevel`
trait DOMChildrenProcessor {
    /// Accumulator
    type Acc;

    /// Folding function
    fn get_processor<T: DOMChildren>() -> fn(&mut Self::Acc, &T) -> ();
}

trait DOMChildren {
    fn process_all<P: DOMChildrenProcessor>(&self, acc: &mut P::Acc) -> ();
}

impl DOMChildren for () {
    fn process_all<P: DOMChildrenProcessor>(&self, _acc: &mut P::Acc) -> () {}
}

impl<T: DOMLevel> DOMChildren for T {
    fn process_all<P: DOMChildrenProcessor>(&self, acc: &mut P::Acc) -> () {
        P::get_processor()(acc, self);
    }
}

impl<T: DOMChildren> DOMChildren for [T] {
    fn process_all<P: DOMChildrenProcessor>(&self, acc: &mut P::Acc) -> () {
        for x in self {
            x.process_all::<P>(acc);
        }
    }
}

macro_rules! array_impls {
    ($($len:expr,)*) => { $(
        impl<T: DOMChildren> DOMChildren for [T; $len] {
            fn process_all<P: DOMChildrenProcessor>(&self, acc: &mut P::Acc) -> () {
                for x in self {
                    x.process_all::<P>(acc);
                }
            }
        }
    )* }
}

array_impls!(
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
);

// Credit to @shepmaster for structure of recursive tuple macro
macro_rules! tuple_impls {
    () => {};

    // Copywrite @shepmaster
    (($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
        /*
         * Invoke recursive reversal of list that ends in the macro expansion implementation
         * of the reversed list
        */
        tuple_impls!([($idx, $typ);] $( ($nidx => $ntyp), )*);
        tuple_impls!($( ($nidx => $ntyp), )*); // invoke macro on tail
    };

    /*
     * ([accumulatedList], listToReverse); recursively calls tuple_impls until the list to reverse
     + is empty (see next pattern)
    */
    ([$(($accIdx: tt, $accTyp: ident);)+]  ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
      tuple_impls!([($idx, $typ); $(($accIdx, $accTyp); )*] $( ($nidx => $ntyp), ) *);
    };

    // Finally expand into the implementation
    ([($idx:tt, $typ:ident); $( ($nidx:tt, $ntyp:ident); )*]) => {
        impl<$typ, $( $ntyp ),*> DOMChildren for ($typ, $( $ntyp ),*)
            where $typ: DOMChildren + Copy,
                  $( $ntyp: DOMChildren + Copy ),*
        {
            fn process_all<P>(&self, acc: &mut P::Acc) -> ()
                    where P: DOMChildrenProcessor {
                &self.$idx.process_all::<P>(acc);
                $(
                    &self.$nidx.process_all::<P>(acc);
                )*
            }
        }
    }
}

tuple_impls!(
    (9 => J),
    (8 => I),
    (7 => H),
    (6 => G),
    (5 => F),
    (4 => E),
    (3 => D),
    (2 => C),
    (1 => B),
    (0 => A),
);

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

    #[derive(Copy, Clone)]
    struct BogusOne;
    impl DOMNode for BogusOne {}

    struct BogusTwo;
    impl DOMNode for BogusTwo {}

    struct ChildCounter;
    impl DOMChildrenProcessor for ChildCounter {
        type Acc = usize;

        fn get_processor<T: DOMChildren>() -> fn(&mut Self::Acc, &T) -> () {
            fn incr<T: DOMChildren>(state: &mut usize, _level: &T) {
                *state += 1;
            }
            incr
        }
    }

    #[test]
    fn counts_children() {
        let mut count = 0;
        (BogusOne, &BogusOne, &BogusTwo).process_all::<ChildCounter>(&mut count);
        assert_eq!(3, count);

        count = 0;
        (BogusOne, (BogusOne,), BogusOne).process_all::<ChildCounter>(&mut count);
        assert_eq!(3, count);

        count = 0;
        [BogusOne, BogusOne, BogusOne].process_all::<ChildCounter>(&mut count);
        assert_eq!(3, count);

        count = 0;
        (BogusOne, BogusOne,
            [BogusOne, BogusOne, BogusOne],
            [(BogusOne)],
            [(), (), ()],
            [&BogusTwo, &BogusTwo, &BogusTwo],
        ).process_all::<ChildCounter>(&mut count);
        assert_eq!(9, count);
    }
}
<|endoftext|>


<commit_before>#![feature(net)]
extern crate time;
extern crate byteorder;

mod ntp;

use std::net::{UdpSocket, lookup_host, SocketAddr};
use time::Timespec;

const NTP_PORT: u16 = 123;
const UDP_LOCAL: &'static str = "0.0.0.0:35000";

/// `retrieve_ntp_timestamp` retrieves the current time from a NTP server.
///
/// # Arguments
///
/// * `host` - The NTP server (i.e. sundial.columbia.edu).
pub fn retrieve_ntp_timestamp(host: &str) -> Result<Timespec, std::io::Error> {
    let host = try!(lookup_host(host)).next().unwrap();
    let addr = SocketAddr::new(try!(host).ip(), NTP_PORT);
    let header = ntp::NTPHeader::new();
    let message = header.encode();

    let socket = try!(UdpSocket::bind(UDP_LOCAL));

    try!(socket.send_to(&message[..], &addr));

    let mut buf = [0u8; 1000];

    // TODO: Rust doesn't support timeouts yet
    let (amt, _) = try!(socket.recv_from(buf.as_mut_slice()));

    drop(socket);

    let header = ntp::NTPHeader::decode(amt, &buf);

    Ok(header.transmit_timestamp.as_timespec())
}

#[test]
fn receive_timestamp() {
    const NTP_SERVER: &'static str = "sundial.columbia.edu";

    let t1 = retrieve_ntp_timestamp(NTP_SERVER).unwrap();
    let t2 = retrieve_ntp_timestamp(NTP_SERVER).unwrap();

    assert!(t2 > t1);
}
<commit_msg>Fixes after stabilization of std::net<commit_after>extern crate time;
extern crate byteorder;

mod ntp;

use std::net::{UdpSocket};
use time::Timespec;

const NTP_PORT: u16 = 123;
const UDP_LOCAL: &'static str = "0.0.0.0:35000";

/// `retrieve_ntp_timestamp` retrieves the current time from a NTP server.
///
/// # Arguments
///
/// * `host` - The NTP server (i.e. sundial.columbia.edu).
pub fn retrieve_ntp_timestamp(host: &str) -> Result<Timespec, std::io::Error> {
    let header = ntp::NTPHeader::new();
    let message = header.encode();

    let socket = try!(UdpSocket::bind(UDP_LOCAL));

    let host = format!("{host}:{port}", host=host, port=NTP_PORT);
    try!(socket.send_to(&message[..], &host[..]));

    let mut buf = [0u8; 1000];

    // TODO: Rust doesn't support timeouts yet
    let (amt, _) = try!(socket.recv_from(buf.as_mut_slice()));

    drop(socket);

    let header = ntp::NTPHeader::decode(amt, &buf);

    Ok(header.transmit_timestamp.as_timespec())
}

#[test]
fn receive_timestamp() {
    const NTP_SERVER: &'static str = "sundial.columbia.edu";

    let t1 = retrieve_ntp_timestamp(NTP_SERVER).unwrap();
    let t2 = retrieve_ntp_timestamp(NTP_SERVER).unwrap();

    assert!(t2 > t1);
}
<|endoftext|>


<commit_before>// Copyright 2015 Dawid Ciężarkiewicz <dpc@dpc.pw>
// See LICENSE-MPL2 file for more information.

//! Coroutine-based handler library for mio
//!
//! Using coroutines, an event-based mio model can be simplified to a set of routines, seamlessly
//! scheduled on demand in userspace.
//!
//! With `mioco` a coroutines can be used to simplify writing asynchronous io handilng in
//! synchronous fashion.

#![feature(result_expect)]
#![warn(missing_docs)]

extern crate mio;
extern crate coroutine;
extern crate nix;

use std::cell::RefCell;
use std::rc::Rc;
use mio::{TryRead, TryWrite, Evented, Token, Handler, EventLoop};

/// State of `mioco` coroutine
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum State {
    BlockedOnWrite(Token),
    BlockedOnRead(Token),
    Running,
    Finished,
}

impl State {
    /// What is the `mio::Interest` for a given `token` at the current state
    fn to_interest_for(&self, token : mio::Token) -> mio::Interest {
        match *self {
            State::Running => panic!("wrong state"),
            State::BlockedOnRead(blocked_token) => if token == blocked_token {
                mio::Interest::readable()
            }
            else {
                mio::Interest::none()
            },
            State::BlockedOnWrite(blocked_token) => if token == blocked_token {
                mio::Interest::writable()
            } else {
                mio::Interest::none()
            },
            State::Finished => mio::Interest::hup(),
        }
    }
}

/// `mioco` can work on any type implementing this trait
pub trait ReadWrite : TryRead+TryWrite+std::io::Read+std::io::Write+Evented { }

impl<T> ReadWrite for T where T: TryRead+TryWrite+std::io::Read+std::io::Write+Evented {}

/// `mioco` coroutine
///
/// Referenced by IO running within it.
struct Coroutine {
    /// Coroutine of Coroutine itself. Stored here so it's available
    /// through every handle and `Coroutine` itself without referencing
    /// back
    pub state : State,
    coroutine : Option<coroutine::coroutine::Handle>,
}

/// Wrapped mio IO (Evented+TryRead+TryWrite)
///
/// `Handle` is just a cloneable reference to this struct
struct IO<T>
where T : ReadWrite {
    coroutine: Rc<RefCell<Coroutine>>,
    token: Token,
    io : T,
    interest: mio::Interest,
    peer_hup: bool,
}

impl<T> IO<T>
where T : ReadWrite {

    /// Handle `hup` condition
    fn hup<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token)
        where H : Handler {
            if self.interest == mio::Interest::hup() {
                self.interest = mio::Interest::none();
                event_loop.deregister(&self.io).ok().expect("deregister() failed");
            } else {
                self.peer_hup = true;
                self.reregister(event_loop, token)
            }
        }

    /// Reregister oneshot handler for the next event
    fn reregister<H>(&mut self, event_loop: &mut EventLoop<H>, token : Token)
        where H : Handler {

            self.interest = self.coroutine.borrow().state.to_interest_for(token) ;

            event_loop.reregister(
                &self.io, token,
                self.interest, mio::PollOpt::edge() | mio::PollOpt::oneshot()
                ).ok().expect("reregister failed")
        }
}

/* BUG: We can guarantee that only one coroutine is running at the time so no concurrent accesses
 * are possible, but user can clone Handle and give to different threads. Boo. */
unsafe impl<T> Send for Handle<T>
where T : ReadWrite { }

// Same as above?
unsafe impl Send for RefCoroutine { }

/// `mioco` wrapper over io associated with a given coroutine.
///
/// Create using `Builder`.
///
/// It implements standard library `Read` and `Write` traits that will
/// take care of blocking and unblocking coroutine when needed. Use this
/// from within `mioco` coroutine only, otherwise misbehaviour is ensured.
///
/// It implements `readable` and `writable`, modeled like original `mio::Handler`
/// methods. Call these from respective `mio::Handler`.
pub struct Handle<T>
where T : ReadWrite {
    inn : Rc<RefCell<IO<T>>>,
}

impl<T> Clone for Handle<T>
where T : ReadWrite {
    fn clone(&self) -> Handle<T> {
        Handle {
            inn: self.inn.clone()
        }
    }
}

impl<T> Handle<T>
where T : ReadWrite {

    /// Is this IO finished and free to be removed
    /// as no more events will be reported for it
    pub fn is_finished(&self) -> bool {
        let co = &self.inn.borrow().coroutine;
        let co_b = co.borrow();
        co_b.state == State::Finished && self.inn.borrow().interest == mio::Interest::none()
    }

    /// Readable event handler
    ///
    /// This corresponds to `mio::Hnalder::readable()`.
    pub fn readable<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token, hint: mio::ReadHint)
    where H : Handler {

        if hint.is_hup() {
            let mut inn = self.inn.borrow_mut();
            inn.hup(event_loop, token);
            return;
        }

        let state = {
            let co = &self.inn.borrow().coroutine;
            let co_b = co.borrow();
            co_b.state
        };

        if let State::BlockedOnRead(blocked_token) = state {
            if token == blocked_token {
                let handle = {
                    let inn = self.inn.borrow();
                    let coroutine_handle = inn.coroutine.borrow().coroutine.as_ref().map(|c| c.clone()).unwrap();
                    inn.coroutine.borrow_mut().state = State::Running;
                    coroutine_handle
                };
                handle.resume().ok().expect("resume() failed");
            }

            let mut inn = self.inn.borrow_mut();
            inn.reregister(event_loop, token)
        } else if let State::BlockedOnWrite(blocked_token) = state {
            if token == blocked_token {
                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }
        }

    }

    /// Readable event handler
    ///
    /// This corresponds to `mio::Hnalder::writable()`.
    pub fn writable<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token)
    where H : Handler {

        let state = {
            let co = &self.inn.borrow().coroutine;
            let co_b = co.borrow();
            co_b.state
        };

        if let State::BlockedOnWrite(blocked_token) = state {
            if token == blocked_token {
                let handle = {
                    let inn = self.inn.borrow();
                    let coroutine_handle = inn.coroutine.borrow().coroutine.as_ref().map(|c| c.clone()).unwrap();
                    inn.coroutine.borrow_mut().state = State::Running;
                    coroutine_handle
                };
                handle.resume().ok().expect("resume() failed");

                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }

        } else if let State::BlockedOnRead(blocked_token) = state {
            if token == blocked_token {
                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }
        }
    }
}

impl<T> std::io::Read for Handle<T>
where T : ReadWrite {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        loop {
            let res = self.inn.borrow_mut().io.try_read(buf);
            match res {
                Ok(None) => {
                    {
                        let inn = self.inn.borrow();
                        inn.coroutine.borrow_mut().state = State::BlockedOnRead(inn.token);
                    }
                    coroutine::Coroutine::block();
                },
                Ok(Some(r))  => {
                    return Ok(r);
                },
                Err(e) => {
                    return Err(e)
                }
            }
        }
    }
}

impl<T> std::io::Write for Handle<T>
where T: ReadWrite {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        loop {
            let res = self.inn.borrow_mut().io.try_write(buf) ;
            match res {
                Ok(None) => {
                    {
                        let inn = self.inn.borrow();
                        inn.coroutine.borrow_mut().state = State::BlockedOnWrite(inn.token);
                    }
                    coroutine::Coroutine::block();
                },
                Ok(Some(r)) => {
                    return Ok(r);
                },
                Err(e) => {
                    return Err(e)
                }
            }
        }
    }

    /* TODO: Should we pass flush to TcpStream/ignore? */
    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}

/// `mioco` coroutine builder
///
/// Create one with `new`, then use `wrap_io` on io that you are going to use in the coroutine
/// that you spawn with `start`.
pub struct Builder {
    coroutine: Rc<RefCell<Coroutine>>,
}

struct RefCoroutine {
    coroutine: Rc<RefCell<Coroutine>>,
}

impl Builder {

    /// Create new Coroutine builder
    pub fn new() -> Builder {
        Builder {
            coroutine: Rc::new(RefCell::new(Coroutine {
                state: State::Running,
                coroutine: None,
            }))
        }
    }

    /// Register `mio`'s io to be used within `mioco` coroutine
    ///
    /// Consumes the `io`, returns a `Handle` to a mio wrapper over it.
    pub fn wrap_io<H, T>(&self, event_loop: &mut mio::EventLoop<H>, io : T, token : Token) -> Handle<T>
    where H : Handler,
    T : ReadWrite {

        event_loop.register_opt(
            &io, token,
            mio::Interest::readable() | mio::Interest::writable(), mio::PollOpt::edge() | mio::PollOpt::oneshot()
            ).expect("register_opt failed");

        Handle {
            inn: Rc::new(RefCell::new(
                     IO {
                         coroutine: self.coroutine.clone(),
                         io: io,
                         token: token,
                         peer_hup: false,
                         interest: mio::Interest::none(),
                     }
                 )),
        }
    }

    /// Create a `mioco` coroutine handler
    ///
    /// `f` is routine handling connection. It should not use any blocking operations,
    /// and use it's argument for all IO with it's peer
    pub fn start<F>(self, f : F)
        where F : FnOnce() + Send + 'static {

            let ioref = RefCoroutine {
                coroutine: self.coroutine.clone(),
            };

            let coroutine_handle = coroutine::coroutine::Coroutine::spawn(move || {
                ioref.coroutine.borrow_mut().coroutine = Some(coroutine::Coroutine::current().clone());
                f();
                ioref.coroutine.borrow_mut().state = State::Finished;
            });

            coroutine_handle.resume().ok().expect("resume() failed");
        }
}
<commit_msg>Add `with_raw` and `with_raw_mut`.<commit_after>// Copyright 2015 Dawid Ciężarkiewicz <dpc@dpc.pw>
// See LICENSE-MPL2 file for more information.

//! Coroutine-based handler library for mio
//!
//! Using coroutines, an event-based mio model can be simplified to a set of routines, seamlessly
//! scheduled on demand in userspace.
//!
//! With `mioco` a coroutines can be used to simplify writing asynchronous io handilng in
//! synchronous fashion.

#![feature(result_expect)]
#![warn(missing_docs)]

extern crate mio;
extern crate coroutine;
extern crate nix;

use std::cell::RefCell;
use std::rc::Rc;
use mio::{TryRead, TryWrite, Evented, Token, Handler, EventLoop};

/// State of `mioco` coroutine
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum State {
    BlockedOnWrite(Token),
    BlockedOnRead(Token),
    Running,
    Finished,
}

impl State {
    /// What is the `mio::Interest` for a given `token` at the current state
    fn to_interest_for(&self, token : mio::Token) -> mio::Interest {
        match *self {
            State::Running => panic!("wrong state"),
            State::BlockedOnRead(blocked_token) => if token == blocked_token {
                mio::Interest::readable()
            }
            else {
                mio::Interest::none()
            },
            State::BlockedOnWrite(blocked_token) => if token == blocked_token {
                mio::Interest::writable()
            } else {
                mio::Interest::none()
            },
            State::Finished => mio::Interest::hup(),
        }
    }
}

/// `mioco` can work on any type implementing this trait
pub trait ReadWrite : TryRead+TryWrite+std::io::Read+std::io::Write+Evented { }

impl<T> ReadWrite for T where T: TryRead+TryWrite+std::io::Read+std::io::Write+Evented {}

/// `mioco` coroutine
///
/// Referenced by IO running within it.
struct Coroutine {
    /// Coroutine of Coroutine itself. Stored here so it's available
    /// through every handle and `Coroutine` itself without referencing
    /// back
    pub state : State,
    coroutine : Option<coroutine::coroutine::Handle>,
}

/// Wrapped mio IO (Evented+TryRead+TryWrite)
///
/// `Handle` is just a cloneable reference to this struct
struct IO<T>
where T : ReadWrite {
    coroutine: Rc<RefCell<Coroutine>>,
    token: Token,
    io : T,
    interest: mio::Interest,
    peer_hup: bool,
}

impl<T> IO<T>
where T : ReadWrite {

    /// Handle `hup` condition
    fn hup<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token)
        where H : Handler {
            if self.interest == mio::Interest::hup() {
                self.interest = mio::Interest::none();
                event_loop.deregister(&self.io).ok().expect("deregister() failed");
            } else {
                self.peer_hup = true;
                self.reregister(event_loop, token)
            }
        }

    /// Reregister oneshot handler for the next event
    fn reregister<H>(&mut self, event_loop: &mut EventLoop<H>, token : Token)
        where H : Handler {

            self.interest = self.coroutine.borrow().state.to_interest_for(token) ;

            event_loop.reregister(
                &self.io, token,
                self.interest, mio::PollOpt::edge() | mio::PollOpt::oneshot()
                ).ok().expect("reregister failed")
        }
}

/* BUG: We can guarantee that only one coroutine is running at the time so no concurrent accesses
 * are possible, but user can clone Handle and give to different threads. Boo. */
unsafe impl<T> Send for Handle<T>
where T : ReadWrite { }

// Same as above?
unsafe impl Send for RefCoroutine { }

/// `mioco` wrapper over io associated with a given coroutine.
///
/// Create using `Builder`.
///
/// It implements standard library `Read` and `Write` traits that will
/// take care of blocking and unblocking coroutine when needed. Use this
/// from within `mioco` coroutine only, otherwise misbehaviour is ensured.
///
/// It implements `readable` and `writable`, modeled like original `mio::Handler`
/// methods. Call these from respective `mio::Handler`.
pub struct Handle<T>
where T : ReadWrite {
    inn : Rc<RefCell<IO<T>>>,
}

impl<T> Clone for Handle<T>
where T : ReadWrite {
    fn clone(&self) -> Handle<T> {
        Handle {
            inn: self.inn.clone()
        }
    }
}

impl<T> Handle<T>
where T : ReadWrite {

    /// Is this IO finished and free to be removed
    /// as no more events will be reported for it
    pub fn is_finished(&self) -> bool {
        let co = &self.inn.borrow().coroutine;
        let co_b = co.borrow();
        co_b.state == State::Finished && self.inn.borrow().interest == mio::Interest::none()
    }

    /// Access the wrapped IO
    pub fn with_raw<F>(&self, f : F)
        where F : Fn(&T) {
        let io = &self.inn.borrow().io;
        f(io)
    }

    /// Access the wrapped IO as mutable
    pub fn with_raw_mut<F>(&mut self, f : F)
        where F : Fn(&mut T) {
        let mut io = &mut self.inn.borrow_mut().io;
        f(&mut io)
    }

    /// Readable event handler
    ///
    /// This corresponds to `mio::Hnalder::readable()`.
    pub fn readable<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token, hint: mio::ReadHint)
    where H : Handler {

        if hint.is_hup() {
            let mut inn = self.inn.borrow_mut();
            inn.hup(event_loop, token);
            return;
        }

        let state = {
            let co = &self.inn.borrow().coroutine;
            let co_b = co.borrow();
            co_b.state
        };

        if let State::BlockedOnRead(blocked_token) = state {
            if token == blocked_token {
                let handle = {
                    let inn = self.inn.borrow();
                    let coroutine_handle = inn.coroutine.borrow().coroutine.as_ref().map(|c| c.clone()).unwrap();
                    inn.coroutine.borrow_mut().state = State::Running;
                    coroutine_handle
                };
                handle.resume().ok().expect("resume() failed");
            }

            let mut inn = self.inn.borrow_mut();
            inn.reregister(event_loop, token)
        } else if let State::BlockedOnWrite(blocked_token) = state {
            if token == blocked_token {
                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }
        }

    }

    /// Readable event handler
    ///
    /// This corresponds to `mio::Hnalder::writable()`.
    pub fn writable<H>(&mut self, event_loop: &mut EventLoop<H>, token: Token)
    where H : Handler {

        let state = {
            let co = &self.inn.borrow().coroutine;
            let co_b = co.borrow();
            co_b.state
        };

        if let State::BlockedOnWrite(blocked_token) = state {
            if token == blocked_token {
                let handle = {
                    let inn = self.inn.borrow();
                    let coroutine_handle = inn.coroutine.borrow().coroutine.as_ref().map(|c| c.clone()).unwrap();
                    inn.coroutine.borrow_mut().state = State::Running;
                    coroutine_handle
                };
                handle.resume().ok().expect("resume() failed");

                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }

        } else if let State::BlockedOnRead(blocked_token) = state {
            if token == blocked_token {
                let mut inn = self.inn.borrow_mut();
                inn.reregister(event_loop, token)
            }
        }
    }
}

impl<T> std::io::Read for Handle<T>
where T : ReadWrite {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        loop {
            let res = self.inn.borrow_mut().io.try_read(buf);
            match res {
                Ok(None) => {
                    {
                        let inn = self.inn.borrow();
                        inn.coroutine.borrow_mut().state = State::BlockedOnRead(inn.token);
                    }
                    coroutine::Coroutine::block();
                },
                Ok(Some(r))  => {
                    return Ok(r);
                },
                Err(e) => {
                    return Err(e)
                }
            }
        }
    }
}

impl<T> std::io::Write for Handle<T>
where T: ReadWrite {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        loop {
            let res = self.inn.borrow_mut().io.try_write(buf) ;
            match res {
                Ok(None) => {
                    {
                        let inn = self.inn.borrow();
                        inn.coroutine.borrow_mut().state = State::BlockedOnWrite(inn.token);
                    }
                    coroutine::Coroutine::block();
                },
                Ok(Some(r)) => {
                    return Ok(r);
                },
                Err(e) => {
                    return Err(e)
                }
            }
        }
    }

    /* TODO: Should we pass flush to TcpStream/ignore? */
    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}

/// `mioco` coroutine builder
///
/// Create one with `new`, then use `wrap_io` on io that you are going to use in the coroutine
/// that you spawn with `start`.
pub struct Builder {
    coroutine: Rc<RefCell<Coroutine>>,
}

struct RefCoroutine {
    coroutine: Rc<RefCell<Coroutine>>,
}

impl Builder {

    /// Create new Coroutine builder
    pub fn new() -> Builder {
        Builder {
            coroutine: Rc::new(RefCell::new(Coroutine {
                state: State::Running,
                coroutine: None,
            }))
        }
    }

    /// Register `mio`'s io to be used within `mioco` coroutine
    ///
    /// Consumes the `io`, returns a `Handle` to a mio wrapper over it.
    pub fn wrap_io<H, T>(&self, event_loop: &mut mio::EventLoop<H>, io : T, token : Token) -> Handle<T>
    where H : Handler,
    T : ReadWrite {

        event_loop.register_opt(
            &io, token,
            mio::Interest::readable() | mio::Interest::writable(), mio::PollOpt::edge() | mio::PollOpt::oneshot()
            ).expect("register_opt failed");

        Handle {
            inn: Rc::new(RefCell::new(
                     IO {
                         coroutine: self.coroutine.clone(),
                         io: io,
                         token: token,
                         peer_hup: false,
                         interest: mio::Interest::none(),
                     }
                 )),
        }
    }

    /// Create a `mioco` coroutine handler
    ///
    /// `f` is routine handling connection. It should not use any blocking operations,
    /// and use it's argument for all IO with it's peer
    pub fn start<F>(self, f : F)
        where F : FnOnce() + Send + 'static {

            let ioref = RefCoroutine {
                coroutine: self.coroutine.clone(),
            };

            let coroutine_handle = coroutine::coroutine::Coroutine::spawn(move || {
                ioref.coroutine.borrow_mut().coroutine = Some(coroutine::Coroutine::current().clone());
                f();
                ioref.coroutine.borrow_mut().state = State::Finished;
            });

            coroutine_handle.resume().ok().expect("resume() failed");
        }
}
<|endoftext|>


<commit_before>//! A generic connection pool.
//!
//! Opening a new database connection every time one is needed is both
//! inefficient and can lead to resource exhaustion under high traffic
//! conditions. A connection pool maintains a set of open connections to a
//! database, handing them out for repeated use.
//!
//! r2d2 is agnostic to the connection type it is managing. Implementors of the
//! `ManageConnection` trait provide the database-specific logic to create and
//! check the health of connections.
//!
//! # Example
//!
//! Using an imaginary "foodb" database.
//!
//! ```rust,ignore
//! use std::thread;
//!
//! extern crate r2d2;
//! extern crate r2d2_foodb;
//!
//! fn main() {
//!     let config = r2d2::Config::builder()
//!         .error_handler(Box::new(r2d2::LoggingErrorHandler))
//!         .build();
//!     let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
//!
//!     let pool = r2d2::Pool::new(config, manager).unwrap();
//!
//!     for _ in 0..20i32 {
//!         let pool = pool.clone();
//!         thread::spawn(move || {
//!             let conn = pool.get().unwrap();
//!             // use the connection
//!             // it will be returned to the pool when it falls out of scope.
//!         })
//!     }
//! }
//! ```
#![warn(missing_docs)]
#![doc(html_root_url="https://sfackler.github.io/r2d2/doc/v0.6.1")]

#[macro_use]
extern crate log;
extern crate time;

use std::collections::VecDeque;
use std::error::Error;
use std::fmt;
use std::ops::{Deref, DerefMut};
use std::mem;
use std::sync::{Arc, Mutex, Condvar};
use time::{Duration, SteadyTime};

#[doc(inline)]
pub use config::Config;

use task::ScheduledThreadPool;

pub mod config;
mod task;
mod thunk;

/// A trait which provides connection-specific functionality.
pub trait ManageConnection: Send + Sync + 'static {
    /// The connection type this manager deals with.
    type Connection: Send + 'static;

    /// The error type returned by `Connection`s.
    type Error: 'static;

    /// Attempts to create a new connection.
    fn connect(&self) -> Result<Self::Connection, Self::Error>;

    /// Determines if the connection is still connected to the database.
    ///
    /// A standard implementation would check if a simple query like `SELECT 1`
    /// succeeds.
    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error>;

    /// *Quickly* determines if the connection is no longer usable.
    ///
    /// This will be called synchronously every time a connection is returned
    /// to the pool, so it should *not* block. If it returns `true`, the
    /// connection will be discarded.
    ///
    /// For example, an implementation might check if the underlying TCP socket
    /// has disconnected. Implementations that do not support this kind of
    /// fast health check may simply return `false`.
    fn has_broken(&self, conn: &mut Self::Connection) -> bool;
}

/// A trait which handles errors reported by the `ManageConnection`.
pub trait HandleError<E>: Send+Sync+'static {
    /// Handles an error.
    fn handle_error(&self, error: E);
}

/// A `HandleError` implementation which does nothing.
#[derive(Copy, Clone, Debug)]
pub struct NopErrorHandler;

impl<E> HandleError<E> for NopErrorHandler {
    fn handle_error(&self, _: E) {}
}

/// A `HandleError` implementation which logs at the error level.
#[derive(Copy, Clone, Debug)]
pub struct LoggingErrorHandler;

impl<E> HandleError<E> for LoggingErrorHandler where E: Error {
    fn handle_error(&self, error: E) {
        error!("{}", error);
    }
}

/// A trait which allows for customization of connections.
pub trait CustomizeConnection<C, E>: Send+Sync+'static {
    /// Called with connections immediately after they are returned from
    /// `ManageConnection::connect`.
    ///
    /// The default implementation simply returns `Ok(())`.
    ///
    /// # Errors
    ///
    /// If this method returns an error, the connection will be discarded.
    #[allow(unused_variables)]
    fn on_acquire(&self, conn: &mut C) -> Result<(), E> {
        Ok(())
    }
}

/// A `CustomizeConnection` which does nothing.
#[derive(Copy, Clone, Debug)]
pub struct NopConnectionCustomizer;

impl<C, E> CustomizeConnection<C, E> for NopConnectionCustomizer {}

struct Conn<C> {
    conn: C,
    birth: SteadyTime,
    idle_start: SteadyTime,
}

impl<C> Conn<C> {
    fn new(conn: C) -> Conn<C> {
        Conn {
            conn: conn,
            birth: SteadyTime::now(),
            idle_start: SteadyTime::now(),
        }
    }
}

struct PoolInternals<C> {
    conns: VecDeque<Conn<C>>,
    num_conns: u32,
    pending_conns: u32,
}

struct SharedPool<M> where M: ManageConnection {
    config: Config<M::Connection, M::Error>,
    manager: M,
    internals: Mutex<PoolInternals<M::Connection>>,
    cond: Condvar,
    thread_pool: ScheduledThreadPool,
}

fn drop_conn<M>(shared: &Arc<SharedPool<M>>,
                internals: &mut PoolInternals<M::Connection>)
        where M: ManageConnection
{
    internals.num_conns -= 1;

    let min = shared.config.min_idle().unwrap_or(shared.config.pool_size());
    if internals.num_conns + internals.pending_conns < min {
        add_connection(shared, internals);
    }
}

fn add_connection<M>(shared: &Arc<SharedPool<M>>,
                     internals: &mut PoolInternals<M::Connection>)
    where M: ManageConnection
{
    internals.pending_conns += 1;
    inner(Duration::zero(), shared);

    fn inner<M>(delay: Duration, shared: &Arc<SharedPool<M>>) where M: ManageConnection {
        let new_shared = shared.clone();
        shared.thread_pool.run_after(delay, move || {
            let shared = new_shared;
            let conn = shared.manager.connect().and_then(|mut conn| {
                shared.config.connection_customizer().on_acquire(&mut conn).map(|_| conn)
            });
            match conn {
                Ok(conn) => {
                    let mut internals = shared.internals.lock().unwrap();
                    internals.conns.push_back(Conn::new(conn));
                    internals.pending_conns -= 1;
                    internals.num_conns += 1;
                    shared.cond.notify_one();
                }
                Err(err) => {
                    shared.config.error_handler().handle_error(err);
                    inner(Duration::seconds(1), &shared);
                },
            }
        });
    }
}

fn reap_connections<M>(shared: &Arc<SharedPool<M>>) where M: ManageConnection {
    let mut old = VecDeque::with_capacity(shared.config.pool_size() as usize);
    let mut to_drop = vec![];

    let mut internals = shared.internals.lock().unwrap();
    mem::swap(&mut old, &mut internals.conns);
    let now = SteadyTime::now();
    for conn in old {
        let mut reap = false;
        if let Some(timeout) = shared.config.idle_timeout() {
            reap |= now - conn.idle_start >= cvt(timeout);
        }
        if let Some(lifetime) = shared.config.max_lifetime() {
            reap |= now - conn.birth >= cvt(lifetime);
        }
        if reap {
            drop_conn(shared, &mut internals);
            to_drop.push(conn.conn);
        } else {
            internals.conns.push_back(conn);
        }
    }
    drop(internals); // make sure we run to_drop destructors without this locked
}

/// A generic connection pool.
pub struct Pool<M> where M: ManageConnection {
    shared: Arc<SharedPool<M>>,
}

impl<M> Drop for Pool<M> where M: ManageConnection {
    fn drop(&mut self) {
        self.shared.thread_pool.clear();
    }
}

/// Returns a new `Pool` referencing the same state as `self`.
impl<M> Clone for Pool<M> where M: ManageConnection {
    fn clone(&self) -> Pool<M> {
        Pool {
            shared: self.shared.clone(),
        }
    }
}

impl<M> fmt::Debug for Pool<M> where M: ManageConnection + fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Pool")
            .field("idle_connections", &self.shared.internals.lock().unwrap().conns.len())
            .field("config", &self.shared.config)
            .field("manager", &self.shared.manager)
            .finish()
    }
}

/// An error returned by `Pool::new` if it fails to initialize connections.
#[derive(Debug)]
pub struct InitializationError(());

impl fmt::Display for InitializationError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

impl Error for InitializationError {
    fn description(&self) -> &str {
        "Unable to initialize connections"
    }
}

/// An error returned by `Pool::get` if it times out without retrieving a connection.
#[derive(Debug)]
pub struct GetTimeout(());

impl fmt::Display for GetTimeout {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

impl Error for GetTimeout {
    fn description(&self) -> &str {
        "Timed out while waiting for a connection"
    }
}

impl<M> Pool<M> where M: ManageConnection {
    /// Creates a new connection pool.
    ///
    /// Returns an `Err` value if `initialization_fail_fast` is set to true in
    /// the configuration and the pool is unable to open all of its
    /// connections.
    pub fn new(config: Config<M::Connection, M::Error>, manager: M)
               -> Result<Pool<M>, InitializationError> {
        let internals = PoolInternals {
            conns: VecDeque::with_capacity(config.pool_size() as usize),
            num_conns: 0,
            pending_conns: 0,
        };

        let shared = Arc::new(SharedPool {
            thread_pool: ScheduledThreadPool::new(config.helper_threads() as usize),
            config: config,
            manager: manager,
            internals: Mutex::new(internals),
            cond: Condvar::new(),
        });

        {
            let mut inner = shared.internals.lock().unwrap();
            for _ in 0..shared.config.min_idle().unwrap_or(shared.config.pool_size()) {
                add_connection(&shared, &mut inner);
            }
            drop(inner);
        }

        if shared.config.initialization_fail_fast() {
            let end = SteadyTime::now() + cvt(shared.config.connection_timeout());
            let mut internals = shared.internals.lock().unwrap();

            while internals.num_conns != shared.config.pool_size() {
                let wait = end - SteadyTime::now();
                if wait <= Duration::zero() {
                    return Err(InitializationError(()));
                }
                internals = shared.cond.wait_timeout_ms(internals,
                                                        wait.num_milliseconds() as u32)
                    .unwrap().0;
            }
        }

        if shared.config.max_lifetime().is_some() || shared.config.idle_timeout().is_some() {
            let s = shared.clone();
            shared.thread_pool.run_at_fixed_rate(Duration::seconds(30),
                                                 move || reap_connections(&s));
        }

        Ok(Pool {
            shared: shared,
        })
    }

    fn get_inner(&self) -> Result<Conn<M::Connection>, GetTimeout> {
        let end = SteadyTime::now() + cvt(self.shared.config.connection_timeout());
        let mut internals = self.shared.internals.lock().unwrap();

        loop {
            match internals.conns.pop_front() {
                Some(mut conn) => {
                    drop(internals);

                    if self.shared.config.test_on_check_out() {
                        if let Err(e) = self.shared.manager.is_valid(&mut conn.conn) {
                            self.shared.config.error_handler().handle_error(e);
                            internals = self.shared.internals.lock().unwrap();
                            drop_conn(&self.shared, &mut internals);
                            continue;
                        }
                    }

                    return Ok(conn);
                }
                None => {
                    if internals.num_conns + internals.pending_conns < self.shared.config.pool_size() {
                        add_connection(&self.shared, &mut internals);
                    }

                    let now = SteadyTime::now();
                    let mut timeout = (end - now).num_milliseconds();
                    if timeout < 0 {
                        timeout = 0
                    };
                    let (new_internals, no_timeout) =
                        self.shared.cond.wait_timeout_ms(internals, timeout as u32).unwrap();
                    internals = new_internals;

                    if !no_timeout {
                        return Err(GetTimeout(()));
                    }
                }
            }
        }
    }

    /// Retrieves a connection from the pool.
    ///
    /// Waits for at most `Config::connection_timeout` before returning an
    /// error.
    pub fn get(&self) -> Result<PooledConnection<M>, GetTimeout> {
        Ok(PooledConnection {
            pool: self.clone(),
            conn: Some(try!(self.get_inner())),
        })
    }

    fn put_back(&self, mut conn: Conn<M::Connection>) {
        // This is specified to be fast, but call it before locking anyways
        let broken = self.shared.manager.has_broken(&mut conn.conn);

        let mut internals = self.shared.internals.lock().unwrap();
        if broken {
            drop_conn(&self.shared, &mut internals);
        } else {
            conn.idle_start = SteadyTime::now();
            internals.conns.push_back(conn);
            self.shared.cond.notify_one();
        }
    }
}

/// A smart pointer wrapping a connection.
pub struct PooledConnection<M> where M: ManageConnection {
    pool: Pool<M>,
    conn: Option<Conn<M::Connection>>,
}

impl<M> fmt::Debug for PooledConnection<M>
        where M: ManageConnection + fmt::Debug, M::Connection: fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("PooledConnection")
            .field("pool", &self.pool)
            .field("connection", &self.conn.as_ref().unwrap().conn)
            .finish()
    }
}

impl<M> Drop for PooledConnection<M> where M: ManageConnection {
    fn drop(&mut self) {
        self.pool.put_back(self.conn.take().unwrap());
    }
}

impl<M> Deref for PooledConnection<M> where M: ManageConnection {
    type Target = M::Connection;

    fn deref(&self) -> &M::Connection {
        &self.conn.as_ref().unwrap().conn
    }
}

impl<M> DerefMut for PooledConnection<M> where M: ManageConnection {
    fn deref_mut(&mut self) -> &mut M::Connection {
        &mut self.conn.as_mut().unwrap().conn
    }
}

fn cvt(d: std::time::Duration) -> Duration {
    Duration::seconds(d.as_secs() as i64) + Duration::nanoseconds(d.subsec_nanos() as i64)
}
<commit_msg>Exponentially fall back on connection acquisition<commit_after>//! A generic connection pool.
//!
//! Opening a new database connection every time one is needed is both
//! inefficient and can lead to resource exhaustion under high traffic
//! conditions. A connection pool maintains a set of open connections to a
//! database, handing them out for repeated use.
//!
//! r2d2 is agnostic to the connection type it is managing. Implementors of the
//! `ManageConnection` trait provide the database-specific logic to create and
//! check the health of connections.
//!
//! # Example
//!
//! Using an imaginary "foodb" database.
//!
//! ```rust,ignore
//! use std::thread;
//!
//! extern crate r2d2;
//! extern crate r2d2_foodb;
//!
//! fn main() {
//!     let config = r2d2::Config::builder()
//!         .error_handler(Box::new(r2d2::LoggingErrorHandler))
//!         .build();
//!     let manager = r2d2_foodb::FooConnectionManager::new("localhost:1234");
//!
//!     let pool = r2d2::Pool::new(config, manager).unwrap();
//!
//!     for _ in 0..20i32 {
//!         let pool = pool.clone();
//!         thread::spawn(move || {
//!             let conn = pool.get().unwrap();
//!             // use the connection
//!             // it will be returned to the pool when it falls out of scope.
//!         })
//!     }
//! }
//! ```
#![warn(missing_docs)]
#![doc(html_root_url="https://sfackler.github.io/r2d2/doc/v0.6.1")]

#[macro_use]
extern crate log;
extern crate time;

use std::cmp;
use std::collections::VecDeque;
use std::error::Error;
use std::fmt;
use std::ops::{Deref, DerefMut};
use std::mem;
use std::sync::{Arc, Mutex, Condvar};
use time::{Duration, SteadyTime};

#[doc(inline)]
pub use config::Config;

use task::ScheduledThreadPool;

pub mod config;
mod task;
mod thunk;

/// A trait which provides connection-specific functionality.
pub trait ManageConnection: Send + Sync + 'static {
    /// The connection type this manager deals with.
    type Connection: Send + 'static;

    /// The error type returned by `Connection`s.
    type Error: 'static;

    /// Attempts to create a new connection.
    fn connect(&self) -> Result<Self::Connection, Self::Error>;

    /// Determines if the connection is still connected to the database.
    ///
    /// A standard implementation would check if a simple query like `SELECT 1`
    /// succeeds.
    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error>;

    /// *Quickly* determines if the connection is no longer usable.
    ///
    /// This will be called synchronously every time a connection is returned
    /// to the pool, so it should *not* block. If it returns `true`, the
    /// connection will be discarded.
    ///
    /// For example, an implementation might check if the underlying TCP socket
    /// has disconnected. Implementations that do not support this kind of
    /// fast health check may simply return `false`.
    fn has_broken(&self, conn: &mut Self::Connection) -> bool;
}

/// A trait which handles errors reported by the `ManageConnection`.
pub trait HandleError<E>: Send+Sync+'static {
    /// Handles an error.
    fn handle_error(&self, error: E);
}

/// A `HandleError` implementation which does nothing.
#[derive(Copy, Clone, Debug)]
pub struct NopErrorHandler;

impl<E> HandleError<E> for NopErrorHandler {
    fn handle_error(&self, _: E) {}
}

/// A `HandleError` implementation which logs at the error level.
#[derive(Copy, Clone, Debug)]
pub struct LoggingErrorHandler;

impl<E> HandleError<E> for LoggingErrorHandler where E: Error {
    fn handle_error(&self, error: E) {
        error!("{}", error);
    }
}

/// A trait which allows for customization of connections.
pub trait CustomizeConnection<C, E>: Send+Sync+'static {
    /// Called with connections immediately after they are returned from
    /// `ManageConnection::connect`.
    ///
    /// The default implementation simply returns `Ok(())`.
    ///
    /// # Errors
    ///
    /// If this method returns an error, the connection will be discarded.
    #[allow(unused_variables)]
    fn on_acquire(&self, conn: &mut C) -> Result<(), E> {
        Ok(())
    }
}

/// A `CustomizeConnection` which does nothing.
#[derive(Copy, Clone, Debug)]
pub struct NopConnectionCustomizer;

impl<C, E> CustomizeConnection<C, E> for NopConnectionCustomizer {}

struct Conn<C> {
    conn: C,
    birth: SteadyTime,
    idle_start: SteadyTime,
}

impl<C> Conn<C> {
    fn new(conn: C) -> Conn<C> {
        Conn {
            conn: conn,
            birth: SteadyTime::now(),
            idle_start: SteadyTime::now(),
        }
    }
}

struct PoolInternals<C> {
    conns: VecDeque<Conn<C>>,
    num_conns: u32,
    pending_conns: u32,
}

struct SharedPool<M> where M: ManageConnection {
    config: Config<M::Connection, M::Error>,
    manager: M,
    internals: Mutex<PoolInternals<M::Connection>>,
    cond: Condvar,
    thread_pool: ScheduledThreadPool,
}

fn drop_conn<M>(shared: &Arc<SharedPool<M>>,
                internals: &mut PoolInternals<M::Connection>)
        where M: ManageConnection
{
    internals.num_conns -= 1;

    let min = shared.config.min_idle().unwrap_or(shared.config.pool_size());
    if internals.num_conns + internals.pending_conns < min {
        add_connection(shared, internals);
    }
}

fn add_connection<M>(shared: &Arc<SharedPool<M>>,
                     internals: &mut PoolInternals<M::Connection>)
    where M: ManageConnection
{
    internals.pending_conns += 1;
    inner(Duration::zero(), shared);

    fn inner<M>(delay: Duration, shared: &Arc<SharedPool<M>>) where M: ManageConnection {
        let new_shared = shared.clone();
        shared.thread_pool.run_after(delay, move || {
            let shared = new_shared;
            let conn = shared.manager.connect().and_then(|mut conn| {
                shared.config.connection_customizer().on_acquire(&mut conn).map(|_| conn)
            });
            match conn {
                Ok(conn) => {
                    let mut internals = shared.internals.lock().unwrap();
                    internals.conns.push_back(Conn::new(conn));
                    internals.pending_conns -= 1;
                    internals.num_conns += 1;
                    shared.cond.notify_one();
                }
                Err(err) => {
                    shared.config.error_handler().handle_error(err);
                    let delay = cmp::max(Duration::milliseconds(200), delay);
                    let delay = cmp::min(cvt(shared.config.connection_timeout()) / 2, delay * 2);
                    inner(delay, &shared);
                },
            }
        });
    }
}

fn reap_connections<M>(shared: &Arc<SharedPool<M>>) where M: ManageConnection {
    let mut old = VecDeque::with_capacity(shared.config.pool_size() as usize);
    let mut to_drop = vec![];

    let mut internals = shared.internals.lock().unwrap();
    mem::swap(&mut old, &mut internals.conns);
    let now = SteadyTime::now();
    for conn in old {
        let mut reap = false;
        if let Some(timeout) = shared.config.idle_timeout() {
            reap |= now - conn.idle_start >= cvt(timeout);
        }
        if let Some(lifetime) = shared.config.max_lifetime() {
            reap |= now - conn.birth >= cvt(lifetime);
        }
        if reap {
            drop_conn(shared, &mut internals);
            to_drop.push(conn.conn);
        } else {
            internals.conns.push_back(conn);
        }
    }
    drop(internals); // make sure we run to_drop destructors without this locked
}

/// A generic connection pool.
pub struct Pool<M> where M: ManageConnection {
    shared: Arc<SharedPool<M>>,
}

impl<M> Drop for Pool<M> where M: ManageConnection {
    fn drop(&mut self) {
        self.shared.thread_pool.clear();
    }
}

/// Returns a new `Pool` referencing the same state as `self`.
impl<M> Clone for Pool<M> where M: ManageConnection {
    fn clone(&self) -> Pool<M> {
        Pool {
            shared: self.shared.clone(),
        }
    }
}

impl<M> fmt::Debug for Pool<M> where M: ManageConnection + fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("Pool")
            .field("idle_connections", &self.shared.internals.lock().unwrap().conns.len())
            .field("config", &self.shared.config)
            .field("manager", &self.shared.manager)
            .finish()
    }
}

/// An error returned by `Pool::new` if it fails to initialize connections.
#[derive(Debug)]
pub struct InitializationError(());

impl fmt::Display for InitializationError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

impl Error for InitializationError {
    fn description(&self) -> &str {
        "Unable to initialize connections"
    }
}

/// An error returned by `Pool::get` if it times out without retrieving a connection.
#[derive(Debug)]
pub struct GetTimeout(());

impl fmt::Display for GetTimeout {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

impl Error for GetTimeout {
    fn description(&self) -> &str {
        "Timed out while waiting for a connection"
    }
}

impl<M> Pool<M> where M: ManageConnection {
    /// Creates a new connection pool.
    ///
    /// Returns an `Err` value if `initialization_fail_fast` is set to true in
    /// the configuration and the pool is unable to open all of its
    /// connections.
    pub fn new(config: Config<M::Connection, M::Error>, manager: M)
               -> Result<Pool<M>, InitializationError> {
        let internals = PoolInternals {
            conns: VecDeque::with_capacity(config.pool_size() as usize),
            num_conns: 0,
            pending_conns: 0,
        };

        let shared = Arc::new(SharedPool {
            thread_pool: ScheduledThreadPool::new(config.helper_threads() as usize),
            config: config,
            manager: manager,
            internals: Mutex::new(internals),
            cond: Condvar::new(),
        });

        {
            let mut inner = shared.internals.lock().unwrap();
            for _ in 0..shared.config.min_idle().unwrap_or(shared.config.pool_size()) {
                add_connection(&shared, &mut inner);
            }
            drop(inner);
        }

        if shared.config.initialization_fail_fast() {
            let end = SteadyTime::now() + cvt(shared.config.connection_timeout());
            let mut internals = shared.internals.lock().unwrap();

            while internals.num_conns != shared.config.pool_size() {
                let wait = end - SteadyTime::now();
                if wait <= Duration::zero() {
                    return Err(InitializationError(()));
                }
                internals = shared.cond.wait_timeout_ms(internals,
                                                        wait.num_milliseconds() as u32)
                    .unwrap().0;
            }
        }

        if shared.config.max_lifetime().is_some() || shared.config.idle_timeout().is_some() {
            let s = shared.clone();
            shared.thread_pool.run_at_fixed_rate(Duration::seconds(30),
                                                 move || reap_connections(&s));
        }

        Ok(Pool {
            shared: shared,
        })
    }

    fn get_inner(&self) -> Result<Conn<M::Connection>, GetTimeout> {
        let end = SteadyTime::now() + cvt(self.shared.config.connection_timeout());
        let mut internals = self.shared.internals.lock().unwrap();

        loop {
            match internals.conns.pop_front() {
                Some(mut conn) => {
                    drop(internals);

                    if self.shared.config.test_on_check_out() {
                        if let Err(e) = self.shared.manager.is_valid(&mut conn.conn) {
                            self.shared.config.error_handler().handle_error(e);
                            internals = self.shared.internals.lock().unwrap();
                            drop_conn(&self.shared, &mut internals);
                            continue;
                        }
                    }

                    return Ok(conn);
                }
                None => {
                    if internals.num_conns + internals.pending_conns < self.shared.config.pool_size() {
                        add_connection(&self.shared, &mut internals);
                    }

                    let now = SteadyTime::now();
                    let mut timeout = (end - now).num_milliseconds();
                    if timeout < 0 {
                        timeout = 0
                    };
                    let (new_internals, no_timeout) =
                        self.shared.cond.wait_timeout_ms(internals, timeout as u32).unwrap();
                    internals = new_internals;

                    if !no_timeout {
                        return Err(GetTimeout(()));
                    }
                }
            }
        }
    }

    /// Retrieves a connection from the pool.
    ///
    /// Waits for at most `Config::connection_timeout` before returning an
    /// error.
    pub fn get(&self) -> Result<PooledConnection<M>, GetTimeout> {
        Ok(PooledConnection {
            pool: self.clone(),
            conn: Some(try!(self.get_inner())),
        })
    }

    fn put_back(&self, mut conn: Conn<M::Connection>) {
        // This is specified to be fast, but call it before locking anyways
        let broken = self.shared.manager.has_broken(&mut conn.conn);

        let mut internals = self.shared.internals.lock().unwrap();
        if broken {
            drop_conn(&self.shared, &mut internals);
        } else {
            conn.idle_start = SteadyTime::now();
            internals.conns.push_back(conn);
            self.shared.cond.notify_one();
        }
    }
}

/// A smart pointer wrapping a connection.
pub struct PooledConnection<M> where M: ManageConnection {
    pool: Pool<M>,
    conn: Option<Conn<M::Connection>>,
}

impl<M> fmt::Debug for PooledConnection<M>
        where M: ManageConnection + fmt::Debug, M::Connection: fmt::Debug {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("PooledConnection")
            .field("pool", &self.pool)
            .field("connection", &self.conn.as_ref().unwrap().conn)
            .finish()
    }
}

impl<M> Drop for PooledConnection<M> where M: ManageConnection {
    fn drop(&mut self) {
        self.pool.put_back(self.conn.take().unwrap());
    }
}

impl<M> Deref for PooledConnection<M> where M: ManageConnection {
    type Target = M::Connection;

    fn deref(&self) -> &M::Connection {
        &self.conn.as_ref().unwrap().conn
    }
}

impl<M> DerefMut for PooledConnection<M> where M: ManageConnection {
    fn deref_mut(&mut self) -> &mut M::Connection {
        &mut self.conn.as_mut().unwrap().conn
    }
}

fn cvt(d: std::time::Duration) -> Duration {
    Duration::seconds(d.as_secs() as i64) + Duration::nanoseconds(d.subsec_nanos() as i64)
}
<|endoftext|>


<commit_before>//! Derive a builder for a struct
//!
//! Use in combination with [custom_derive][custom_derive].
//!
//! [custom_derive]: https://crates.io/crates/custom_derive
//!
//! # Examples
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Debug, PartialEq, Default, Builder)]
//!     struct Lorem {
//!         ipsum: String,
//!         dolor: i32,
//!     }
//! }
//!
//! fn main() {
//!     let x = Lorem::default().ipsum("sit").dolor(42);
//!     assert_eq!(x, Lorem { ipsum: "sit".into(), dolor: 42 });
//! }
//! ```
//!
//! ## Generic structs
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Debug, PartialEq, Default, Builder)]
//!     struct GenLorem<T> {
//!         ipsum: String,
//!         dolor: T,
//!     }
//! }
//!
//! fn main() {
//!     let x = GenLorem::default().ipsum("sit").dolor(42);
//!     assert_eq!(x, GenLorem { ipsum: "sit".into(), dolor: 42 });
//! }
//! ```
//!
//! ## Doc-Comments and Attributes
//!
//! `#[derive(Builder)]` copies doc-comments and attributes `#[...]` from your fields
//! to the according setter-method, if it is one of the following:
//!
//! * `/// ...`
//! * `#[doc = ...]`
//! * `#[cfg(...)]`
//! * `#[allow(...)]`
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Debug, PartialEq, Default, Builder)]
//!     struct Lorem {
//!         /// `ipsum` may be any `String` (be creative).
//!         ipsum: String,
//!         #[doc = r"`dolor` is the estimated amount of work."]
//!         dolor: i32,
//!         // `#[derive(Builder)]` understands conditional compilation via cfg-attributes,
//!         // i.e. => "no field = no setter".
//!         #[cfg(target_os = "macos")]
//!         #[allow(non_snake_case)]
//!         Im_a_Mac: bool,
//!     }
//! }
//!
//! fn main() {
//!     let x = Lorem::default().ipsum("sit").dolor(42);
//!     assert_eq!(x, Lorem { ipsum: "sit".into(), dolor: 42, ..Lorem::default() });
//! }
//! ```
//!
//! ## Gotchas
//!
//! - Tuple structs and unit structs are not supported as they have no field
//!   names.
//! - When defining a generic struct, you cannot use `VALUE` as a generic
//!   parameter as this is what all setters are using.

mod parse_struct;
mod derive_builder;
<commit_msg>fix example<commit_after>//! Derive a builder for a struct
//!
//! Use in combination with [custom_derive][custom_derive].
//!
//! [custom_derive]: https://crates.io/crates/custom_derive
//!
//! # Examples
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Debug, PartialEq, Default, Builder)]
//!     struct Lorem {
//!         ipsum: String,
//!         dolor: i32,
//!     }
//! }
//!
//! fn main() {
//!     let x = Lorem::default().ipsum("sit").dolor(42);
//!     assert_eq!(x, Lorem { ipsum: "sit".into(), dolor: 42 });
//! }
//! ```
//!
//! ## Generic structs
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Debug, PartialEq, Default, Builder)]
//!     struct GenLorem<T> {
//!         ipsum: String,
//!         dolor: T,
//!     }
//! }
//!
//! fn main() {
//!     let x = GenLorem::default().ipsum("sit").dolor(42);
//!     assert_eq!(x, GenLorem { ipsum: "sit".into(), dolor: 42 });
//! }
//! ```
//!
//! ## Doc-Comments and Attributes
//!
//! `#[derive(Builder)]` copies doc-comments and attributes `#[...]` from your fields
//! to the according setter-method, if it is one of the following:
//!
//! * `/// ...`
//! * `#[doc = ...]`
//! * `#[cfg(...)]`
//! * `#[allow(...)]`
//!
//! ```rust
//! #[macro_use] extern crate custom_derive;
//! #[macro_use] extern crate derive_builder;
//!
//! custom_derive!{
//!     #[derive(Builder)]
//!     struct Lorem {
//!         /// `ipsum` may be any `String` (be creative).
//!         ipsum: String,
//!         #[doc = r"`dolor` is the estimated amount of work."]
//!         dolor: i32,
//!         // `#[derive(Builder)]` understands conditional compilation via cfg-attributes,
//!         // i.e. => "no field = no setter".
//!         #[cfg(target_os = "macos")]
//!         #[allow(non_snake_case)]
//!         Im_a_Mac: bool,
//!     }
//! }
//! # fn main() {}
//! ```
//!
//! ## Gotchas
//!
//! - Tuple structs and unit structs are not supported as they have no field
//!   names.
//! - When defining a generic struct, you cannot use `VALUE` as a generic
//!   parameter as this is what all setters are using.

mod parse_struct;
mod derive_builder;
<|endoftext|>


<commit_before>#[macro_use] extern crate log;

use std::net::{TcpListener, TcpStream};
use std::io::{Read};
use std::sync::Arc;
use std::thread;

pub use std::net::{ToSocketAddrs, SocketAddr};

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

#[derive(Debug)]
pub enum HttpError {
    IoError(std::io::Error),
    Utf8Error(std::str::Utf8Error),
}

impl From<std::io::Error> for HttpError {
    fn from(err : std::io::Error) -> HttpError {
        HttpError::IoError(err)
    }
}

impl From<std::str::Utf8Error> for HttpError {
    fn from(err : std::str::Utf8Error) -> HttpError {
        HttpError::Utf8Error(err)
    }
}

/// A HTTP server.
///
/// # Examples
///
/// ```no_run
/// # use self::http2;
/// use http2::{HttpServer, HttpConnection};
///
/// fn handle_connection(con: HttpConnection) {
///   // ...
/// }
///
/// let server = HttpServer::bind("127.0.0.1:80").unwrap();
///
/// // accept connections and process them
/// server.listen(handle_connection);
///
/// // close the http server
/// drop(server);
/// ```
///
#[derive(Debug)]
pub struct HttpServer {
    /// The underlying TCP socket listener
    tcp_listener: TcpListener,
}

impl HttpServer {
    /// Create a new `HttpServer` and bind it to a network address.
    ///
    /// # Arguments
    ///  - `addr` - The address to bind.
    ///
    /// # Failures
    ///  - The given address could not be bound.
    ///
    ///    Reasons for this error include
    ///    - the port already being in use, and
    ///    - the port requiring elevated permissions.
    ///
    pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<HttpServer> {
        let listener = try!(TcpListener::bind(addr));

        // Log address we are listening to
        if let Ok(addr) = listener.local_addr() {
            info!("Listening on address {}", addr);
        }
        else {
            info!("Listening on unknown address");
        }

        Ok(HttpServer { tcp_listener: listener })
    }

    /// Listen for incoming connections.
    ///
    /// A new thread is spawned whenever a connection is established.
    ///
    /// # Arguments
    ///  - `cb` - A callback which is run in a new thread for each connection.
    ///
    /// # Panics
    ///  - A spawned thread could not be joined. (TODO: fix this)
    ///
    pub fn listen<F>(&self, cb: F)
        where F: Fn(&mut HttpConnection) -> (),
              F: 'static + Send + Sync {
        let mut handles = vec![];
        let cb = Arc::new(cb);

        // TODO: there should be a clean way to break out of this loop
        for stream in self.tcp_listener.incoming() {
            match stream {
                Err(err) => error!("Error: {}", err),
                Ok(stream) => {
                    let mut con = HttpConnection::new(stream);
                    let cb = cb.clone();
                    handles.push(thread::spawn(move || cb(&mut con)));
                },
            }
        }

        // Join all spawned threads
        for handle in handles {
            // TODO: proper error handling
            handle.join().unwrap();
        }
    }
}

/// A HTTP request
///
/// TODO: implement this fully
#[derive(Debug)]
pub struct HttpRequest;

/// A HTTP response
///
/// TODO: implement this fully
#[derive(Debug)]
pub struct HttpResponse;

/// A HTTP connection
#[derive(Debug)]
pub struct HttpConnection {
    /// The underlying TCP stream.
    tcp_stream: TcpStream,
}

impl HttpConnection {
    /// Create a new `HttpConnection`
    ///
    /// # Arguments
    ///  - `stream` - The underlying TCP stream.
    fn new(stream: TcpStream) -> HttpConnection {
        HttpConnection { tcp_stream: stream }
    }

    /// The address of the local end of the connection.
    pub fn local_addr(&self) -> Result<SocketAddr> {
        match self.tcp_stream.local_addr() {
            Ok(addr) => Ok(addr),
            Err(err) => Err(HttpError::IoError(err)),
        }
    }

    /// The address of the remote end of the connection.
    pub fn remote_addr(&self) -> Result<SocketAddr> {
        match self.tcp_stream.peer_addr() {
            Ok(addr) => Ok(addr),
            Err(err) => Err(HttpError::IoError(err)),
        }
    }

    /// Block until the next request arrives.
    ///
    /// TODO: parse the request
    pub fn next_request(&mut self) -> Result<HttpRequest> {

        // Block until there is an incoming message and then read it in
        // chunks of BUFSIZE bytes.
        const BUFSIZE : usize = 1024;
        let mut read_buf = [0u8; BUFSIZE];
        let mut accum_buf : Vec<u8> = Vec::with_capacity(BUFSIZE);
        while let Ok(count) = self.tcp_stream.read(&mut read_buf) {
            accum_buf.extend(&read_buf[..count]);
            if count < BUFSIZE { break; }
        }

        let text = try!(std::str::from_utf8(&accum_buf));
        info!("Read message: {:?}", text);

        // TODO: actually parse the request
        Ok(HttpRequest)
    }

    /// Send a response
    pub fn send_response(&self, response: HttpResponse) {
        unimplemented!();
    }
}
<commit_msg>Fixed error in docs example.<commit_after>#[macro_use] extern crate log;

use std::net::{TcpListener, TcpStream};
use std::io::{Read};
use std::sync::Arc;
use std::thread;

pub use std::net::{ToSocketAddrs, SocketAddr};

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

#[derive(Debug)]
pub enum HttpError {
    IoError(std::io::Error),
    Utf8Error(std::str::Utf8Error),
}

impl From<std::io::Error> for HttpError {
    fn from(err : std::io::Error) -> HttpError {
        HttpError::IoError(err)
    }
}

impl From<std::str::Utf8Error> for HttpError {
    fn from(err : std::str::Utf8Error) -> HttpError {
        HttpError::Utf8Error(err)
    }
}

/// A HTTP server.
///
/// # Examples
///
/// ```no_run
/// # use self::http2;
/// use http2::{HttpServer, HttpConnection};
///
/// fn handle_connection(con: &mut HttpConnection) {
///   // ...
/// }
///
/// let server = HttpServer::bind("127.0.0.1:80").unwrap();
///
/// // accept connections and process them
/// server.listen(handle_connection);
///
/// // close the http server
/// drop(server);
/// ```
///
#[derive(Debug)]
pub struct HttpServer {
    /// The underlying TCP socket listener
    tcp_listener: TcpListener,
}

impl HttpServer {
    /// Create a new `HttpServer` and bind it to a network address.
    ///
    /// # Arguments
    ///  - `addr` - The address to bind.
    ///
    /// # Failures
    ///  - The given address could not be bound.
    ///
    ///    Reasons for this error include
    ///    - the port already being in use, and
    ///    - the port requiring elevated permissions.
    ///
    pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<HttpServer> {
        let listener = try!(TcpListener::bind(addr));

        // Log address we are listening to
        if let Ok(addr) = listener.local_addr() {
            info!("Listening on address {}", addr);
        }
        else {
            info!("Listening on unknown address");
        }

        Ok(HttpServer { tcp_listener: listener })
    }

    /// Listen for incoming connections.
    ///
    /// A new thread is spawned whenever a connection is established.
    ///
    /// # Arguments
    ///  - `cb` - A callback which is run in a new thread for each connection.
    ///
    /// # Panics
    ///  - A spawned thread could not be joined. (TODO: fix this)
    ///
    pub fn listen<F>(&self, cb: F)
        where F: Fn(&mut HttpConnection) -> (),
              F: 'static + Send + Sync {
        let mut handles = vec![];
        let cb = Arc::new(cb);

        // TODO: there should be a clean way to break out of this loop
        for stream in self.tcp_listener.incoming() {
            match stream {
                Err(err) => error!("Error: {}", err),
                Ok(stream) => {
                    let mut con = HttpConnection::new(stream);
                    let cb = cb.clone();
                    handles.push(thread::spawn(move || cb(&mut con)));
                },
            }
        }

        // Join all spawned threads
        for handle in handles {
            // TODO: proper error handling
            handle.join().unwrap();
        }
    }
}

/// A HTTP request
///
/// TODO: implement this fully
#[derive(Debug)]
pub struct HttpRequest;

/// A HTTP response
///
/// TODO: implement this fully
#[derive(Debug)]
pub struct HttpResponse;

/// A HTTP connection
#[derive(Debug)]
pub struct HttpConnection {
    /// The underlying TCP stream.
    tcp_stream: TcpStream,
}

impl HttpConnection {
    /// Create a new `HttpConnection`
    ///
    /// # Arguments
    ///  - `stream` - The underlying TCP stream.
    fn new(stream: TcpStream) -> HttpConnection {
        HttpConnection { tcp_stream: stream }
    }

    /// The address of the local end of the connection.
    pub fn local_addr(&self) -> Result<SocketAddr> {
        match self.tcp_stream.local_addr() {
            Ok(addr) => Ok(addr),
            Err(err) => Err(HttpError::IoError(err)),
        }
    }

    /// The address of the remote end of the connection.
    pub fn remote_addr(&self) -> Result<SocketAddr> {
        match self.tcp_stream.peer_addr() {
            Ok(addr) => Ok(addr),
            Err(err) => Err(HttpError::IoError(err)),
        }
    }

    /// Block until the next request arrives.
    ///
    /// TODO: parse the request
    pub fn next_request(&mut self) -> Result<HttpRequest> {

        // Block until there is an incoming message and then read it in
        // chunks of BUFSIZE bytes.
        const BUFSIZE : usize = 1024;
        let mut read_buf = [0u8; BUFSIZE];
        let mut accum_buf : Vec<u8> = Vec::with_capacity(BUFSIZE);
        while let Ok(count) = self.tcp_stream.read(&mut read_buf) {
            accum_buf.extend(&read_buf[..count]);
            if count < BUFSIZE { break; }
        }

        let text = try!(std::str::from_utf8(&accum_buf));
        info!("Read message: {:?}", text);

        // TODO: actually parse the request
        Ok(HttpRequest)
    }

    /// Send a response
    pub fn send_response(&self, response: HttpResponse) {
        unimplemented!();
    }
}
<|endoftext|>


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

//!
//! A library for interning things that are `AsRef<str>`.
//!
//! Some strings may be interned at compile time using the `string-cache-codegen` crate, or the
//! `EmptyStaticAtomSet` may be used that has no compile-time interned strings. An `Atom` is an
//! interned string for a given set (either `EmptyStaticAtomSet` or a generated `StaticAtomSet`).
//!
//! Generated `Atom`s will have assocated macros to intern static strings at compile-time.
//!
//! # Examples
//!
//! Here are two examples, one with compile-time `Atom`s, and one without.
//!
//! ## With compile-time atoms
//!
//! In `Cargo.toml`:
//! ```toml
//! [dependencies]
//! string_cache = "0.8"
//!
//! [dev-dependencies]
//! string_cache_codegen = "0.5"
//! ```
//!
//! In `build.rs`:
//!
//! ```ignore
//! extern crate string_cache_codegen;
//!
//! use std::env;
//! use std::path::Path;
//!
//! fn main() {
//!     string_cache_codegen::AtomType::new("foo::FooAtom", "foo_atom!")
//!         .atoms(&["foo", "bar"])
//!         .write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("foo_atom.rs"))
//!         .unwrap()
//! }
//! ```
//!
//! In `lib.rs`:
//!
//! ```ignore
//! extern crate string_cache;
//!
//! mod foo {
//!     include!(concat!(env!("OUT_DIR"), "/foo_atom.rs"));
//! }
//!
//! fn use_the_atom(t: &str) {
//!     match *t {
//!         foo_atom!("foo") => println!("Found foo!"),
//!         foo_atom!("bar") => println!("Found bar!"),
//!         // foo_atom!("baz") => println!("Found baz!"), - would be a compile time error
//!         _ => {
//!             println!("String not interned");
//!             // We can intern strings at runtime as well
//!             foo::FooAtom::from(t)
//!         }
//!     }
//! }
//! ```
//!
//! ## No compile-time atoms
//!
//! ```
//! # extern crate string_cache;
//! use string_cache::DefaultAtom;
//!
//! # fn main() {
//! let mut interned_stuff = Vec::new();
//! let text = "here is a sentence of text that will be tokenised and
//!             interned and some repeated tokens is of text and";
//! for word in text.split_whitespace() {
//!     let seen_before = interned_stuff.iter()
//!         // We can use impl PartialEq<T> where T is anything string-like
//!         // to compare to interned strings to either other interned strings,
//!         // or actual strings  Comparing two interned strings is very fast
//!         // (normally a single cpu operation).
//!         .filter(|interned_word| interned_word == &word)
//!         .count();
//!     if seen_before > 0 {
//!         println!(r#"Seen the word "{}" {} times"#, word, seen_before);
//!     } else {
//!         println!(r#"Not seen the word "{}" before"#, word);
//!     }
//!     // We use the impl From<(Cow<'a, str>, or &'a str, or String)> for
//!     // Atom<Static> to intern a new string.
//!     interned_stuff.push(DefaultAtom::from(word));
//! }
//! # }
//! ```
//!

#![crate_name = "string_cache"]
#![crate_type = "rlib"]
#![cfg_attr(test, deny(warnings))]

mod atom;
mod dynamic_set;
mod static_sets;

pub use atom::Atom;
pub use static_sets::{EmptyStaticAtomSet, PhfStrSet, StaticAtomSet};

/// Use this if you don’t care about static atoms.
pub type DefaultAtom = Atom<EmptyStaticAtomSet>;

// Some minor tests of internal layout here.
// See ../integration-tests for much more.

/// Guard against accidental changes to the sizes of things.
#[test]
fn assert_sizes() {
    use std::mem::size_of;
    assert_eq!(size_of::<DefaultAtom>(), 8);
    assert_eq!(size_of::<Option<DefaultAtom>>(), size_of::<DefaultAtom>(),);
}
<commit_msg>Remove attributes redundant with Cargo<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//!
//! A library for interning things that are `AsRef<str>`.
//!
//! Some strings may be interned at compile time using the `string-cache-codegen` crate, or the
//! `EmptyStaticAtomSet` may be used that has no compile-time interned strings. An `Atom` is an
//! interned string for a given set (either `EmptyStaticAtomSet` or a generated `StaticAtomSet`).
//!
//! Generated `Atom`s will have assocated macros to intern static strings at compile-time.
//!
//! # Examples
//!
//! Here are two examples, one with compile-time `Atom`s, and one without.
//!
//! ## With compile-time atoms
//!
//! In `Cargo.toml`:
//! ```toml
//! [dependencies]
//! string_cache = "0.8"
//!
//! [dev-dependencies]
//! string_cache_codegen = "0.5"
//! ```
//!
//! In `build.rs`:
//!
//! ```ignore
//! extern crate string_cache_codegen;
//!
//! use std::env;
//! use std::path::Path;
//!
//! fn main() {
//!     string_cache_codegen::AtomType::new("foo::FooAtom", "foo_atom!")
//!         .atoms(&["foo", "bar"])
//!         .write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("foo_atom.rs"))
//!         .unwrap()
//! }
//! ```
//!
//! In `lib.rs`:
//!
//! ```ignore
//! extern crate string_cache;
//!
//! mod foo {
//!     include!(concat!(env!("OUT_DIR"), "/foo_atom.rs"));
//! }
//!
//! fn use_the_atom(t: &str) {
//!     match *t {
//!         foo_atom!("foo") => println!("Found foo!"),
//!         foo_atom!("bar") => println!("Found bar!"),
//!         // foo_atom!("baz") => println!("Found baz!"), - would be a compile time error
//!         _ => {
//!             println!("String not interned");
//!             // We can intern strings at runtime as well
//!             foo::FooAtom::from(t)
//!         }
//!     }
//! }
//! ```
//!
//! ## No compile-time atoms
//!
//! ```
//! # extern crate string_cache;
//! use string_cache::DefaultAtom;
//!
//! # fn main() {
//! let mut interned_stuff = Vec::new();
//! let text = "here is a sentence of text that will be tokenised and
//!             interned and some repeated tokens is of text and";
//! for word in text.split_whitespace() {
//!     let seen_before = interned_stuff.iter()
//!         // We can use impl PartialEq<T> where T is anything string-like
//!         // to compare to interned strings to either other interned strings,
//!         // or actual strings  Comparing two interned strings is very fast
//!         // (normally a single cpu operation).
//!         .filter(|interned_word| interned_word == &word)
//!         .count();
//!     if seen_before > 0 {
//!         println!(r#"Seen the word "{}" {} times"#, word, seen_before);
//!     } else {
//!         println!(r#"Not seen the word "{}" before"#, word);
//!     }
//!     // We use the impl From<(Cow<'a, str>, or &'a str, or String)> for
//!     // Atom<Static> to intern a new string.
//!     interned_stuff.push(DefaultAtom::from(word));
//! }
//! # }
//! ```
//!

#![cfg_attr(test, deny(warnings))]

mod atom;
mod dynamic_set;
mod static_sets;

pub use atom::Atom;
pub use static_sets::{EmptyStaticAtomSet, PhfStrSet, StaticAtomSet};

/// Use this if you don’t care about static atoms.
pub type DefaultAtom = Atom<EmptyStaticAtomSet>;

// Some minor tests of internal layout here.
// See ../integration-tests for much more.

/// Guard against accidental changes to the sizes of things.
#[test]
fn assert_sizes() {
    use std::mem::size_of;
    assert_eq!(size_of::<DefaultAtom>(), 8);
    assert_eq!(size_of::<Option<DefaultAtom>>(), size_of::<DefaultAtom>(),);
}
<|endoftext|>