<commit_before>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/iron")]
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]

//! The main crate for Iron.
//!
//! ## Overview
//!
//! Iron is a high level web framework built in and for Rust, built on
//! [hyper](https://github.com/hyperium/hyper). Iron is designed to take advantage
//! of Rust's greatest features - it's excellent type system and its principled
//! approach to ownership in both single threaded and multi threaded contexts.
//!
//! Iron is highly concurrent and can scale horizontally on more machines behind a
//! load balancer or by running more threads on a more powerful machine. Iron
//! avoids the bottlenecks encountered in highly concurrent code by avoiding shared
//! writes and locking in the core framework.
//!
//! ## Hello World
//!
//! ```no_run
//! # use iron::prelude::*;
//! # use iron::status;
//! Iron::new(|req: &mut Request| {
//!     Ok(Response::with((status::Ok, "Hello World!")))
//! }).http("localhost:3000").unwrap();
//! ```
//!
//! ## Design Philosophy
//!
//! Iron is meant to be as extensible and pluggable as possible; Iron's core is
//! concentrated and avoids unnecessary features by leaving them to middleware,
//! plugins, and modifiers.
//!
//! Middleware, Plugins, and Modifiers are the main ways to extend Iron with new
//! functionality. Most extensions that would be provided by middleware in other
//! web frameworks are instead addressed by the much simpler Modifier and Plugin
//! systems.
//!
//! Modifiers allow external code to manipulate Requests and Response in an ergonomic
//! fashion, allowing third-party extensions to get the same treatment as modifiers
//! defined in Iron itself. Plugins allow for lazily-evaluated, automatically cached
//! extensions to Requests and Responses, perfect for parsing, accessing, and
//! otherwise lazily manipulating an http connection.
//!
//! Middleware are only used when it is necessary to modify the control flow of a
//! Request flow, hijack the entire handling of a Request, check an incoming
//! Request, or to do final post-processing. This covers areas such as routing,
//! mounting, static asset serving, final template rendering, authentication, and
//! logging.
//!
//! Iron comes with only basic modifiers for setting the status, body, and various
//! headers, and the infrastructure for creating modifiers, plugins, and
//! middleware. No plugins or middleware are bundled with Iron.
//!

// Stdlib dependencies
#[macro_use] extern crate log;

// Third party packages
extern crate hyper;
extern crate typemap as tmap;
extern crate plugin;
extern crate error as err;
extern crate url;
extern crate num_cpus;
extern crate conduit_mime_types as mime_types;
#[macro_use]
extern crate lazy_static;

// Request + Response
pub use request::{Request, Url};
pub use response::Response;

// Middleware system
pub use middleware::{BeforeMiddleware, AfterMiddleware, AroundMiddleware,
                     Handler, Chain};

// Server
pub use iron::{Iron, Protocol};

// Extensions
pub use typemap::TypeMap;

// Headers
pub use hyper::header as headers;
pub use hyper::header::Headers;

// Expose `Pluggable` as `Plugin` so users can do `use iron::Plugin`.
pub use plugin::Pluggable as Plugin;

// Expose modifiers.
pub use modifier::Set;

// Errors
pub use error::Error;
pub use error::IronError;

// Mime types
pub use hyper::mime;

/// Iron's error type and associated utilities.
pub mod error;

/// The Result alias used throughout Iron and in clients of Iron.
pub type IronResult<T> = Result<T, IronError>;

/// A module meant to be glob imported when using Iron, for instance:
///
/// ```
/// use iron::prelude::*;
/// ```
///
/// This module contains several important traits that provide many
/// of the convenience methods in Iron, as well as `Request`, `Response`
/// `IronResult`, `IronError` and `Iron`.
pub mod prelude {
    pub use {Set, Plugin, Chain, Request, Response,
             IronResult, IronError, Iron};
}

/// Re-exports from the TypeMap crate.
pub mod typemap {
    pub use tmap::{TypeMap, Key};
}

/// Re-exports from the Modifier crate.
pub mod modifier {
    extern crate modifier as modfier;
    pub use self::modfier::*;
}

/// Status Codes
pub mod status {
    pub use hyper::status::StatusCode as Status;
    pub use hyper::status::StatusCode::*;
    pub use hyper::status::StatusClass;
}

/// HTTP Methods
pub mod method {
    pub use hyper::method::Method;
    pub use hyper::method::Method::*;
}

// Publicized to show the documentation
pub mod middleware;

// Response utilities
pub mod response;

// Request utilities
pub mod request;

// Request and Response Modifiers
pub mod modifiers;

mod iron;

<commit_msg>Fix prelude doc formatting.<commit_after>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/iron")]
#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]

//! The main crate for Iron.
//!
//! ## Overview
//!
//! Iron is a high level web framework built in and for Rust, built on
//! [hyper](https://github.com/hyperium/hyper). Iron is designed to take advantage
//! of Rust's greatest features - it's excellent type system and its principled
//! approach to ownership in both single threaded and multi threaded contexts.
//!
//! Iron is highly concurrent and can scale horizontally on more machines behind a
//! load balancer or by running more threads on a more powerful machine. Iron
//! avoids the bottlenecks encountered in highly concurrent code by avoiding shared
//! writes and locking in the core framework.
//!
//! ## Hello World
//!
//! ```no_run
//! # use iron::prelude::*;
//! # use iron::status;
//! Iron::new(|req: &mut Request| {
//!     Ok(Response::with((status::Ok, "Hello World!")))
//! }).http("localhost:3000").unwrap();
//! ```
//!
//! ## Design Philosophy
//!
//! Iron is meant to be as extensible and pluggable as possible; Iron's core is
//! concentrated and avoids unnecessary features by leaving them to middleware,
//! plugins, and modifiers.
//!
//! Middleware, Plugins, and Modifiers are the main ways to extend Iron with new
//! functionality. Most extensions that would be provided by middleware in other
//! web frameworks are instead addressed by the much simpler Modifier and Plugin
//! systems.
//!
//! Modifiers allow external code to manipulate Requests and Response in an ergonomic
//! fashion, allowing third-party extensions to get the same treatment as modifiers
//! defined in Iron itself. Plugins allow for lazily-evaluated, automatically cached
//! extensions to Requests and Responses, perfect for parsing, accessing, and
//! otherwise lazily manipulating an http connection.
//!
//! Middleware are only used when it is necessary to modify the control flow of a
//! Request flow, hijack the entire handling of a Request, check an incoming
//! Request, or to do final post-processing. This covers areas such as routing,
//! mounting, static asset serving, final template rendering, authentication, and
//! logging.
//!
//! Iron comes with only basic modifiers for setting the status, body, and various
//! headers, and the infrastructure for creating modifiers, plugins, and
//! middleware. No plugins or middleware are bundled with Iron.
//!

// Stdlib dependencies
#[macro_use] extern crate log;

// Third party packages
extern crate hyper;
extern crate typemap as tmap;
extern crate plugin;
extern crate error as err;
extern crate url;
extern crate num_cpus;
extern crate conduit_mime_types as mime_types;
#[macro_use]
extern crate lazy_static;

// Request + Response
pub use request::{Request, Url};
pub use response::Response;

// Middleware system
pub use middleware::{BeforeMiddleware, AfterMiddleware, AroundMiddleware,
                     Handler, Chain};

// Server
pub use iron::{Iron, Protocol};

// Extensions
pub use typemap::TypeMap;

// Headers
pub use hyper::header as headers;
pub use hyper::header::Headers;

// Expose `Pluggable` as `Plugin` so users can do `use iron::Plugin`.
pub use plugin::Pluggable as Plugin;

// Expose modifiers.
pub use modifier::Set;

// Errors
pub use error::Error;
pub use error::IronError;

// Mime types
pub use hyper::mime;

/// Iron's error type and associated utilities.
pub mod error;

/// The Result alias used throughout Iron and in clients of Iron.
pub type IronResult<T> = Result<T, IronError>;

/// A module meant to be glob imported when using Iron.
///
/// For instance:
///
/// ```
/// use iron::prelude::*;
/// ```
///
/// This module contains several important traits that provide many
/// of the convenience methods in Iron, as well as `Request`, `Response`
/// `IronResult`, `IronError` and `Iron`.
pub mod prelude {
    pub use {Set, Plugin, Chain, Request, Response,
             IronResult, IronError, Iron};
}

/// Re-exports from the TypeMap crate.
pub mod typemap {
    pub use tmap::{TypeMap, Key};
}

/// Re-exports from the Modifier crate.
pub mod modifier {
    extern crate modifier as modfier;
    pub use self::modfier::*;
}

/// Status Codes
pub mod status {
    pub use hyper::status::StatusCode as Status;
    pub use hyper::status::StatusCode::*;
    pub use hyper::status::StatusClass;
}

/// HTTP Methods
pub mod method {
    pub use hyper::method::Method;
    pub use hyper::method::Method::*;
}

// Publicized to show the documentation
pub mod middleware;

// Response utilities
pub mod response;

// Request utilities
pub mod request;

// Request and Response Modifiers
pub mod modifiers;

mod iron;

<|endoftext|>


<commit_before>extern crate rand;

use rand::{Rand, Rng};
use rand::Closed01 as RandClosed01;

/// Encapsulates a floating point number in the range [0, 1] including both endpoints.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Closed01<F>(F);

impl Closed01<f32> {
    #[inline(always)]
    pub fn new(f: f32) -> Closed01<f32> {
        assert!(f >= 0.0 && f <= 1.0);
        Closed01(f)
    }

    #[inline(always)]
    pub fn zero() -> Closed01<f32> {
        Closed01(0.0)
    }

    #[inline(always)]
    pub fn center() -> Closed01<f32> {
        Closed01(0.5)
    }

    #[inline(always)]
    pub fn one() -> Closed01<f32> {
        Closed01(1.0)
    }

    #[inline(always)]
    /// Returns the smaller of the two.
    pub fn min(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 <= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the greater of the two.
    pub fn max(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 >= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the distance between the two numbers.
    pub fn distance(self, other: Closed01<f32>) -> Closed01<f32> {
        let d = (self.0 - other.0).abs();
        debug_assert!(d >= 0.0 && d <= 1.0);
        Closed01(d)
    }

    #[inline(always)]
    pub fn get(self) -> f32 {
        debug_assert!(self.0 >= 0.0 && self.0 <= 1.0);
        self.0
    }

    #[inline(always)]
    /// The average of two values.
    pub fn average(self: Closed01<f32>, other: Closed01<f32>) -> Closed01<f32> {
        let avg = (self.get() + other.get()) / 2.0;
        debug_assert!(avg >= 0.0 && avg <= 1.0);
        Closed01(avg)
    }

    #[inline(always)]
    /// Saturating add
    pub fn saturating_add(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sum = self.0 + other.0;
        if sum > 1.0 {
            sum = 1.0;
        }
        debug_assert!(sum >= 0.0 && sum <= 1.0);
        Closed01(sum)
    }

    #[inline(always)]
    /// Saturating sub
    pub fn saturating_sub(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sub = self.0 - other.0;
        if sub < 0.0 {
            sub = 0.0;
        }
        debug_assert!(sub >= 0.0 && sub <= 1.0);
        Closed01(sub)
    }

    #[inline(always)]
    /// Multiplies both numbers
    pub fn mul(self, scalar: Closed01<f32>) -> Closed01<f32> {
        let s = self.get() * scalar.get();
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    pub fn approx_eq(self, other: Closed01<f32>, eps: Closed01<f32>) -> bool {
        self.distance(other) < eps
    }

    #[inline(always)]
    /// This scales `self` towards 1.0
    pub fn scale_up(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 + (1.0 - self.0) * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// This scales `self` towards 0.0
    pub fn scale_down(self, other: Closed01<f32>) -> Closed01<f32> {
        let s = self.0 - self.0 * other.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// Invert the number (Mirror at 0.5; 1.0 - number).
    pub fn inv(self) -> Closed01<f32> {
        let s = 1.0 - self.0;
        debug_assert!(s >= 0.0 && s <= 1.0);
        Closed01(s)
    }

    #[inline(always)]
    /// Round the number to 0.0 or 1.0
    pub fn round(self) -> Closed01<f32> {
        if self.0 < 0.5 {
            Closed01::zero()
        } else {
            Closed01::one()
        }
    }
}

impl Into<f32> for Closed01<f32> {
    fn into(self) -> f32 {
        self.get()
    }
}

impl Rand for Closed01<f32> {
    fn rand<R: Rng>(rng: &mut R) -> Closed01<f32> {
        Closed01::new(RandClosed01::<f32>::rand(rng).0)
    }
}

#[test]
fn test_into() {
    assert_eq!(0.5f32, Closed01::new(0.5).into());
}

#[test]
fn test_minmax() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    assert_eq!(a, a.min(b));
    assert_eq!(a, b.min(a));
    assert_eq!(b, a.max(b));
    assert_eq!(b, b.max(a));
}

#[test]
fn test_saturation() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    let c = Closed01::new(0.6);

    assert_eq!(0.9, a.saturating_add(b).get());
    assert_eq!(1.0, a.saturating_add(c).get());
    assert_eq!(1.0, b.saturating_add(c).get());

    assert_eq!(0.0, a.saturating_sub(b).get());
    assert_eq!(0.0, a.saturating_sub(c).get());
    assert_eq!(0.0, b.saturating_sub(c).get());

    let eps = Closed01::new(0.001);
    assert!(c.saturating_sub(b).approx_eq(Closed01::new(0.1), eps));
    assert!(c.saturating_sub(a).approx_eq(Closed01::new(0.2), eps));
}

#[test]
fn test_scale_up() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(b, a.scale_up(b));
    assert_eq!(c, a.scale_up(c));

    assert_eq!(c, c.scale_up(a));
    assert_eq!(b, c.scale_up(b));
}

#[test]
fn test_scale_down() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, c.scale_down(b));
    assert_eq!(b, b.scale_down(a));
    assert_eq!(c, b.scale_down(c));
}

#[test]
fn test_invert() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, a.inv().inv());
    assert_eq!(b, b.inv().inv());
    assert_eq!(c, c.inv().inv());

    assert_eq!(b, a.inv());
    assert_eq!(a, b.inv());
    assert_eq!(c, c.inv());
}

#[test]
fn test_round() {
    assert_eq!(Closed01::zero(), Closed01::new(0.0).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.1).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.2).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.3).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.4).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.49999).round());
    assert_eq!(Closed01::one(), Closed01::new(0.5).round());
    assert_eq!(Closed01::one(), Closed01::new(0.6).round());
    assert_eq!(Closed01::one(), Closed01::new(0.8).round());
    assert_eq!(Closed01::one(), Closed01::new(0.9).round());
    assert_eq!(Closed01::one(), Closed01::new(1.0).round());
}
<commit_msg>Move debug_assert into Closed01::new_debug_checked<commit_after>extern crate rand;

use rand::{Rand, Rng};
use rand::Closed01 as RandClosed01;

/// Encapsulates a floating point number in the range [0, 1] including both endpoints.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Closed01<F>(F);

impl Closed01<f32> {
    #[inline(always)]
    pub fn new(f: f32) -> Closed01<f32> {
        assert!(f >= 0.0 && f <= 1.0);
        Closed01(f)
    }

    #[inline(always)]
    fn new_debug_checked(f: f32) -> Closed01<f32> {
        debug_assert!(f >= 0.0 && f <= 1.0);
        Closed01(f)
    }

    #[inline(always)]
    pub fn zero() -> Closed01<f32> {
        Closed01::new_debug_checked(0.0)
    }

    #[inline(always)]
    pub fn center() -> Closed01<f32> {
        Closed01::new_debug_checked(0.5)
    }

    #[inline(always)]
    pub fn one() -> Closed01<f32> {
        Closed01::new_debug_checked(1.0)
    }

    #[inline(always)]
    /// Returns the smaller of the two.
    pub fn min(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 <= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the greater of the two.
    pub fn max(self, other: Closed01<f32>) -> Closed01<f32> {
        if self.0 >= other.0 {
            self
        } else {
            other
        }
    }

    #[inline(always)]
    /// Returns the distance between the two numbers.
    pub fn distance(self, other: Closed01<f32>) -> Closed01<f32> {
        Closed01::new_debug_checked((self.0 - other.0).abs())
    }

    #[inline(always)]
    pub fn get(self) -> f32 {
        debug_assert!(self.0 >= 0.0 && self.0 <= 1.0);
        self.0
    }

    #[inline(always)]
    /// The average of two values.
    pub fn average(self: Closed01<f32>, other: Closed01<f32>) -> Closed01<f32> {
        Closed01::new_debug_checked((self.get() + other.get()) / 2.0)
    }

    #[inline(always)]
    /// Saturating add
    pub fn saturating_add(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sum = self.0 + other.0;
        if sum > 1.0 {
            sum = 1.0;
        }
        Closed01::new_debug_checked(sum)
    }

    #[inline(always)]
    /// Saturating sub
    pub fn saturating_sub(self, other: Closed01<f32>) -> Closed01<f32> {
        let mut sub = self.0 - other.0;
        if sub < 0.0 {
            sub = 0.0;
        }
        Closed01::new_debug_checked(sub)
    }

    #[inline(always)]
    /// Multiplies both numbers
    pub fn mul(self, scalar: Closed01<f32>) -> Closed01<f32> {
        Closed01::new_debug_checked(self.get() * scalar.get())
    }

    #[inline(always)]
    pub fn approx_eq(self, other: Closed01<f32>, eps: Closed01<f32>) -> bool {
        self.distance(other) < eps
    }

    #[inline(always)]
    /// This scales `self` towards 1.0
    pub fn scale_up(self, other: Closed01<f32>) -> Closed01<f32> {
        Closed01::new_debug_checked(self.0 + (1.0 - self.0) * other.0)
    }

    #[inline(always)]
    /// This scales `self` towards 0.0
    pub fn scale_down(self, other: Closed01<f32>) -> Closed01<f32> {
        Closed01::new_debug_checked(self.0 - self.0 * other.0)
    }

    #[inline(always)]
    /// Invert the number (Mirror at 0.5; 1.0 - number).
    pub fn inv(self) -> Closed01<f32> {
        Closed01::new_debug_checked(1.0 - self.0)
    }

    #[inline(always)]
    /// Round the number to 0.0 or 1.0
    pub fn round(self) -> Closed01<f32> {
        if self.0 < 0.5 {
            Closed01::zero()
        } else {
            Closed01::one()
        }
    }
}

impl Into<f32> for Closed01<f32> {
    fn into(self) -> f32 {
        self.get()
    }
}

impl Rand for Closed01<f32> {
    fn rand<R: Rng>(rng: &mut R) -> Closed01<f32> {
        Closed01::new(RandClosed01::<f32>::rand(rng).0)
    }
}

#[test]
fn test_into() {
    assert_eq!(0.5f32, Closed01::new(0.5).into());
}

#[test]
fn test_minmax() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    assert_eq!(a, a.min(b));
    assert_eq!(a, b.min(a));
    assert_eq!(b, a.max(b));
    assert_eq!(b, b.max(a));
}

#[test]
fn test_saturation() {
    let a = Closed01::new(0.4);
    let b = Closed01::new(0.5);
    let c = Closed01::new(0.6);

    assert_eq!(0.9, a.saturating_add(b).get());
    assert_eq!(1.0, a.saturating_add(c).get());
    assert_eq!(1.0, b.saturating_add(c).get());

    assert_eq!(0.0, a.saturating_sub(b).get());
    assert_eq!(0.0, a.saturating_sub(c).get());
    assert_eq!(0.0, b.saturating_sub(c).get());

    let eps = Closed01::new(0.001);
    assert!(c.saturating_sub(b).approx_eq(Closed01::new(0.1), eps));
    assert!(c.saturating_sub(a).approx_eq(Closed01::new(0.2), eps));
}

#[test]
fn test_scale_up() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(b, a.scale_up(b));
    assert_eq!(c, a.scale_up(c));

    assert_eq!(c, c.scale_up(a));
    assert_eq!(b, c.scale_up(b));
}

#[test]
fn test_scale_down() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, c.scale_down(b));
    assert_eq!(b, b.scale_down(a));
    assert_eq!(c, b.scale_down(c));
}

#[test]
fn test_invert() {
    let a = Closed01::new(0.0);
    let b = Closed01::new(1.0);
    let c = Closed01::new(0.5);

    assert_eq!(a, a.inv().inv());
    assert_eq!(b, b.inv().inv());
    assert_eq!(c, c.inv().inv());

    assert_eq!(b, a.inv());
    assert_eq!(a, b.inv());
    assert_eq!(c, c.inv());
}

#[test]
fn test_round() {
    assert_eq!(Closed01::zero(), Closed01::new(0.0).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.1).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.2).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.3).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.4).round());
    assert_eq!(Closed01::zero(), Closed01::new(0.49999).round());
    assert_eq!(Closed01::one(), Closed01::new(0.5).round());
    assert_eq!(Closed01::one(), Closed01::new(0.6).round());
    assert_eq!(Closed01::one(), Closed01::new(0.8).round());
    assert_eq!(Closed01::one(), Closed01::new(0.9).round());
    assert_eq!(Closed01::one(), Closed01::new(1.0).round());
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;
extern crate chrono;
extern crate hyper;

pub mod message_templates;
pub mod payloads;
pub mod pipeline;

macro_rules! get_event_data {
    ($s:expr, $( $n:ident: $v:expr ),* ) => {{
        use std::fmt::Write;
        use std::collections;
        use serde_json;

        let mut names: Vec<&str> = vec![];
        let mut properties: collections::BTreeMap<&'static str, String> = collections::BTreeMap::new();

        $(
            names.push(stringify!($n));
            properties.insert(stringify!($n), serde_json::to_string(&$v).unwrap());
        )*

        let template = $crate::message_templates::build_template($s, &names);

        (template, properties)
    }};
}

#[macro_export]
macro_rules! emit {
    ( $s:expr, $( $n:ident: $v:expr ),* ) => {{
        let (template, properties) = get_event_data!($s, $($n: $v),*);
        $crate::pipeline::emit(&template, &properties);
    }};

    ( $s:expr ) => {{
        emit!($s,);
    }};
}

#[cfg(test)]
mod tests {

    #[test]
    fn it_works() {
        emit!("Starting...");

        let u = "World";
        let q = 42;

        emit!("User {} exceeded quota of {}!", user: u, quota: q);
    }

}
<commit_msg>Test template/property capture.<commit_after>extern crate serde;
extern crate serde_json;
extern crate chrono;
extern crate hyper;

pub mod message_templates;
pub mod payloads;
pub mod pipeline;

macro_rules! get_event_data {
    ($s:expr, $( $n:ident: $v:expr ),* ) => {{
        use std::fmt::Write;
        use std::collections;
        use serde_json;

        let mut names: Vec<&str> = vec![];
        let mut properties: collections::BTreeMap<&'static str, String> = collections::BTreeMap::new();

        $(
            names.push(stringify!($n));
            properties.insert(stringify!($n), serde_json::to_string(&$v).unwrap());
        )*

        let template = $crate::message_templates::build_template($s, &names);

        (template, properties)
    }};
}

#[macro_export]
macro_rules! emit {
    ( $s:expr, $( $n:ident: $v:expr ),* ) => {{
        let (template, properties) = get_event_data!($s, $($n: $v),*);
        $crate::pipeline::emit(&template, &properties);
    }};

    ( $s:expr ) => {{
        emit!($s,);
    }};
}

#[cfg(test)]
mod tests {

    #[test]
    fn unparameterized_templates_are_captured() {
        let (template, properties) = get_event_data!("Starting...",);
        assert!(template == "Starting...");
        assert!(properties.len() == 0);
    }

    #[test]
    fn template_and_properties_are_captured() {
        let u = "nblumhardt";
        let q = 42;

        let (template, properties) = get_event_data!("User {} exceeded quota of {}!", user: u, quota: q);
        assert!(template == "User {user} exceeded quota of {quota}!");
        assert!(properties.get("user") == Some(&"\"nblumhardt\"".to_owned()));
        assert!(properties.get("quota") == Some(&"42".to_owned()));
    }

}
<|endoftext|>


<commit_before>/// If logging is not compiled into the library, this module defines the logging macros to result
/// in nothing.
///

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! debug {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! error {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! info {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! log {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! trace {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! warn {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

<commit_msg>Add documentation to logging macros<commit_after>//! If logging is not compiled into the library, this module defines the logging macros to result
//! in nothing.

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! debug {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! error {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! info {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! log {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! trace {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

/// This macro is defined if the `logging` feature is _not_ compiled into the library
///
/// It ignores all logging calls inside the library.
#[cfg(not(feature = "logging"))]
#[macro_export]
macro_rules! warn {
    (target: $target:expr, $($arg:tt)*) => { };
    ($($arg:tt)*) => { };
}

<|endoftext|>


<commit_before>use ::std::cell::*;

/// Provides interior mutability for a add-only set.
/// Items can be added (a reference is returned)
/// References can be looked up via a pointer to the item
#[derive(Debug,Clone, PartialEq)]
pub struct AppendOnlySet<T>{
    slots: RefCell<Vec<Box<T>>>
}
impl<T> AppendOnlySet<T> {
    pub fn with_capacity(slots: usize) -> AppendOnlySet<T> {
        AppendOnlySet {
            slots: RefCell::new(Vec::with_capacity(slots))
        }
    }
    // &T's lifetime can't exceed that of AppendOnlySet's
    pub fn add(&self, value: T) -> &T {
        //Boxing T means that the address will never change,
        //Even if the vector owning the Boxed values is resized and moved via push
        let boxed = Box::new(value);
        //We take the stable address of boxed T
        let ptr = &*boxed as *const T;
        self.slots.borrow_mut().push(boxed);
        //Change lifetime to that of of AppendOnlySet instead of slots.borrow_mut()
        unsafe { &*ptr }
    }

    // We return a reference to the cell
    // First match wins; multiple matches would indicate that two Boxes had been
    // allocated with the same address.
    // Pointer is never dereferenced
    pub fn get_reference(&self, ptr: *const T) -> Option<&T> {
        for ref item in self.slots.borrow().iter() {
            let item_ptr = &***item as *const T;
            if ptr == item_ptr {
                //Change lifetime to that of of AppendOnlySet instead of slots.borrow()
                return Some(unsafe { &*item_ptr })
            }
        }
        None
    }
    // Pointer is never dereferenced
    pub fn contains(&self, item: *const T) -> bool {
        self.get_reference(item).is_some()
    }

    ///
    /// If you have a mutable reference, you can do whatever you like, since
    /// there cannot be any other outstanding references
    pub fn get_mut_vec(&mut self) -> &mut Vec<Box<T>>{
        self.slots.get_mut()
    }

    pub fn iter(&self) -> IterAppendOnlySet<T>{
        IterAppendOnlySet{
            set: self,
            index: 0
        }
    }

}

pub struct IterAppendOnlySet<'a, T: 'a>{
    set: &'a AppendOnlySet<T>,
    index: usize
}

impl<'a, T> Iterator for IterAppendOnlySet<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        let vec_ref = self.set.slots.borrow();
        let result = vec_ref.get(self.index).map(|b| {
            //Change lifetime from 'vec_ref to 'a
            unsafe{ &* (&**b as *const T)}
        });
        self.index += 1;
        result
    }
}

/// Provides a simple set which has interior mutability.
/// Removal is offered, but can fail at runtime if there is an active borrow.
/// Removal leaves holes, and there is no way to reclaim that space.
///
///
#[derive(Debug,Clone, PartialEq)]
pub struct AddRemoveSet<T>{
    inner: AppendOnlySet<RefCell<Option<T>>>
}
impl<T> AddRemoveSet<T> {
    pub fn with_capacity(slots: usize) -> AddRemoveSet<T> {
        AddRemoveSet {
            inner: AppendOnlySet::with_capacity(slots)
        }
    }
    pub fn add(&self, value: T) -> Ref<T> {
        Ref::map(self.inner.add(RefCell::new(Some(value))).borrow(), |t| t.as_ref().unwrap())
    }
    pub fn add_mut(&self, value: T) -> RefMut<T> {
        RefMut::map(self.inner.add(RefCell::new(Some(value))).borrow_mut(), |t| t.as_mut().unwrap())
    }

    pub fn iter(&self) -> IterAddRemoveSet<T>{
        IterAddRemoveSet{ inner: self.inner.iter() }
    }

    /// Ok(None) means it definitely doesn't exist in the set
    /// Err() means we couldn't access all the items in
    //    pub fn get_reference(&self, ptr: *const T) -> Result<Option<&T>,BorrowMutError>{
    //        self.iter().find(|r| if let Ok(reference) = r { reference as *const T == ptr } else {false}).map(|v| Some(v)).unwrap_or(Ok(None))
    //    }

    pub fn iter_mut(&self) -> IterMutAddRemoveSet<T>{
        IterMutAddRemoveSet{ inner: self.inner.iter() }
    }

    pub fn mut_clear(&mut self){
        self.inner.get_mut_vec().clear();
    }

    pub fn clear(&self) -> Result<(),BorrowMutError>{
        for refcell in self.inner.iter() {
            match refcell.try_borrow_mut() {
                Ok(mut ref_obj) => {
                    *ref_obj = None
                }
                Err(e) => { return Err(e) }
            }
        }
        Ok(())
    }

    /// Ok(true) - removed. Ok(false) - certainly didn't exist. Err() - either borrowed or didn't exist (unknowable)
    pub fn try_remove(&self, v: *const T) -> Result<bool, BorrowMutError>{
        match self.try_get_option_reference_mut(v){
            Ok(Some(mut ref_obj)) => {
                *ref_obj = None;
                return Ok(true)
            },
            Ok(None) => Ok(false),
            Err(e) => Err(e)
        }
    }
    pub fn try_contains(&self, v: *const T) -> Result<bool, BorrowError>{
        self.try_get_reference(v).map(|opt| opt.is_some())
    }

    pub fn try_get_reference(&self, v: *const T) -> Result<Option<Ref<T>>, BorrowError>{
        let mut last_error = None;
        for refcell in self.inner.iter() {
            match refcell.try_borrow() {
                Ok(ref_obj) => {
                    let other_ptr = ref_obj.as_ref().map(|v| v as *const T);
                    if Some(v) == other_ptr{
                        return Ok(Some(Ref::map(ref_obj, |r| r.as_ref().unwrap())));
                    }
                }
                Err(e) => { last_error = Some(e); }
            }
        }
        if last_error.is_some(){
            Err(last_error.unwrap())
        }else{
            Ok(None)
        }
    }
    pub fn try_get_reference_mut(&self, v: *const T) -> Result<Option<RefMut<T>>, BorrowMutError>{
        self.try_get_option_reference_mut(v).map(|opt| opt.and_then(|ref_obj| {
            if ref_obj.is_some() { Some(RefMut::map(ref_obj, |r| r.as_mut().unwrap())) } else {None}
        }))
    }
    fn try_get_option_reference_mut(&self, v: *const T) -> Result<Option<RefMut<Option<T>>>, BorrowMutError>{
        let mut last_error = None;
        for refcell in self.inner.iter() {
            match refcell.try_borrow_mut() {
                Ok(ref_obj) => {
                    if ref_obj.is_some() && ref_obj.as_ref().unwrap() as *const T == v {
                        return Ok(Some(ref_obj));
                    }
                }
                Err(e) => { last_error = Some(e); }
            }
        }
        if last_error.is_some(){
            Err(last_error.unwrap())
        }else{
            Ok(None)
        }
    }
}

pub struct IterAddRemoveSet<'a, T: 'a>{
    inner: IterAppendOnlySet<'a, RefCell<Option<T>>>
}

impl<'a, T> Iterator for IterAddRemoveSet<'a, T> {
    type Item = Result<Ref<'a,T>, BorrowError>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next(){
            None => None,
            Some(cell) => {
                match cell.try_borrow(){
                    Ok(ref_obj) => {
                        if ref_obj.is_none(){
                            None
                        }else{
                            Some(Ok(Ref::map(ref_obj, |r| r.as_ref().unwrap())))
                        }
                    }
                    Err(e) => Some(Err(e))
                }
            }
        }
    }
}

pub struct IterMutAddRemoveSet<'a, T: 'a>{
    inner: IterAppendOnlySet<'a, RefCell<Option<T>>>
}

impl<'a, T> Iterator for IterMutAddRemoveSet<'a, T> {
    type Item = Result<RefMut<'a,T>, BorrowMutError>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next(){
            None => None,
            Some(cell) => {
                match cell.try_borrow_mut(){
                    Ok(ref_obj) => {
                        if ref_obj.is_none(){
                            None
                        }else{
                            Some(Ok(RefMut::map(ref_obj, |r| r.as_mut().unwrap())))
                        }
                    }
                    Err(e) => Some(Err(e))
                }
            }
        }
    }
}

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

    #[derive(Clone, PartialEq,Debug)]
    struct Container{
        objects: AppendOnlySet<RefCell<Option<Child>>>,
        b: AddRemoveSet<Child>
    }
    impl Container{
        pub fn new() -> Container{
            Container{
                objects: AppendOnlySet::with_capacity(4),
                b: AddRemoveSet::with_capacity(1)
            }
        }

        pub fn add_child_get_cell(&self) -> &RefCell<Option<Child>>{
            self.objects.add(RefCell::new(Some(Child{})))
        }

        pub fn add_child_get_ref(&self) -> RefMut<Option<Child>>{
            self.objects.add(RefCell::new(Some(Child{}))).borrow_mut()
        }

    }

    #[derive(Clone, PartialEq,Debug)]
    struct Child{

    }
    impl Child{
        pub fn do_a_thing(&mut self, _: &Container){

        }
    }

    #[test]
    fn test_sets_with_interior_mutability(){
        let g = Container::new();

        let child = g.add_child_get_cell();
        child.borrow_mut().as_mut().unwrap().do_a_thing(&g);
        assert_eq!(g.objects.get_reference(child as *const RefCell<Option<Child>>), Some(child));
        assert!(g.objects.contains(&*child));
        let mut c2 = g.add_child_get_ref();
        assert!(g.objects.contains(&*child));
        c2.as_mut().unwrap().do_a_thing(&g);

        let c3_ptr;
        {
            let c3 = g.b.add(Child {});
            c3_ptr = &*c3 as *const Child;
            g.b.add_mut(Child {}).do_a_thing(&g);
            for _ in 0..30 {
                let addl_ptr;
                {
                    let mut addl = g.b.add_mut(Child {});
                    addl.do_a_thing(&g);
                    addl_ptr = &*addl as *const Child;
                }
                assert!(g.b.try_contains(&*c3).unwrap());
                assert!(g.b.try_remove(addl_ptr).unwrap());
                assert!(!g.b.try_contains(addl_ptr).unwrap());
            }
        }
        assert!(g.b.try_remove(c3_ptr).unwrap());
        assert!(!g.b.try_contains(c3_ptr).unwrap());
    }

    struct GenericOfRef<T>{

    }
    #[test]
    fn t(){
        let a = GenericOfRef::<&mut Vec<i32>>{};

    }

//    mod experiment_with_parent_references{
//        use super::super::*;
//        use ::std::cell::RefMut;
//        struct P<'a>{ c: AddRemoveSet<C<'a>> } struct C<'a>{ p: &'a P<'a> }
//        impl<'a> P<'a>{
//
//            pub fn new() -> P<'static>{
//                P{
//                    c: AddRemoveSet::with_capacity(1)
//                }
//            }
//
//            pub fn add_child(&'a self) -> RefMut<C<'a>>{
//                self.c.add_mut(C{p:self})
//            }
//        }
//
//        #[test]
//        fn tryit(){
//
//            let mut a = P::new();
//
//            let mut child = a.add_child();
//
//        }
//
//
//
//    }
}<commit_msg>fix(types): delete exploratory test code causing build failure<commit_after>use ::std::cell::*;

/// Provides interior mutability for a add-only set.
/// Items can be added (a reference is returned)
/// References can be looked up via a pointer to the item
#[derive(Debug,Clone, PartialEq)]
pub struct AppendOnlySet<T>{
    slots: RefCell<Vec<Box<T>>>
}
impl<T> AppendOnlySet<T> {
    pub fn with_capacity(slots: usize) -> AppendOnlySet<T> {
        AppendOnlySet {
            slots: RefCell::new(Vec::with_capacity(slots))
        }
    }
    // &T's lifetime can't exceed that of AppendOnlySet's
    pub fn add(&self, value: T) -> &T {
        //Boxing T means that the address will never change,
        //Even if the vector owning the Boxed values is resized and moved via push
        let boxed = Box::new(value);
        //We take the stable address of boxed T
        let ptr = &*boxed as *const T;
        self.slots.borrow_mut().push(boxed);
        //Change lifetime to that of of AppendOnlySet instead of slots.borrow_mut()
        unsafe { &*ptr }
    }

    // We return a reference to the cell
    // First match wins; multiple matches would indicate that two Boxes had been
    // allocated with the same address.
    // Pointer is never dereferenced
    pub fn get_reference(&self, ptr: *const T) -> Option<&T> {
        for ref item in self.slots.borrow().iter() {
            let item_ptr = &***item as *const T;
            if ptr == item_ptr {
                //Change lifetime to that of of AppendOnlySet instead of slots.borrow()
                return Some(unsafe { &*item_ptr })
            }
        }
        None
    }
    // Pointer is never dereferenced
    pub fn contains(&self, item: *const T) -> bool {
        self.get_reference(item).is_some()
    }

    ///
    /// If you have a mutable reference, you can do whatever you like, since
    /// there cannot be any other outstanding references
    pub fn get_mut_vec(&mut self) -> &mut Vec<Box<T>>{
        self.slots.get_mut()
    }

    pub fn iter(&self) -> IterAppendOnlySet<T>{
        IterAppendOnlySet{
            set: self,
            index: 0
        }
    }

}

pub struct IterAppendOnlySet<'a, T: 'a>{
    set: &'a AppendOnlySet<T>,
    index: usize
}

impl<'a, T> Iterator for IterAppendOnlySet<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        let vec_ref = self.set.slots.borrow();
        let result = vec_ref.get(self.index).map(|b| {
            //Change lifetime from 'vec_ref to 'a
            unsafe{ &* (&**b as *const T)}
        });
        self.index += 1;
        result
    }
}

/// Provides a simple set which has interior mutability.
/// Removal is offered, but can fail at runtime if there is an active borrow.
/// Removal leaves holes, and there is no way to reclaim that space.
///
///
#[derive(Debug,Clone, PartialEq)]
pub struct AddRemoveSet<T>{
    inner: AppendOnlySet<RefCell<Option<T>>>
}
impl<T> AddRemoveSet<T> {
    pub fn with_capacity(slots: usize) -> AddRemoveSet<T> {
        AddRemoveSet {
            inner: AppendOnlySet::with_capacity(slots)
        }
    }
    pub fn add(&self, value: T) -> Ref<T> {
        Ref::map(self.inner.add(RefCell::new(Some(value))).borrow(), |t| t.as_ref().unwrap())
    }
    pub fn add_mut(&self, value: T) -> RefMut<T> {
        RefMut::map(self.inner.add(RefCell::new(Some(value))).borrow_mut(), |t| t.as_mut().unwrap())
    }

    pub fn iter(&self) -> IterAddRemoveSet<T>{
        IterAddRemoveSet{ inner: self.inner.iter() }
    }

    /// Ok(None) means it definitely doesn't exist in the set
    /// Err() means we couldn't access all the items in
    //    pub fn get_reference(&self, ptr: *const T) -> Result<Option<&T>,BorrowMutError>{
    //        self.iter().find(|r| if let Ok(reference) = r { reference as *const T == ptr } else {false}).map(|v| Some(v)).unwrap_or(Ok(None))
    //    }

    pub fn iter_mut(&self) -> IterMutAddRemoveSet<T>{
        IterMutAddRemoveSet{ inner: self.inner.iter() }
    }

    pub fn mut_clear(&mut self){
        self.inner.get_mut_vec().clear();
    }

    pub fn clear(&self) -> Result<(),BorrowMutError>{
        for refcell in self.inner.iter() {
            match refcell.try_borrow_mut() {
                Ok(mut ref_obj) => {
                    *ref_obj = None
                }
                Err(e) => { return Err(e) }
            }
        }
        Ok(())
    }

    /// Ok(true) - removed. Ok(false) - certainly didn't exist. Err() - either borrowed or didn't exist (unknowable)
    pub fn try_remove(&self, v: *const T) -> Result<bool, BorrowMutError>{
        match self.try_get_option_reference_mut(v){
            Ok(Some(mut ref_obj)) => {
                *ref_obj = None;
                return Ok(true)
            },
            Ok(None) => Ok(false),
            Err(e) => Err(e)
        }
    }
    pub fn try_contains(&self, v: *const T) -> Result<bool, BorrowError>{
        self.try_get_reference(v).map(|opt| opt.is_some())
    }

    pub fn try_get_reference(&self, v: *const T) -> Result<Option<Ref<T>>, BorrowError>{
        let mut last_error = None;
        for refcell in self.inner.iter() {
            match refcell.try_borrow() {
                Ok(ref_obj) => {
                    let other_ptr = ref_obj.as_ref().map(|v| v as *const T);
                    if Some(v) == other_ptr{
                        return Ok(Some(Ref::map(ref_obj, |r| r.as_ref().unwrap())));
                    }
                }
                Err(e) => { last_error = Some(e); }
            }
        }
        if last_error.is_some(){
            Err(last_error.unwrap())
        }else{
            Ok(None)
        }
    }
    pub fn try_get_reference_mut(&self, v: *const T) -> Result<Option<RefMut<T>>, BorrowMutError>{
        self.try_get_option_reference_mut(v).map(|opt| opt.and_then(|ref_obj| {
            if ref_obj.is_some() { Some(RefMut::map(ref_obj, |r| r.as_mut().unwrap())) } else {None}
        }))
    }
    fn try_get_option_reference_mut(&self, v: *const T) -> Result<Option<RefMut<Option<T>>>, BorrowMutError>{
        let mut last_error = None;
        for refcell in self.inner.iter() {
            match refcell.try_borrow_mut() {
                Ok(ref_obj) => {
                    if ref_obj.is_some() && ref_obj.as_ref().unwrap() as *const T == v {
                        return Ok(Some(ref_obj));
                    }
                }
                Err(e) => { last_error = Some(e); }
            }
        }
        if last_error.is_some(){
            Err(last_error.unwrap())
        }else{
            Ok(None)
        }
    }
}

pub struct IterAddRemoveSet<'a, T: 'a>{
    inner: IterAppendOnlySet<'a, RefCell<Option<T>>>
}

impl<'a, T> Iterator for IterAddRemoveSet<'a, T> {
    type Item = Result<Ref<'a,T>, BorrowError>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next(){
            None => None,
            Some(cell) => {
                match cell.try_borrow(){
                    Ok(ref_obj) => {
                        if ref_obj.is_none(){
                            None
                        }else{
                            Some(Ok(Ref::map(ref_obj, |r| r.as_ref().unwrap())))
                        }
                    }
                    Err(e) => Some(Err(e))
                }
            }
        }
    }
}

pub struct IterMutAddRemoveSet<'a, T: 'a>{
    inner: IterAppendOnlySet<'a, RefCell<Option<T>>>
}

impl<'a, T> Iterator for IterMutAddRemoveSet<'a, T> {
    type Item = Result<RefMut<'a,T>, BorrowMutError>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next(){
            None => None,
            Some(cell) => {
                match cell.try_borrow_mut(){
                    Ok(ref_obj) => {
                        if ref_obj.is_none(){
                            None
                        }else{
                            Some(Ok(RefMut::map(ref_obj, |r| r.as_mut().unwrap())))
                        }
                    }
                    Err(e) => Some(Err(e))
                }
            }
        }
    }
}

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

    #[derive(Clone, PartialEq,Debug)]
    struct Container{
        objects: AppendOnlySet<RefCell<Option<Child>>>,
        b: AddRemoveSet<Child>
    }
    impl Container{
        pub fn new() -> Container{
            Container{
                objects: AppendOnlySet::with_capacity(4),
                b: AddRemoveSet::with_capacity(1)
            }
        }

        pub fn add_child_get_cell(&self) -> &RefCell<Option<Child>>{
            self.objects.add(RefCell::new(Some(Child{})))
        }

        pub fn add_child_get_ref(&self) -> RefMut<Option<Child>>{
            self.objects.add(RefCell::new(Some(Child{}))).borrow_mut()
        }

    }

    #[derive(Clone, PartialEq,Debug)]
    struct Child{

    }
    impl Child{
        pub fn do_a_thing(&mut self, _: &Container){

        }
    }

    #[test]
    fn test_sets_with_interior_mutability(){
        let g = Container::new();

        let child = g.add_child_get_cell();
        child.borrow_mut().as_mut().unwrap().do_a_thing(&g);
        assert_eq!(g.objects.get_reference(child as *const RefCell<Option<Child>>), Some(child));
        assert!(g.objects.contains(&*child));
        let mut c2 = g.add_child_get_ref();
        assert!(g.objects.contains(&*child));
        c2.as_mut().unwrap().do_a_thing(&g);

        let c3_ptr;
        {
            let c3 = g.b.add(Child {});
            c3_ptr = &*c3 as *const Child;
            g.b.add_mut(Child {}).do_a_thing(&g);
            for _ in 0..30 {
                let addl_ptr;
                {
                    let mut addl = g.b.add_mut(Child {});
                    addl.do_a_thing(&g);
                    addl_ptr = &*addl as *const Child;
                }
                assert!(g.b.try_contains(&*c3).unwrap());
                assert!(g.b.try_remove(addl_ptr).unwrap());
                assert!(!g.b.try_contains(addl_ptr).unwrap());
            }
        }
        assert!(g.b.try_remove(c3_ptr).unwrap());
        assert!(!g.b.try_contains(c3_ptr).unwrap());
    }

//    mod experiment_with_parent_references{
//        use super::super::*;
//        use ::std::cell::RefMut;
//        struct P<'a>{ c: AddRemoveSet<C<'a>> } struct C<'a>{ p: &'a P<'a> }
//        impl<'a> P<'a>{
//
//            pub fn new() -> P<'static>{
//                P{
//                    c: AddRemoveSet::with_capacity(1)
//                }
//            }
//
//            pub fn add_child(&'a self) -> RefMut<C<'a>>{
//                self.c.add_mut(C{p:self})
//            }
//        }
//
//        #[test]
//        fn tryit(){
//
//            let mut a = P::new();
//
//            let mut child = a.add_child();
//
//        }
//
//
//
//    }
}<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

#![macro_escape]

// use std;
// use gl;
// use gl::types::{GLuint, GLsizeiptr};
// use cgmath::{Vector3, rad, ortho};
// use core_misc::deg_to_rad;
// use core_types::{Size2, MInt};
// use visualizer::types::{MFloat, Color3, Color4, ScreenPos};
use visualizer_types::{/*MFloat,*/ Color3};
// use cgmath::{Matrix, Matrix4, Matrix3, ToMatrix4};
use libc::c_void;
use gl;
use gl::types::{GLuint, GLint, GLenum};
use std::ptr;

use gl::Gles2 as Gl;

/*
pub const GREY_3: Color3 = Color3{r: 0.3, g: 0.3, b: 0.3};
pub const BLACK_3: Color3 = Color3{r: 0.0, g: 0.0, b: 0.0};
pub const WHITE: Color4 = Color4{r: 1.0, g: 1.0, b: 1.0, a: 1.0};
pub const BLUE: Color4 = Color4{r: 0.0, g: 0.0, b: 1.0, a: 1.0};
pub const BLACK: Color4 = Color4{r: 0.0, g: 0.0, b: 0.0, a: 1.0};
*/

pub struct Mgl {
    pub gl: Gl,
}

impl Mgl {
    pub fn new(get_proc_address: |&str| -> *const c_void) -> Mgl {
        let gl = Gl::load_with(|s| get_proc_address(s));
    	Mgl{gl: gl}
    }

    pub fn set_clear_color(&mut self, color: Color3) {
        unsafe {
            self.gl.ClearColor(color.r, color.g, color.b, 1.0);
        }
        self.check();
    }

    pub fn clear_screen(&self) {
        unsafe {
            self.gl.Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
        self.check();
    }

    /*
    pub fn set_viewport(&mut self, size: Size2<MInt>) {
        unsafe {
            self.gl.Viewport(0, 0, size.w, size.h);
        }
        self.check();
    }

    // TODO: replace with something from cgmath-rs
    pub fn tr(&self, m: Matrix4<MFloat>, v: Vector3<MFloat>) -> Matrix4<MFloat> {
        let mut t = Matrix4::<MFloat>::identity();
        t[3][0] = v.x;
        t[3][1] = v.y;
        t[3][2] = v.z;
        m.mul_m(&t)
    }

    pub fn scale(&self, m: Matrix4<MFloat>, scale: MFloat) -> Matrix4<MFloat> {
        let mut t = Matrix4::<MFloat>::identity();
        t[0][0] = scale;
        t[1][1] = scale;
        t[2][2] = scale;
        m.mul_m(&t)
    }

    pub fn rot_x(&self, m: Matrix4<MFloat>, angle: MFloat) -> Matrix4<MFloat> {
        let rad = rad(deg_to_rad(angle));
        let r = Matrix3::from_angle_x(rad).to_matrix4();
        m.mul_m(&r)
    }

    pub fn rot_z(&self, m: Matrix4<MFloat>, angle: MFloat) -> Matrix4<MFloat> {
        let rad = rad(deg_to_rad(angle));
        let r = Matrix3::from_angle_z(rad).to_matrix4();
        m.mul_m(&r)
    }
    */

    pub fn check(&self) {
        let error_code = unsafe { self.gl.GetError() };
        if error_code != 0 {
            let description = match error_code {
                gl::INVALID_ENUM => "GL_INVALID_ENUM",
                gl::INVALID_FRAMEBUFFER_OPERATION => "GL_INVALID_FRAMEBUFFER_OPERATION",
                gl::INVALID_OPERATION => "GL_INVALID_OPERATION",
                gl::INVALID_VALUE => "GL_INVALID_VALUE",
                gl::NO_ERROR => "GL_NO_ERROR",
                gl::OUT_OF_MEMORY => "GL_OUT_OF_MEMORY",
                _ => panic!("Bad gl error code: {}", error_code),
            };
            panic!("gl error: {}({})", description, error_code);
        }
    }
}

/*
pub enum MeshRenderMode {
    Triangles,
    Lines,
}

impl MeshRenderMode {
    fn to_gl_type(&self) -> GLuint {
        match *self {
            MeshRenderMode::Triangles => gl::TRIANGLES,
            MeshRenderMode::Lines => gl::LINES,
        }
    }
}
*/

/*
pub fn init_opengl() {
    verify!(gl::Enable(gl::DEPTH_TEST));
    verify!(gl::Enable(gl::BLEND));
    verify!(gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA));
}
*/

/*
pub struct Vao {
    id: GLuint,
}

impl Vao {
    pub fn new(mgl: &Mgl) -> Vao {
        let mut id = 0;
        unsafe {
            mgl.gl.GenVertexArrays(1, &mut id);
        }
        mgl.check();
        let vao = Vao{id: id};
        vao.bind();
        vao
    }

    pub fn bind(&self) {
        gl.BindVertexArray(self.id);
        mgl.check();
    }

    pub fn unbind(&self) {
        gl.BindVertexArray(0);
        mgl.check();
    }

    pub fn draw_array(&self, mesh_mode: MeshRenderMode, faces_count: MInt) {
        let starting_index = 0;
        let vertices_count = faces_count * 3;
        let mode = mesh_mode.to_gl_type();
        gl.DrawArrays(mode, starting_index, vertices_count);
        mgl.check();
    }
}

impl Drop for Vao {
    fn drop(&mut self) {
        unsafe {
            gl.DeleteVertexArrays(1, &self.id);
        }
        mgl.check();
    }
}
*/

/*
pub struct Vbo {
    id: GLuint,
}

fn get_new_vbo_id() -> GLuint {
    let mut id = 0;
    unsafe {
        verify!(gl::GenBuffers(1, &mut id));
    }
    id
}

impl Vbo {
    pub fn from_data<T>(data: &[T]) -> Vbo {
        let vbo = Vbo{id: get_new_vbo_id()};
        vbo.bind();
        let size = std::mem::size_of::<T>();
        let buf_size = (data.len() * size) as GLsizeiptr;
        if data.len() != 0 {
            unsafe {
                let data_ptr = std::mem::transmute(&data[0]);
                verify!(gl::BufferData(
                    gl::ARRAY_BUFFER,
                    buf_size,
                    data_ptr,
                    gl::STATIC_DRAW,
                ));
            }
        }
        vbo
    }

    pub fn bind(&self) {
        verify!(gl::BindBuffer(gl::ARRAY_BUFFER, self.id));
    }
}

impl Drop for Vbo {
    fn drop(&mut self) {
        unsafe {
            verify!(gl::DeleteBuffers(1, &self.id));
        }
    }
}
*/

/*
pub fn read_pixel_bytes(
    win_size: Size2<MInt>,
    mouse_pos: ScreenPos,
) -> (MInt, MInt, MInt, MInt) {
    let height = win_size.h;
    let reverted_h = height - mouse_pos.v.y;
    let data: [u8, ..4] = [0, 0, 0, 0]; // mut
    unsafe {
        let data_ptr = std::mem::transmute(&data[0]);
        verify!(gl::ReadPixels(
            mouse_pos.v.x, reverted_h, 1, 1,
            gl::RGBA,
            gl::UNSIGNED_BYTE,
            data_ptr
        ));
    }
    (data[0] as MInt, data[1] as MInt, data[2] as MInt, data[3] as MInt)
}

pub fn get_2d_screen_matrix(win_size: Size2<MInt>) -> Matrix4<MFloat> {
    let left = 0.0;
    let right = win_size.w as MFloat;
    let bottom = 0.0;
    let top = win_size.h as MFloat;
    let near = -1.0;
    let far = 1.0;
    ortho(left, right, bottom, top, near, far)
}
*/

pub fn compile_shader(gl: &Gl, src: &str, ty: GLenum) -> GLuint {
    let shader;
    unsafe {
        shader = gl.CreateShader(ty);
        src.with_c_str(|ptr| gl.ShaderSource(shader, 1, &ptr, ptr::null()));
        gl.CompileShader(shader);
        {
            let mut status = gl::FALSE as GLint;
            gl.GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
            assert!(status == gl::TRUE as GLint);
        }
    }
    shader
}

pub fn link_program(gl: &Gl, vs: GLuint, fs: GLuint) -> GLuint {
    unsafe {
        let program = gl.CreateProgram();
        gl.AttachShader(program, vs);
        gl.AttachShader(program, fs);
        gl.LinkProgram(program);
        {
            let mut status = gl::FALSE as GLint;
            gl.GetProgramiv(program, gl::LINK_STATUS, &mut status);
            assert!(status == (gl::TRUE as GLint));
        }
        program
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>mgl.rs: link_program/compile_shader: Added error reporting<commit_after>// See LICENSE file for copyright and license details.

#![macro_escape]

// use std;
// use gl;
// use gl::types::{GLuint, GLsizeiptr};
// use cgmath::{Vector3, rad, ortho};
// use core_misc::deg_to_rad;
// use core_types::{Size2, MInt};
// use visualizer::types::{MFloat, Color3, Color4, ScreenPos};
use visualizer_types::{/*MFloat,*/ Color3};
// use cgmath::{Matrix, Matrix4, Matrix3, ToMatrix4};
use libc::c_void;
use gl;
use gl::types::{GLuint, GLint, GLenum, GLchar};
use std::ptr;
use std::str;

use gl::Gles2 as Gl;

/*
pub const GREY_3: Color3 = Color3{r: 0.3, g: 0.3, b: 0.3};
pub const BLACK_3: Color3 = Color3{r: 0.0, g: 0.0, b: 0.0};
pub const WHITE: Color4 = Color4{r: 1.0, g: 1.0, b: 1.0, a: 1.0};
pub const BLUE: Color4 = Color4{r: 0.0, g: 0.0, b: 1.0, a: 1.0};
pub const BLACK: Color4 = Color4{r: 0.0, g: 0.0, b: 0.0, a: 1.0};
*/

pub struct Mgl {
    pub gl: Gl,
}

impl Mgl {
    pub fn new(get_proc_address: |&str| -> *const c_void) -> Mgl {
        let gl = Gl::load_with(|s| get_proc_address(s));
    	Mgl{gl: gl}
    }

    pub fn set_clear_color(&mut self, color: Color3) {
        unsafe {
            self.gl.ClearColor(color.r, color.g, color.b, 1.0);
        }
        self.check();
    }

    pub fn clear_screen(&self) {
        unsafe {
            self.gl.Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
        self.check();
    }

    /*
    pub fn set_viewport(&mut self, size: Size2<MInt>) {
        unsafe {
            self.gl.Viewport(0, 0, size.w, size.h);
        }
        self.check();
    }

    // TODO: replace with something from cgmath-rs
    pub fn tr(&self, m: Matrix4<MFloat>, v: Vector3<MFloat>) -> Matrix4<MFloat> {
        let mut t = Matrix4::<MFloat>::identity();
        t[3][0] = v.x;
        t[3][1] = v.y;
        t[3][2] = v.z;
        m.mul_m(&t)
    }

    pub fn scale(&self, m: Matrix4<MFloat>, scale: MFloat) -> Matrix4<MFloat> {
        let mut t = Matrix4::<MFloat>::identity();
        t[0][0] = scale;
        t[1][1] = scale;
        t[2][2] = scale;
        m.mul_m(&t)
    }

    pub fn rot_x(&self, m: Matrix4<MFloat>, angle: MFloat) -> Matrix4<MFloat> {
        let rad = rad(deg_to_rad(angle));
        let r = Matrix3::from_angle_x(rad).to_matrix4();
        m.mul_m(&r)
    }

    pub fn rot_z(&self, m: Matrix4<MFloat>, angle: MFloat) -> Matrix4<MFloat> {
        let rad = rad(deg_to_rad(angle));
        let r = Matrix3::from_angle_z(rad).to_matrix4();
        m.mul_m(&r)
    }
    */

    pub fn check(&self) {
        let error_code = unsafe { self.gl.GetError() };
        if error_code != 0 {
            let description = match error_code {
                gl::INVALID_ENUM => "GL_INVALID_ENUM",
                gl::INVALID_FRAMEBUFFER_OPERATION => "GL_INVALID_FRAMEBUFFER_OPERATION",
                gl::INVALID_OPERATION => "GL_INVALID_OPERATION",
                gl::INVALID_VALUE => "GL_INVALID_VALUE",
                gl::NO_ERROR => "GL_NO_ERROR",
                gl::OUT_OF_MEMORY => "GL_OUT_OF_MEMORY",
                _ => panic!("Bad gl error code: {}", error_code),
            };
            panic!("gl error: {}({})", description, error_code);
        }
    }
}

/*
pub enum MeshRenderMode {
    Triangles,
    Lines,
}

impl MeshRenderMode {
    fn to_gl_type(&self) -> GLuint {
        match *self {
            MeshRenderMode::Triangles => gl::TRIANGLES,
            MeshRenderMode::Lines => gl::LINES,
        }
    }
}
*/

/*
pub fn init_opengl() {
    verify!(gl::Enable(gl::DEPTH_TEST));
    verify!(gl::Enable(gl::BLEND));
    verify!(gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA));
}
*/

/*
pub struct Vao {
    id: GLuint,
}

impl Vao {
    pub fn new(mgl: &Mgl) -> Vao {
        let mut id = 0;
        unsafe {
            mgl.gl.GenVertexArrays(1, &mut id);
        }
        mgl.check();
        let vao = Vao{id: id};
        vao.bind();
        vao
    }

    pub fn bind(&self) {
        gl.BindVertexArray(self.id);
        mgl.check();
    }

    pub fn unbind(&self) {
        gl.BindVertexArray(0);
        mgl.check();
    }

    pub fn draw_array(&self, mesh_mode: MeshRenderMode, faces_count: MInt) {
        let starting_index = 0;
        let vertices_count = faces_count * 3;
        let mode = mesh_mode.to_gl_type();
        gl.DrawArrays(mode, starting_index, vertices_count);
        mgl.check();
    }
}

impl Drop for Vao {
    fn drop(&mut self) {
        unsafe {
            gl.DeleteVertexArrays(1, &self.id);
        }
        mgl.check();
    }
}
*/

/*
pub struct Vbo {
    id: GLuint,
}

fn get_new_vbo_id() -> GLuint {
    let mut id = 0;
    unsafe {
        verify!(gl::GenBuffers(1, &mut id));
    }
    id
}

impl Vbo {
    pub fn from_data<T>(data: &[T]) -> Vbo {
        let vbo = Vbo{id: get_new_vbo_id()};
        vbo.bind();
        let size = std::mem::size_of::<T>();
        let buf_size = (data.len() * size) as GLsizeiptr;
        if data.len() != 0 {
            unsafe {
                let data_ptr = std::mem::transmute(&data[0]);
                verify!(gl::BufferData(
                    gl::ARRAY_BUFFER,
                    buf_size,
                    data_ptr,
                    gl::STATIC_DRAW,
                ));
            }
        }
        vbo
    }

    pub fn bind(&self) {
        verify!(gl::BindBuffer(gl::ARRAY_BUFFER, self.id));
    }
}

impl Drop for Vbo {
    fn drop(&mut self) {
        unsafe {
            verify!(gl::DeleteBuffers(1, &self.id));
        }
    }
}
*/

/*
pub fn read_pixel_bytes(
    win_size: Size2<MInt>,
    mouse_pos: ScreenPos,
) -> (MInt, MInt, MInt, MInt) {
    let height = win_size.h;
    let reverted_h = height - mouse_pos.v.y;
    let data: [u8, ..4] = [0, 0, 0, 0]; // mut
    unsafe {
        let data_ptr = std::mem::transmute(&data[0]);
        verify!(gl::ReadPixels(
            mouse_pos.v.x, reverted_h, 1, 1,
            gl::RGBA,
            gl::UNSIGNED_BYTE,
            data_ptr
        ));
    }
    (data[0] as MInt, data[1] as MInt, data[2] as MInt, data[3] as MInt)
}

pub fn get_2d_screen_matrix(win_size: Size2<MInt>) -> Matrix4<MFloat> {
    let left = 0.0;
    let right = win_size.w as MFloat;
    let bottom = 0.0;
    let top = win_size.h as MFloat;
    let near = -1.0;
    let far = 1.0;
    ortho(left, right, bottom, top, near, far)
}
*/

pub fn compile_shader(gl: &Gl, src: &str, ty: GLenum) -> GLuint {
    let shader;
    unsafe {
        shader = gl.CreateShader(ty);
        src.with_c_str(|ptr| gl.ShaderSource(shader, 1, &ptr, ptr::null()));
        gl.CompileShader(shader);
        {
            let mut status = gl::FALSE as GLint;
            gl.GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
            if status != gl::TRUE as GLint {
                let mut len = 0;
                gl.GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
                // subtract 1 to skip the trailing null character
                let mut buf = Vec::from_elem(len as uint - 1, 0u8);
                gl.GetShaderInfoLog(
                    shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                panic!("{}", str::from_utf8(buf.as_slice())
                    .expect("ShaderInfoLog not valid utf8"));
            }
        }
    }
    shader
}

pub fn link_program(gl: &Gl, vs: GLuint, fs: GLuint) -> GLuint {
    unsafe {
        let program = gl.CreateProgram();
        gl.AttachShader(program, vs);
        gl.AttachShader(program, fs);
        gl.LinkProgram(program);
        {
            let mut status = gl::FALSE as GLint;
            gl.GetProgramiv(program, gl::LINK_STATUS, &mut status);
            if status != gl::TRUE as GLint {
                let mut len: GLint = 0;
                gl.GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
                // subtract 1 to skip the trailing null character
                let mut buf = Vec::from_elem(len as uint - 1, 0u8);
                gl.GetProgramInfoLog(
                    program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
                panic!("{}", str::from_utf8(buf.as_slice())
                    .expect("ProgramInfoLog not valid utf8"));
            }
        }
        program
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! jsonrpc server over unix sockets
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//! extern crate rand;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::IoHandler;
use std::sync::*;
use std::sync::atomic::*;
use std;
use slab;
use validator;
#[cfg(test)]
use tests;
use std::collections::VecDeque;

const SERVER: Token = Token(0);
const MAX_CONCURRENT_CONNECTIONS: usize = 16;
const MAX_WRITE_LENGTH: usize = 8192;

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

type Slab<T> = slab::Slab<T, Token>;

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(4096)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
			if buf.remaining() < MAX_WRITE_LENGTH {
	            try!(self.socket.write_all(&buf.bytes()));
				self.interest.remove(EventSet::writable());
				self.interest.insert(EventSet::readable());
			}
			else {
				try!(self.socket.write_all(&buf.bytes()[0..MAX_WRITE_LENGTH]));
				self.buf = Some(ByteBuf::from_slice(&buf.bytes()[MAX_WRITE_LENGTH..]));
			}
        }

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
				trace!(target: "ipc", "Empty read ({:?})", self.token);
                self.mut_buf = Some(buf);
				return Ok(());
            }
            Ok(Some(_)) => {
                let (requests, last_index) = validator::extract_requests(buf.bytes());
                if requests.len() > 0 {
                    let mut response_bytes = Vec::new();
                    for rpc_msg in requests {
                        trace!(target: "ipc", "Request: {}", rpc_msg);
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            trace!(target: "ipc", "Response: {}", &response_str);
                            response_bytes.extend(response_str.into_bytes());
                        }
                    }
                    self.buf = Some(ByteBuf::from_slice(&response_bytes[..]));

                    let mut new_buf = ByteBuf::mut_with_capacity(4096);
                    new_buf.write_slice(&buf.bytes()[last_index+1..]);
                    self.mut_buf = Some(new_buf);

                    self.interest.remove(EventSet::readable());
                    self.interest.insert(EventSet::writable());
                }
                else {
                    self.mut_buf = Some(buf);
                }
            }
            Err(e) => {
                trace!(target: "ipc", "Error receiving data ({:?}): {:?}", self.token, e);
                self.interest.remove(EventSet::readable());
            }

        };
        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
	tokens: VecDeque<Token>,
}

pub struct Server {
    rpc_server: Arc<RwLock<RpcServer>>,
    event_loop: Arc<RwLock<EventLoop<RpcServer>>>,
    is_stopping: Arc<AtomicBool>,
    is_stopped: Arc<AtomicBool>,
    addr: String,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    NotStarted,
    AlreadyStopping,
    NotStopped,
    IsStopping,
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: Arc::new(RwLock::new(server)),
            event_loop: Arc::new(RwLock::new(event_loop)),
            is_stopping: Arc::new(AtomicBool::new(false)),
            is_stopped: Arc::new(AtomicBool::new(true)),
            addr: socket_addr.to_owned(),
        })
    }

    /// Run server (in current thread)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests (for manual async scenarios)
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }

    /// Run server (in separate thread)
    pub fn run_async(&self) -> Result<(), Error> {
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::IsStopping) }
        if !self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStopped) }

        self.is_stopped.store(false, Ordering::Relaxed);

        let event_loop = self.event_loop.clone();
        let server = self.rpc_server.clone();
        let thread_stopping = self.is_stopping.clone();
        let thread_stopped = self.is_stopped.clone();
        std::thread::spawn(move || {
            let mut event_loop = event_loop.write().unwrap();
            let mut server = server.write().unwrap();
            while !thread_stopping.load(Ordering::Relaxed) {
                event_loop.run_once(&mut server, Some(100)).unwrap();
            }
            thread_stopped.store(true, Ordering::Relaxed);
        });
        Ok(())
    }

    pub fn stop_async(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        Ok(())
    }

    pub fn stop(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        while !self.is_stopped.load(Ordering::Relaxed) { std::thread::sleep(std::time::Duration::new(0, 10)); }
        Ok(())
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.stop().unwrap_or_else(|_| {}); // ignore error - can be stopped already
        ::std::fs::remove_file(&self.addr).unwrap_or_else(|_| {}); // ignoer error - server could have never been started
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), MAX_CONCURRENT_CONNECTIONS),
            io_handler: io_handler.clone(),
			tokens: VecDeque::new(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        if self.connections.count() >= MAX_CONCURRENT_CONNECTIONS {
            let oldest_token = self.tokens.pop_front()
                .expect("fatal: impossible since count > MAX_CONCURRENT_CONNECTIONS and we request the oldest one")
                .clone();

            self.connections.remove(oldest_token).expect("There is max connections here");
			trace!(target: "ipc", "Reusing the most old token {:?}", oldest_token);
        }
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connection to slab (memory issue?)");
		self.tokens.push_back(token);

		trace!(target: "ipc", "Accepted connection with token {:?}", token);

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("fatal: could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }
}

impl Handler for RpcServer {
    type Timeout = usize;
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[test]
pub fn test_reqrep_poll() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    let server = Server::new(&addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
    assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}

#[test]
pub fn test_file_removed() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    {
        let server = Server::new(&addr, &io).unwrap();
        server.run_async().unwrap();
        std::thread::sleep(std::time::Duration::from_millis(50));

        let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
        let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
        assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());
    }
    assert!(::std::fs::metadata(addr).is_err()); // err is file not exists
}
<commit_msg>add hup drop<commit_after>// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

//! jsonrpc server over unix sockets
//!
//! ```no_run
//! extern crate jsonrpc_core;
//! extern crate json_ipc_server;
//! extern crate rand;
//!
//! use std::sync::Arc;
//! use jsonrpc_core::*;
//! use json_ipc_server::Server;
//!
//! struct SayHello;
//! impl MethodCommand for SayHello {
//! 	fn execute(&self, _params: Params) -> Result<Value, Error> {
//! 		Ok(Value::String("hello".to_string()))
//! 	}
//! }
//!
//! fn main() {
//! 	let io = IoHandler::new();
//! 	io.add_method("say_hello", SayHello);
//! 	let server = Server::new("/tmp/json-ipc-test.ipc", &Arc::new(io)).unwrap();
//!     ::std::thread::spawn(move || server.run());
//! }
//! ```

use mio::*;
use mio::unix::*;
use bytes::{Buf, ByteBuf, MutByteBuf};
use std::io;
use jsonrpc_core::IoHandler;
use std::sync::*;
use std::sync::atomic::*;
use std;
use slab;
use validator;
#[cfg(test)]
use tests;
use std::collections::VecDeque;

const SERVER: Token = Token(0);
const MAX_CONCURRENT_CONNECTIONS: usize = 16;
const MAX_WRITE_LENGTH: usize = 8192;

struct SocketConnection {
    socket: UnixStream,
    buf: Option<ByteBuf>,
    mut_buf: Option<MutByteBuf>,
    token: Option<Token>,
    interest: EventSet,
}

type Slab<T> = slab::Slab<T, Token>;

impl SocketConnection {
    fn new(sock: UnixStream) -> Self {
        SocketConnection {
            socket: sock,
            buf: None,
            mut_buf: Some(ByteBuf::mut_with_capacity(4096)),
            token: None,
            interest: EventSet::hup(),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<RpcServer>, _handler: &IoHandler) -> io::Result<()> {
        use std::io::Write;
        if let Some(buf) = self.buf.take() {
			if buf.remaining() < MAX_WRITE_LENGTH {
	            try!(self.socket.write_all(&buf.bytes()));
				self.interest.remove(EventSet::writable());
				self.interest.insert(EventSet::readable());
			}
			else {
				try!(self.socket.write_all(&buf.bytes()[0..MAX_WRITE_LENGTH]));
				self.buf = Some(ByteBuf::from_slice(&buf.bytes()[MAX_WRITE_LENGTH..]));
			}
        }

        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }

    fn readable(&mut self, event_loop: &mut EventLoop<RpcServer>, handler: &IoHandler) -> io::Result<()> {
        let mut buf = self.mut_buf.take().unwrap_or_else(|| panic!("unwrapping mutable buffer which is None"));

        match self.socket.try_read_buf(&mut buf) {
            Ok(None) => {
				trace!(target: "ipc", "Empty read ({:?})", self.token);
                self.mut_buf = Some(buf);
				return Ok(());
            }
            Ok(Some(_)) => {
                let (requests, last_index) = validator::extract_requests(buf.bytes());
                if requests.len() > 0 {
                    let mut response_bytes = Vec::new();
                    for rpc_msg in requests {
                        trace!(target: "ipc", "Request: {}", rpc_msg);
                        let response: Option<String> = handler.handle_request(&rpc_msg);
                        if let Some(response_str) = response {
                            trace!(target: "ipc", "Response: {}", &response_str);
                            response_bytes.extend(response_str.into_bytes());
                        }
                    }
                    self.buf = Some(ByteBuf::from_slice(&response_bytes[..]));

                    let mut new_buf = ByteBuf::mut_with_capacity(4096);
                    new_buf.write_slice(&buf.bytes()[last_index+1..]);
                    self.mut_buf = Some(new_buf);

                    self.interest.remove(EventSet::readable());
                    self.interest.insert(EventSet::writable());
                }
                else {
                    self.mut_buf = Some(buf);
                }
            }
            Err(e) => {
                trace!(target: "ipc", "Error receiving data ({:?}): {:?}", self.token, e);
                self.interest.remove(EventSet::readable());
            }

        };
        event_loop.reregister(&self.socket, self.token.unwrap(), self.interest, PollOpt::edge() | PollOpt::oneshot())
    }
}

struct RpcServer {
    socket: UnixListener,
    connections: Slab<SocketConnection>,
    io_handler: Arc<IoHandler>,
	tokens: VecDeque<Token>,
}

pub struct Server {
    rpc_server: Arc<RwLock<RpcServer>>,
    event_loop: Arc<RwLock<EventLoop<RpcServer>>>,
    is_stopping: Arc<AtomicBool>,
    is_stopped: Arc<AtomicBool>,
    addr: String,
}

#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    NotStarted,
    AlreadyStopping,
    NotStopped,
    IsStopping,
}

impl std::convert::From<std::io::Error> for Error {
    fn from(io_error: std::io::Error) -> Error {
        Error::Io(io_error)
    }
}

impl Server {
    /// New server
    pub fn new(socket_addr: &str, io_handler: &Arc<IoHandler>) -> Result<Server, Error> {
        let (server, event_loop) = try!(RpcServer::start(socket_addr, io_handler));
        Ok(Server {
            rpc_server: Arc::new(RwLock::new(server)),
            event_loop: Arc::new(RwLock::new(event_loop)),
            is_stopping: Arc::new(AtomicBool::new(false)),
            is_stopped: Arc::new(AtomicBool::new(true)),
            addr: socket_addr.to_owned(),
        })
    }

    /// Run server (in current thread)
    pub fn run(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();
        event_loop.run(&mut server).unwrap();
    }

    /// Poll server requests (for manual async scenarios)
    pub fn poll(&self) {
        let mut event_loop = self.event_loop.write().unwrap();
        let mut server = self.rpc_server.write().unwrap();

        event_loop.run_once(&mut server, Some(100)).unwrap();
    }

    /// Run server (in separate thread)
    pub fn run_async(&self) -> Result<(), Error> {
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::IsStopping) }
        if !self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStopped) }

        self.is_stopped.store(false, Ordering::Relaxed);

        let event_loop = self.event_loop.clone();
        let server = self.rpc_server.clone();
        let thread_stopping = self.is_stopping.clone();
        let thread_stopped = self.is_stopped.clone();
        std::thread::spawn(move || {
            let mut event_loop = event_loop.write().unwrap();
            let mut server = server.write().unwrap();
            while !thread_stopping.load(Ordering::Relaxed) {
                event_loop.run_once(&mut server, Some(100)).unwrap();
            }
            thread_stopped.store(true, Ordering::Relaxed);
        });
        Ok(())
    }

    pub fn stop_async(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        Ok(())
    }

    pub fn stop(&self) -> Result<(), Error> {
        if self.is_stopped.load(Ordering::Relaxed) { return Err(Error::NotStarted) }
        if self.is_stopping.load(Ordering::Relaxed) { return Err(Error::AlreadyStopping)}
        self.is_stopping.store(true, Ordering::Relaxed);
        while !self.is_stopped.load(Ordering::Relaxed) { std::thread::sleep(std::time::Duration::new(0, 10)); }
        Ok(())
    }
}

impl Drop for Server {
    fn drop(&mut self) {
        self.stop().unwrap_or_else(|_| {}); // ignore error - can be stopped already
        ::std::fs::remove_file(&self.addr).unwrap_or_else(|_| {}); // ignoer error - server could have never been started
    }
}

impl RpcServer {

    /// start ipc rpc server (blocking)
    pub fn start(addr: &str, io_handler: &Arc<IoHandler>) -> Result<(RpcServer, EventLoop<RpcServer>), Error> {
        let mut event_loop = try!(EventLoop::new());
        ::std::fs::remove_file(addr).unwrap_or_else(|_| {} ); // ignore error (if no file)
        let socket = try!(UnixListener::bind(&addr));
        event_loop.register(&socket, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();
        let server = RpcServer {
            socket: socket,
            connections: Slab::new_starting_at(Token(1), MAX_CONCURRENT_CONNECTIONS),
            io_handler: io_handler.clone(),
			tokens: VecDeque::new(),
        };
        Ok((server, event_loop))
    }

    fn accept(&mut self, event_loop: &mut EventLoop<RpcServer>) -> io::Result<()> {
        let new_client_socket = self.socket.accept().unwrap().unwrap();
        let connection = SocketConnection::new(new_client_socket);
        if self.connections.count() >= MAX_CONCURRENT_CONNECTIONS {
            let oldest_token = self.tokens.pop_front()
                .expect("fatal: impossible since count > MAX_CONCURRENT_CONNECTIONS and we request the oldest one")
                .clone();

            self.connections.remove(oldest_token).expect("There is max connections here");
			trace!(target: "ipc", "Reusing the most old token {:?}", oldest_token);
        }
        let token = self.connections.insert(connection).ok().expect("fatal: Could not add connection to slab (memory issue?)");
		self.tokens.push_back(token);

		trace!(target: "ipc", "Accepted connection with token {:?}", token);

        self.connections[token].token = Some(token);
        event_loop.register(
            &self.connections[token].socket,
            token,
            EventSet::readable(),
            PollOpt::edge() | PollOpt::oneshot()
        ).ok().expect("fatal: could not register socket with event loop (memory issue?)");

        Ok(())
    }

    fn connection_readable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).readable(event_loop, &io_handler)
    }

    fn connection_writable(&mut self, event_loop: &mut EventLoop<RpcServer>, tok: Token) -> io::Result<()> {
        let io_handler = self.io_handler.clone();
        self.connection(tok).writable(event_loop, &io_handler)
    }

    fn connection<'a>(&'a mut self, tok: Token) -> &'a mut SocketConnection {
        &mut self.connections[tok]
    }

    fn drop_connection(&mut self, tok: Token) {
        trace!(target: "ipc", "Dropping connection {:?}", tok);
        self.connections.remove(tok);
    }
}

impl Handler for RpcServer {
    type Timeout = usize;
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<RpcServer>, token: Token, events: EventSet) {
        if events.is_readable() {
            match token {
                SERVER => self.accept(event_loop).unwrap(),
                _ => self.connection_readable(event_loop, token).unwrap()
            };
        }

        if events.is_hup() {
            match token {
                SERVER => { trace!(target: "ipc", "Server hup"); },
                other_token => {
                    self.drop_connection(other_token)
                }
            }
        }

        if events.is_writable() {
            match token {
                SERVER => { },
                _ => self.connection_writable(event_loop, token).unwrap_or_else(|_| {}), // todo: disqualify connection from list on error
            };
        }
    }
}

#[test]
pub fn test_reqrep_poll() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    let server = Server::new(&addr, &io).unwrap();
    std::thread::spawn(move || {
        loop {
            server.poll();
        }
    });

    let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
    let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
    assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());

    std::thread::sleep(std::time::Duration::from_millis(500));
}

#[test]
pub fn test_file_removed() {
    let addr = tests::random_ipc_endpoint();
    let io = tests::dummy_io_handler();
    {
        let server = Server::new(&addr, &io).unwrap();
        server.run_async().unwrap();
        std::thread::sleep(std::time::Duration::from_millis(50));

        let request = r#"{"jsonrpc": "2.0", "method": "say_hello", "params": [42, 23], "id": 1}"#;
        let response = r#"{"jsonrpc":"2.0","result":"hello 42! you sent 23","id":1}"#;
        assert_eq!(String::from_utf8(tests::dummy_request(&addr, request.as_bytes())).unwrap(), response.to_string());
    }
    assert!(::std::fs::metadata(addr).is_err()); // err is file not exists
}
<|endoftext|>