<commit_before>#![feature(custom_derive, quote, plugin, plugin_registrar, rustc_private)]

#[macro_use]
extern crate rustc_plugin;
#[macro_use]
extern crate syntax;

use syntax::ext::base::MultiDecorator;
use syntax::parse::token;
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::build::AstBuilder;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ptr::P;
use rustc_plugin::Registry;

fn expand_derive_tojson(ct: &mut ExtCtxt, span: Span, _: &ast::MetaItem,
                        item: &Annotatable, push: &mut FnMut(Annotatable)) {
    if let Annotatable::Item(ref item) = *item {
        if let ast::ItemStruct(ref struct_def, ref generics) = item.node {
            let struct_name = item.ident;

            let lifetimes: Vec<ast::Lifetime> = generics.lifetimes.iter().map(|ld| ld.lifetime).collect();
            let generic_parameters: Vec<P<ast::Ty>> = generics.ty_params.iter().map(|ty| ct.ty_ident(span, ty.ident)).collect();
            let struct_ty = ct.ty_path(ct.path_all(span, false, vec![struct_name], lifetimes, generic_parameters, Vec::new()));
            let where_clause = generics.clone().where_clause;

            let conv_body: Vec<P<ast::Expr>> = struct_def.fields().iter().map(|field| {
                if let ast::NamedField(name, _) = field.node.kind {
                    let name_str = name.name.as_str();
                    quote_expr!(ct, {
                        __container.insert($name_str.to_string(), self.$name.to_json());
                    })
                } else {
                    ct.span_fatal(span, "#[derive(ToJson)] doesn't support simple struct for now");
                }
            }).collect();
            let impl_item = quote_item!(ct,
                                        impl $generics ::rustc_serialize::json::ToJson for $struct_ty $where_clause {
                                            fn to_json(&self) -> ::rustc_serialize::json::Json {
                                                let mut __container = ::std::collections::BTreeMap::new();
                                                $conv_body;
                                                ::rustc_serialize::json::Json::Object(__container)
                                            }
                                        }).unwrap();

            //println!("{}", syntax::print::pprust::item_to_string(&impl_item));
            push(Annotatable::Item(impl_item));
        } else {
            ct.span_err(span, "#[derive(ToJson)] is only valid for struct");
        }
    } else {
        ct.span_err(span, "#[derive(ToJson)] is only valid for struct");
    }

}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        token::intern("derive_ToJson"),
        MultiDecorator(Box::new(expand_derive_tojson)));
}
<commit_msg>(fix) use .to_owned() in preference to .to_string()<commit_after>#![feature(custom_derive, quote, plugin, plugin_registrar, rustc_private)]

#[macro_use]
extern crate rustc_plugin;
#[macro_use]
extern crate syntax;

use syntax::ext::base::MultiDecorator;
use syntax::parse::token;
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::build::AstBuilder;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ptr::P;
use rustc_plugin::Registry;

fn expand_derive_tojson(ct: &mut ExtCtxt, span: Span, _: &ast::MetaItem,
                        item: &Annotatable, push: &mut FnMut(Annotatable)) {
    if let Annotatable::Item(ref item) = *item {
        if let ast::ItemStruct(ref struct_def, ref generics) = item.node {
            let struct_name = item.ident;

            let lifetimes: Vec<ast::Lifetime> = generics.lifetimes.iter().map(|ld| ld.lifetime).collect();
            let generic_parameters: Vec<P<ast::Ty>> = generics.ty_params.iter().map(|ty| ct.ty_ident(span, ty.ident)).collect();
            let struct_ty = ct.ty_path(ct.path_all(span, false, vec![struct_name], lifetimes, generic_parameters, Vec::new()));
            let where_clause = generics.clone().where_clause;

            let conv_body: Vec<P<ast::Expr>> = struct_def.fields().iter().map(|field| {
                if let ast::NamedField(name, _) = field.node.kind {
                    let name_str = name.name.as_str();
                    quote_expr!(ct, {
                        __container.insert($name_str.to_owned(), self.$name.to_json());
                    })
                } else {
                    ct.span_fatal(span, "#[derive(ToJson)] doesn't support simple struct for now");
                }
            }).collect();
            let impl_item = quote_item!(ct,
                                        impl $generics ::rustc_serialize::json::ToJson for $struct_ty $where_clause {
                                            fn to_json(&self) -> ::rustc_serialize::json::Json {
                                                let mut __container = ::std::collections::BTreeMap::new();
                                                $conv_body;
                                                ::rustc_serialize::json::Json::Object(__container)
                                            }
                                        }).unwrap();

            //println!("{}", syntax::print::pprust::item_to_string(&impl_item));
            push(Annotatable::Item(impl_item));
        } else {
            ct.span_err(span, "#[derive(ToJson)] is only valid for struct");
        }
    } else {
        ct.span_err(span, "#[derive(ToJson)] is only valid for struct");
    }

}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        token::intern("derive_ToJson"),
        MultiDecorator(Box::new(expand_derive_tojson)));
}
<|endoftext|>


<commit_before>// See the LICENSE file at the top-level directory of this distribution
// for information about copyright and licensing of this code.

//! This crate contains a collection of interesting code in Rust.

pub mod numeric;
<commit_msg>minor formatting change to trigger travis build<commit_after>// See the LICENSE file at the top-level directory of this distribution
// for information about copyright and licensing of this code.

//! This crate contains a collection of interesting code in Rust.

pub mod numeric;
<|endoftext|>


<commit_before>//! Complex numbers

#![deny(missing_docs, warnings)]
#![feature(macro_rules, associated_types, default_type_params)]

extern crate onezero;

use std::fmt;
use std::ops::{Add, Sub, Mul, Div, Neg};
use std::rand::{Rand, Rng};

use onezero::{One, Zero};

mod ffi;
mod math;

pub mod f32;
pub mod f64;

/// A complex number in Cartesian form.
#[repr(C)]
#[derive(Clone, Copy, PartialEq)]
pub struct Complex<T> {
    /// The real part
    pub re: T,
    /// The imaginary part
    pub im: T,
}

/// Single precision complex number
#[allow(non_camel_case_types)]
pub type c64 = Complex<f32>;
/// Double precision complex number
#[allow(non_camel_case_types)]
pub type c128 = Complex<f64>;

impl<T> Complex<T> {
    /// Create a new complex number
    pub fn new(re: T, im: T) -> Complex<T> {
        Complex {
            im: im,
            re: re,
        }
    }
}

impl<T> Complex<T> where T: Add<Output=T> + Clone + Mul<Output=T> {
    fn norm_sqr(self) -> T {
        self.re.clone() * self.re + self.im.clone() * self.im
    }
}

impl<T> Add<T> for Complex<T> where T: Add<Output=T> + Clone {
    type Output = Complex<T>;

    fn add(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re + rhs,
            im: self.im.clone(),
        }
    }
}

impl<T> Add for Complex<T> where T: Add<Output=T> {
    type Output = Complex<T>;

    fn add(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re + rhs.re,
            im: self.im + rhs.im,
        }
    }
}

impl<T> Add<Complex<T>> for T where T: Add<Output=T> + Clone {
    type Output = Complex<T>;

    fn add(self, rhs: Complex<T>) -> Complex<T> {
        rhs + self
    }
}

impl<T> Div<T> for Complex<T> where T: Clone + Div<Output=T> {
    type Output = Complex<T>;

    fn div(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re / rhs.clone(),
            im: self.im / rhs,
        }
    }
}

impl<T> Div for Complex<T> where
    T: Add<Output=T> + Clone + Div<Output=T> + Mul<Output=T> + Sub<Output=T>
{
    type Output = Complex<T>;

    fn div(self, rhs: Complex<T>) -> Complex<T> {
        let den = rhs.clone().norm_sqr();

        Complex {
            re: {
                self.re.clone() * rhs.re.clone() + self.im.clone() * rhs.im.clone()
            } / den.clone(),
            im: (self.im * rhs.re - self.re * rhs.im) / den,
        }
    }
}

impl<T> Div<Complex<T>> for T where
    T: Add<Output=T> + Clone + Div<Output=T> + Mul<Output=T> + Neg<Output=T>,
{
    type Output = Complex<T>;

    fn div(self, rhs: Complex<T>) -> Complex<T> {
        let den = rhs.clone().norm_sqr();

        Complex {
            re: (self.clone() * rhs.re) / den.clone(),
            im: -(self * rhs.im) / den,
        }
    }
}

impl<T> Mul<T> for Complex<T> where T: Clone + Mul<Output=T> {
    type Output = Complex<T>;

    fn mul(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re * rhs.clone(),
            im: self.im * rhs,
        }
    }
}

impl<T> Mul for Complex<T> where
    T: Add<Output=T> + Clone + Mul<Output=T> + Sub<Output=T>,
{
    type Output = Complex<T>;

    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re.clone() * rhs.re.clone() - self.im.clone() * rhs.im.clone(),
            im: self.re * rhs.im + self.im * rhs.re,
        }
    }
}

impl<T> Mul<Complex<T>> for T where T: Clone + Mul<Output=T> {
    type Output = Complex<T>;

    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        rhs * self
    }
}

impl<T> Neg for Complex<T> where T: Neg<Output=T> {
    type Output = Complex<T>;

    fn neg(self) -> Complex<T> {
        Complex {
            re: -self.re,
            im: -self.im,
        }
    }
}

impl<T> One for Complex<T> where T: One + Zero {
    fn one() -> Complex<T> {
        Complex {
            re: One::one(),
            im: Zero::zero(),
        }
    }
}

impl<T> Rand for Complex<T> where T: Rand {
    fn rand<R>(rng: &mut R) -> Complex<T> where R: Rng {
        Complex::new(rng.gen(), rng.gen())
    }
}

impl<T> fmt::Show for Complex<T> where T: PartialOrd + fmt::Show + Zero {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.im < Zero::zero() {
            write!(f, "{}-{}i", self.re, self.im)
        } else {
            write!(f, "{}+{}i", self.re, self.im)
        }
    }
}

impl<T> Sub<T> for Complex<T> where T: Clone + Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re - rhs,
            im: self.im.clone(),
        }
    }
}

impl<T> Sub for Complex<T> where T: Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re - rhs.re,
            im: self.im - rhs.im,
        }
    }
}

impl<T> Sub<Complex<T>> for T where T: Neg<Output=T> + Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self - rhs.re,
            im: -rhs.im,
        }
    }
}

impl<T> Zero for Complex<T> where T: Zero {
    fn zero() -> Complex<T> {
        Complex {
            re: Zero::zero(),
            im: Zero::zero(),
        }
    }
}

/// Mathematical operations on complex numbers
// FIXME (AI) `T` should be an associated output type
pub trait Math<T> {
    /// Computes the complex absolute value (also called norm, modulus or magnitude)
    fn abs(self) -> T;

    /// Computes the arc cosine
    fn acos(self) -> Self;

    /// Computes the arc hyperbolic cosine
    fn acosh(self) -> Self;

    /// Computes the argument (also called the phase angle)
    fn arg(self) -> T;

    /// Computes the arc sine
    fn asin(self) -> Self;

    /// Computes the arc hyperbolic sine
    fn asinh(self) -> Self;

    /// Computes the arc tangent
    fn atan(self) -> Self;

    /// Computes the arc hyperbolic tangent
    fn atanh(self) -> Self;

    /// Computes the arc cosine
    fn cos(self) -> Self;

    /// Computes the arc hyperbolic cosine
    fn cosh(self) -> Self;

    /// Computes the complex base-e exponential
    fn exp(self) -> Self;

    /// Returns the imaginary part
    fn imag(self) -> T;

    /// Computes the complex base-e logarithm
    fn log(self) -> Self;

    /// Computes the complex conjugate
    fn conj(self) -> Self;

    /// Computes the complex power
    fn pow(self, Self) -> Self;

    /// Computes the Riemann sphere projection
    fn proj(self) -> Self;

    /// Returns the real part
    fn real(self) -> T;

    /// Computes the arc sine
    fn sin(self) -> Self;

    /// Computes the arc hyperbolic sine
    fn sinh(self) -> Self;

    /// Computes the square root
    fn sqrt(self) -> Self;

    /// Computes the arc tangent
    fn tan(self) -> Self;

    /// Computes the arc hyperbolic tangent
    fn tanh(self) -> Self;
}

#[cfg(test)]
mod test {
    macro_rules! test {
        ($($ty:ident),+) => {$(
            mod $ty {
                use Complex;
                use $ty::I;

                #[test]
                fn constructor() {
                    assert_eq!(Complex::new(3., 4.), I * 4. + 3.)
                }
            })+
         }
    }

    test!(f32, f64);
}
<commit_msg>fix: update to rust nightly<commit_after>//! Complex numbers

#![allow(unstable)]
#![deny(missing_docs, warnings)]

extern crate onezero;

use std::fmt;
use std::ops::{Add, Sub, Mul, Div, Neg};
use std::rand::{Rand, Rng};

use onezero::{One, Zero};

mod ffi;
mod math;

pub mod f32;
pub mod f64;

/// A complex number in Cartesian form.
#[repr(C)]
#[derive(Clone, Copy, PartialEq)]
pub struct Complex<T> {
    /// The real part
    pub re: T,
    /// The imaginary part
    pub im: T,
}

/// Single precision complex number
#[allow(non_camel_case_types)]
pub type c64 = Complex<f32>;
/// Double precision complex number
#[allow(non_camel_case_types)]
pub type c128 = Complex<f64>;

impl<T> Complex<T> {
    /// Create a new complex number
    pub fn new(re: T, im: T) -> Complex<T> {
        Complex {
            im: im,
            re: re,
        }
    }
}

impl<T> Complex<T> where T: Add<Output=T> + Clone + Mul<Output=T> {
    fn norm_sqr(self) -> T {
        self.re.clone() * self.re + self.im.clone() * self.im
    }
}

impl<T> Add<T> for Complex<T> where T: Add<Output=T> + Clone {
    type Output = Complex<T>;

    fn add(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re + rhs,
            im: self.im.clone(),
        }
    }
}

impl<T> Add for Complex<T> where T: Add<Output=T> {
    type Output = Complex<T>;

    fn add(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re + rhs.re,
            im: self.im + rhs.im,
        }
    }
}

/* FIXME(rust-lang/rust#20749)
impl<T> Add<Complex<T>> for T where T: Add<Output=T> + Clone {
    type Output = Complex<T>;

    fn add(self, rhs: Complex<T>) -> Complex<T> {
        rhs + self
    }
}
*/

impl<T> Div<T> for Complex<T> where T: Clone + Div<Output=T> {
    type Output = Complex<T>;

    fn div(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re / rhs.clone(),
            im: self.im / rhs,
        }
    }
}

impl<T> Div for Complex<T> where
    T: Add<Output=T> + Clone + Div<Output=T> + Mul<Output=T> + Sub<Output=T>
{
    type Output = Complex<T>;

    fn div(self, rhs: Complex<T>) -> Complex<T> {
        let den = rhs.clone().norm_sqr();

        Complex {
            re: {
                self.re.clone() * rhs.re.clone() + self.im.clone() * rhs.im.clone()
            } / den.clone(),
            im: (self.im * rhs.re - self.re * rhs.im) / den,
        }
    }
}

/* FIXME(rust-lang/rust#20749)
impl<T> Div<Complex<T>> for T where
    T: Add<Output=T> + Clone + Div<Output=T> + Mul<Output=T> + Neg<Output=T>,
{
    type Output = Complex<T>;

    fn div(self, rhs: Complex<T>) -> Complex<T> {
        let den = rhs.clone().norm_sqr();

        Complex {
            re: (self.clone() * rhs.re) / den.clone(),
            im: -(self * rhs.im) / den,
        }
    }
}
*/

impl<T> Mul<T> for Complex<T> where T: Clone + Mul<Output=T> {
    type Output = Complex<T>;

    fn mul(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re * rhs.clone(),
            im: self.im * rhs,
        }
    }
}

impl<T> Mul for Complex<T> where
    T: Add<Output=T> + Clone + Mul<Output=T> + Sub<Output=T>,
{
    type Output = Complex<T>;

    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re.clone() * rhs.re.clone() - self.im.clone() * rhs.im.clone(),
            im: self.re * rhs.im + self.im * rhs.re,
        }
    }
}

/* FIXME(rust-lang/rust#20749)
impl<T> Mul<Complex<T>> for T where T: Clone + Mul<Output=T> {
    type Output = Complex<T>;

    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        rhs * self
    }
}
*/

impl<T> Neg for Complex<T> where T: Neg<Output=T> {
    type Output = Complex<T>;

    fn neg(self) -> Complex<T> {
        Complex {
            re: -self.re,
            im: -self.im,
        }
    }
}

impl<T> One for Complex<T> where T: One + Zero {
    fn one() -> Complex<T> {
        Complex {
            re: One::one(),
            im: Zero::zero(),
        }
    }
}

impl<T> Rand for Complex<T> where T: Rand {
    fn rand<R>(rng: &mut R) -> Complex<T> where R: Rng {
        Complex::new(rng.gen(), rng.gen())
    }
}

impl<T> fmt::Show for Complex<T> where T: PartialOrd + fmt::Show + Zero {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.im < Zero::zero() {
            write!(f, "{:?}-{:?}i", self.re, self.im)
        } else {
            write!(f, "{:?}+{:?}i", self.re, self.im)
        }
    }
}

impl<T> Sub<T> for Complex<T> where T: Clone + Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: T) -> Complex<T> {
        Complex {
            re: self.re - rhs,
            im: self.im.clone(),
        }
    }
}

impl<T> Sub for Complex<T> where T: Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self.re - rhs.re,
            im: self.im - rhs.im,
        }
    }
}

/* FIXME(rust-lang/rust#20749)
impl<T> Sub<Complex<T>> for T where T: Neg<Output=T> + Sub<Output=T> {
    type Output = Complex<T>;

    fn sub(self, rhs: Complex<T>) -> Complex<T> {
        Complex {
            re: self - rhs.re,
            im: -rhs.im,
        }
    }
}
*/

impl<T> Zero for Complex<T> where T: Zero {
    fn zero() -> Complex<T> {
        Complex {
            re: Zero::zero(),
            im: Zero::zero(),
        }
    }
}

/// Mathematical operations on complex numbers
// FIXME (AI) `T` should be an associated output type
pub trait Math<T> {
    /// Computes the complex absolute value (also called norm, modulus or magnitude)
    fn abs(self) -> T;

    /// Computes the arc cosine
    fn acos(self) -> Self;

    /// Computes the arc hyperbolic cosine
    fn acosh(self) -> Self;

    /// Computes the argument (also called the phase angle)
    fn arg(self) -> T;

    /// Computes the arc sine
    fn asin(self) -> Self;

    /// Computes the arc hyperbolic sine
    fn asinh(self) -> Self;

    /// Computes the arc tangent
    fn atan(self) -> Self;

    /// Computes the arc hyperbolic tangent
    fn atanh(self) -> Self;

    /// Computes the arc cosine
    fn cos(self) -> Self;

    /// Computes the arc hyperbolic cosine
    fn cosh(self) -> Self;

    /// Computes the complex base-e exponential
    fn exp(self) -> Self;

    /// Returns the imaginary part
    fn imag(self) -> T;

    /// Computes the complex base-e logarithm
    fn log(self) -> Self;

    /// Computes the complex conjugate
    fn conj(self) -> Self;

    /// Computes the complex power
    fn pow(self, Self) -> Self;

    /// Computes the Riemann sphere projection
    fn proj(self) -> Self;

    /// Returns the real part
    fn real(self) -> T;

    /// Computes the arc sine
    fn sin(self) -> Self;

    /// Computes the arc hyperbolic sine
    fn sinh(self) -> Self;

    /// Computes the square root
    fn sqrt(self) -> Self;

    /// Computes the arc tangent
    fn tan(self) -> Self;

    /// Computes the arc hyperbolic tangent
    fn tanh(self) -> Self;
}

#[cfg(test)]
mod test {
    macro_rules! test {
        ($($ty:ident),+) => {$(
            mod $ty {
                use Complex;
                use $ty::I;

                #[test]
                fn constructor() {
                    assert_eq!(Complex::new(3., 4.), I * 4. + 3.)
                }
            })+
         }
    }

    test!(f32, f64);
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;

macro_rules! expect_string {
    ($value:expr) => (try!(
        match $value.as_string() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected string value")})
        }
    ))
}

macro_rules! expect_f64 {
    ($value:expr) => (try!(
        match $value.as_f64() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected f64 value")})
        }
    ))
}

macro_rules! expect_array {
    ($value:expr) => (try!(
        match $value.as_array() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected array value")})
        }
    ))
}

macro_rules! expect_object {
    ($value:expr) => (try!(
        match $value.as_object() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected object value")})
        }
    ))
}

macro_rules! expect_property {
    ($obj:expr, $name:expr, $desc:expr) => (
        match $obj.get($name) {
            Some(v) => v,
            None => return Err({use GeoJsonError; GeoJsonError::new($desc)}),
        };
    )
}

mod types;

#[derive(Copy)]
pub struct GeoJsonError {
    pub desc: &'static str,
}

impl GeoJsonError {
    pub fn new(desc: &'static str) -> GeoJsonError {
        GeoJsonError{desc: desc}
    }
}

pub type GeoJsonResult<T> = Result<T, GeoJsonError>;
<commit_msg>Remove explicit derive copy<commit_after>// Copyright 2014-2015 The GeoRust Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate rustc_serialize;

pub use types::pos::Pos;

pub use types::ring::Ring;

pub use types::point::Point;
pub use types::multipoint::MultiPoint;

pub use types::linestring::LineString;
pub use types::multilinestring::MultiLineString;

pub use types::poly::Poly;
pub use types::polygon::Polygon;
pub use types::multipolygon::MultiPolygon;

pub use types::geometry::Geometry;
pub use types::geometrycollection::GeometryCollection;

pub use types::feature::Feature;
pub use types::featurecollection::FeatureCollection;

macro_rules! expect_string {
    ($value:expr) => (try!(
        match $value.as_string() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected string value")})
        }
    ))
}

macro_rules! expect_f64 {
    ($value:expr) => (try!(
        match $value.as_f64() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected f64 value")})
        }
    ))
}

macro_rules! expect_array {
    ($value:expr) => (try!(
        match $value.as_array() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected array value")})
        }
    ))
}

macro_rules! expect_object {
    ($value:expr) => (try!(
        match $value.as_object() {
            Some(v) => Ok(v),
            None => Err({use GeoJsonError; GeoJsonError::new("Expected object value")})
        }
    ))
}

macro_rules! expect_property {
    ($obj:expr, $name:expr, $desc:expr) => (
        match $obj.get($name) {
            Some(v) => v,
            None => return Err({use GeoJsonError; GeoJsonError::new($desc)}),
        };
    )
}

mod types;

pub struct GeoJsonError {
    pub desc: &'static str,
}

impl GeoJsonError {
    pub fn new(desc: &'static str) -> GeoJsonError {
        GeoJsonError{desc: desc}
    }
}

pub type GeoJsonResult<T> = Result<T, GeoJsonError>;
<|endoftext|>


<commit_before>//! A simple timer, used to enqueue operations meant to be executed at
//! a given time or after a given delay.

extern crate chrono;

use std::cmp::Ordering;
use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering as AtomicOrdering;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{channel, Sender};
use std::collections::BinaryHeap;
use chrono::{Duration, DateTime, UTC};

/// An item scheduled for delayed execution.
struct Schedule {
    /// The instant at which to execute.
    date: DateTime<UTC>,

    /// The callback to execute.
    cb: Box<FnMut() + Send>,

    /// A mechanism to cancel execution of an item.
    guard: Guard,

    /// If `Some(d)`, the item must be repeated every interval of
    /// length `d`, until cancelled.
    repeat: Option<Duration>
}
impl Ord for Schedule {
    fn cmp(&self, other: &Self) -> Ordering {
        self.date.cmp(&other.date).reverse()
    }
}
impl PartialOrd for Schedule {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.date.partial_cmp(&other.date).map(|ord| ord.reverse())
    }
}
impl Eq for Schedule {
}
impl PartialEq for Schedule {
    fn eq(&self, other: &Self) -> bool {
        self.date.eq(&other.date)
    }
}

/// An operation to be sent across threads.
enum Op {
    /// Schedule a new item for execution.
    Schedule(Schedule),

    /// Stop the thread.
    Stop
}

/// A mutex-based kind-of-channel used to communicate between the
/// Communication thread and the Scheuler thread.
struct WaiterChannel {
    /// Pending messages.
    messages: Mutex<Vec<Op>>,
    /// A condition variable used for waiting.
    condvar: Condvar,
}
impl WaiterChannel {
    fn with_capacity(cap: usize) -> Self {
        WaiterChannel {
            messages: Mutex::new(Vec::with_capacity(cap)),
            condvar: Condvar::new(),
        }
    }
}

struct Scheduler {
    waiter: Arc<WaiterChannel>,
    heap: BinaryHeap<Schedule>,
}

impl Scheduler {
    fn with_capacity(waiter: Arc<WaiterChannel>, capacity: usize) -> Self {
        Scheduler {
            waiter: waiter,
            heap: BinaryHeap::with_capacity(capacity),
        }
    }

    fn run(&mut self) {
        enum Sleep {
            NotAtAll,
            UntilAwakened,
            AtMost(Duration)
        }

        let ref waiter = *self.waiter;
        loop {
            let mut lock = waiter.messages.lock().unwrap();

            // Pop all messages.
            for msg in lock.drain(..) {
                match msg {
                    Op::Stop => {
                        return;
                    }
                    Op::Schedule(sched) => self.heap.push(sched),
                }
            }

            // Pop all the callbacks that are ready.

            // If we don't find
            let mut sleep = Sleep::UntilAwakened;
            loop {
                let now = UTC::now();
                if let Some(sched) = self.heap.peek() {
                    if sched.date > now {
                        // First item is not ready yet, so we need to
                        // wait until it is or something happens.
                        sleep = Sleep::AtMost(sched.date - now);
                        break;
                    }
                } else {
                    // Schedule is empty, nothing to do, wait until something happens.
                    break;
                }
                // At this stage, we have an item that has reached
                // execution time. The `unwrap()` is guaranteed to
                // succeed.
                let mut sched = self.heap.pop().unwrap();
                if !sched.guard.should_execute() {
                    // Execution has been cancelled, skip this item.
                    continue;
                }
                (sched.cb)();
                if let Some(delta) = sched.repeat {
                    // This is a repeating timer, so we need to
                    // enqueue the next call.
                    sleep = Sleep::NotAtAll;
                    self.heap.push(Schedule {
                        date: sched.date + delta,
                        cb: sched.cb,
                        guard: sched.guard,
                        repeat: Some(delta)
                    });
                }
            }

            match sleep {
                Sleep::UntilAwakened => {
                    let _ = waiter.condvar.wait(lock);
                },
                Sleep::AtMost(delay) => {
                    let sec = delay.num_seconds();
                    let ns = (delay - Duration::seconds(sec)).num_nanoseconds().unwrap(); // This `unwrap()` asserts that the number of ns is not > 1_000_000_000. Since we just substracted the number of seconds, the assertion should always pass.
                    let duration = std::time::Duration::new(sec as u64, ns as u32);
                    let _ = waiter.condvar.wait_timeout(lock, duration);
                },
                Sleep::NotAtAll => {}
            }
        }
    }
}

/// A timer, used to schedule execution of callbacks at a later date.
///
/// In the current implementation, each timer is executed as two
/// threads. The _Scheduler_ thread is in charge of maintaining the
/// queue of callbacks to execute and of actually executing them. The
/// _Communication_ thread is in charge of communicating with the
/// _Scheduler_ thread (which requires acquiring a possibly-long-held
/// Mutex) without blocking the caller thread.
pub struct Timer {
    /// Sender used to communicate with the _Communication_ thread. In
    /// turn, this thread will send
    tx: Sender<Op>
}

impl Drop for Timer {
    fn drop(&mut self) {
        self.tx.send(Op::Stop).unwrap();
    }
}

impl Timer {
    /// Create a timer.
    ///
    /// This immediatey launches two threads, which will remain
    /// launched until the timer is dropped. As expected, the threads
    /// spend most of their life waiting for instructions.
    pub fn new() -> Self {
        Self::with_capacity(32)
    }

    /// As `new()`, but with a manually specified initial capaicty.
    pub fn with_capacity(capacity: usize) -> Self {
        let waiter_send = Arc::new(WaiterChannel::with_capacity(capacity));
        let waiter_recv = waiter_send.clone();

        // Spawn a first thread, whose sole role is to dispatch
        // messages to the second thread without having to wait too
        // long for the mutex.
        let (tx, rx) = channel();
        thread::spawn(move || {
            use Op::*;
            let ref waiter = *waiter_send;
            for msg in rx.iter() {
                let mut vec = waiter.messages.lock().unwrap();
                match msg {
                    Schedule(sched) => {
                        vec.push(Schedule(sched));
                        waiter.condvar.notify_one();
                    }
                    Stop => {
                        vec.clear();
                        vec.push(Op::Stop);
                        waiter.condvar.notify_one();
                        return;
                    }
                }
            }
        });

        // Spawn a second thread, in charge of scheduling.
        thread::Builder::new().name("Timer thread".to_owned()).spawn(move || {
            let mut scheduler = Scheduler::with_capacity(waiter_recv, capacity);
            scheduler.run()
        }).unwrap();
        Timer {
            tx: tx
        }
    }

    /// Schedule a callback for execution after a delay.
    ///
    /// Callbacks are guaranteed to never be called before the
    /// delay. However, it is possible that they will be called a
    /// little after the delay.
    ///
    /// If the delay is negative or 0, the callback is executed as
    /// soon as possible.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, execution is cancelled.
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    ///
    /// # Example
    ///
    /// ```
    /// extern crate timer;
    /// extern crate chrono;
    /// use std::sync::mpsc::channel;
    ///
    /// let timer = timer::Timer::new();
    /// let (tx, rx) = channel();
    ///
    /// let _guard = timer.schedule_with_delay(chrono::Duration::seconds(3), move || {
    ///   // This closure is executed on the scheduler thread,
    ///   // so we want to move it away asap.
    ///
    ///   let _ignored = tx.send(()); // Avoid unwrapping here.
    /// });
    ///
    /// rx.recv().unwrap();
    /// println!("This code has been executed after 3 seconds");
    /// ```
    pub fn schedule_with_delay<F>(&self, delay: Duration, cb: F) -> Guard
        where F: 'static + FnMut() + Send {
        self.schedule_with_date(UTC::now() + delay, cb)
    }

    /// Schedule a callback for execution at a given date.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// If the date is in the past, the callback is executed as soon
    /// as possible.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, execution is cancelled.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    pub fn schedule_with_date<F, T>(&self, date: DateTime<T>, cb: F) -> Guard
        where F: 'static + FnMut() + Send, T : chrono::offset::TimeZone
    {
        self.schedule(date, None, cb)
    }

    /// Schedule a callback for execution once per interval.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, repeat is stopped.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    ///
    /// # Example
    ///
    /// ```
    /// extern crate timer;
    /// extern crate chrono;
    /// use std::thread;
    /// use std::sync::{Arc, Mutex};
    ///
    /// let timer = timer::Timer::new();
    /// // Number of times the callback has been called.
    /// let count = Arc::new(Mutex::new(0));
    ///
    /// // Start repeating. Each callback increases `count`.
    /// let guard = {
    ///   let count = count.clone();
    ///   timer.schedule_repeating(chrono::Duration::milliseconds(5), move || {
    ///     *count.lock().unwrap() += 1;
    ///   })
    /// };
    ///
    /// // Sleep one second. The callback should be called ~200 times.
    /// thread::sleep(std::time::Duration::new(1, 0));
    /// let count_result = *count.lock().unwrap();
    /// assert!(190 <= count_result && count_result <= 210,
    ///   "The timer was called {} times", count_result);
    ///
    /// // Now drop the guard. This should stop the timer.
    /// drop(guard);
    /// thread::sleep(std::time::Duration::new(0, 100));
    ///
    /// // Let's check that the count stops increasing.
    /// let count_start = *count.lock().unwrap();
    /// thread::sleep(std::time::Duration::new(1, 0));
    /// let count_stop =  *count.lock().unwrap();
    /// assert_eq!(count_start, count_stop);
    /// ```
    pub fn schedule_repeating<F>(&self, repeat: Duration, cb: F) -> Guard
        where F: 'static + FnMut() + Send
    {
        self.schedule(UTC::now() + repeat, Some(repeat), cb)
    }

    /// Schedule a callback for execution at a given time, then once
    /// per interval. A typical use case is to execute code once per
    /// day at 12am.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, repeat is stopped.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    pub fn schedule<F, T>(&self, date: DateTime<T>, repeat: Option<Duration>, cb: F) -> Guard
        where F: 'static + FnMut() + Send, T : chrono::offset::TimeZone
    {
        let guard = Guard::new();
        self.tx.send(Op::Schedule(Schedule {
            date: date.with_timezone(&UTC),
            cb: Box::new(cb),
            guard: guard.clone(),
            repeat: repeat
        })).unwrap();
        guard
    }
}

#[derive(Clone)]
pub struct Guard {
    should_execute: Arc<AtomicBool>
}
impl Guard {
    fn new() -> Self {
        Guard {
            should_execute: Arc::new(AtomicBool::new(true))
        }
    }
    fn should_execute(&self) -> bool {
        self.should_execute.load(AtomicOrdering::Relaxed)
    }
}
impl Drop for Guard {
    fn drop(&mut self) {
        self.should_execute.store(false, AtomicOrdering::Relaxed)
    }
}

#[test]
fn test_schedule_with_delay() {
    let timer = Timer::new();
    let (tx, rx) = channel();
    let mut guards = vec![];

    // Schedule a number of callbacks in an arbitrary order, make sure
    // that they are executed in the right order.
    let mut delays = vec![1, 5, 3, -1];
    let start = UTC::now();
    for i in delays.clone() {
        println!("Scheduling for execution in {} seconds", i);
        let tx = tx.clone();
        guards.push(timer.schedule_with_delay(Duration::seconds(i), move || {
            println!("Callback {}", i);
            tx.send(i).unwrap();
        }));
    }

    delays.sort();
    for (i, msg) in (0..delays.len()).zip(rx.iter()) {
        let elapsed = (UTC::now() - start).num_seconds();
        println!("Received message {} after {} seconds", msg, elapsed);
        assert_eq!(msg, delays[i]);
        assert!(delays[i] <= elapsed && elapsed <= delays[i] + 3, "We have waited {} seconds, expecting [{}, {}]", elapsed, delays[i], delays[i] + 3);
    }

    // Now make sure that callbacks that are designed to be executed
    // immediately are executed quickly.
    let start = UTC::now();
    for i in vec![10, 0] {
        println!("Scheduling for execution in {} seconds", i);
        let tx = tx.clone();
        guards.push(timer.schedule_with_delay(Duration::seconds(i), move || {
            println!("Callback {}", i);
            tx.send(i).unwrap();
        }));
    }

    assert_eq!(rx.recv().unwrap(), 0);
    assert!(UTC::now() - start <= Duration::seconds(1));
}

#[test]
fn test_guards() {
    println!("Testing that callbacks aren't called if the guard is dropped");
    let timer = Timer::new();
    let called = Arc::new(Mutex::new(false));

    for i in 0..10 {
        let called = called.clone();
        timer.schedule_with_delay(Duration::milliseconds(i), move || {
            *called.lock().unwrap() = true;
        });
    }

    thread::sleep(std::time::Duration::new(1, 0));
    assert_eq!(*called.lock().unwrap(), false);
}
<commit_msg>Some documentation<commit_after>//! A simple timer, used to enqueue operations meant to be executed at
//! a given time or after a given delay.

extern crate chrono;

use std::cmp::Ordering;
use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering as AtomicOrdering;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{channel, Sender};
use std::collections::BinaryHeap;
use chrono::{Duration, DateTime, UTC};

/// An item scheduled for delayed execution.
struct Schedule {
    /// The instant at which to execute.
    date: DateTime<UTC>,

    /// The callback to execute.
    cb: Box<FnMut() + Send>,

    /// A mechanism to cancel execution of an item.
    guard: Guard,

    /// If `Some(d)`, the item must be repeated every interval of
    /// length `d`, until cancelled.
    repeat: Option<Duration>
}
impl Ord for Schedule {
    fn cmp(&self, other: &Self) -> Ordering {
        self.date.cmp(&other.date).reverse()
    }
}
impl PartialOrd for Schedule {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.date.partial_cmp(&other.date).map(|ord| ord.reverse())
    }
}
impl Eq for Schedule {
}
impl PartialEq for Schedule {
    fn eq(&self, other: &Self) -> bool {
        self.date.eq(&other.date)
    }
}

/// An operation to be sent across threads.
enum Op {
    /// Schedule a new item for execution.
    Schedule(Schedule),

    /// Stop the thread.
    Stop
}

/// A mutex-based kind-of-channel used to communicate between the
/// Communication thread and the Scheuler thread.
struct WaiterChannel {
    /// Pending messages.
    messages: Mutex<Vec<Op>>,
    /// A condition variable used for waiting.
    condvar: Condvar,
}
impl WaiterChannel {
    fn with_capacity(cap: usize) -> Self {
        WaiterChannel {
            messages: Mutex::new(Vec::with_capacity(cap)),
            condvar: Condvar::new(),
        }
    }
}

struct Scheduler {
    waiter: Arc<WaiterChannel>,
    heap: BinaryHeap<Schedule>,
}

impl Scheduler {
    fn with_capacity(waiter: Arc<WaiterChannel>, capacity: usize) -> Self {
        Scheduler {
            waiter: waiter,
            heap: BinaryHeap::with_capacity(capacity),
        }
    }

    fn run(&mut self) {
        enum Sleep {
            NotAtAll,
            UntilAwakened,
            AtMost(Duration)
        }

        let ref waiter = *self.waiter;
        loop {
            let mut lock = waiter.messages.lock().unwrap();

            // Pop all messages.
            for msg in lock.drain(..) {
                match msg {
                    Op::Stop => {
                        return;
                    }
                    Op::Schedule(sched) => self.heap.push(sched),
                }
            }

            // Pop all the callbacks that are ready.

            // If we don't find
            let mut sleep = Sleep::UntilAwakened;
            loop {
                let now = UTC::now();
                if let Some(sched) = self.heap.peek() {
                    if sched.date > now {
                        // First item is not ready yet, so we need to
                        // wait until it is or something happens.
                        sleep = Sleep::AtMost(sched.date - now);
                        break;
                    }
                } else {
                    // Schedule is empty, nothing to do, wait until something happens.
                    break;
                }
                // At this stage, we have an item that has reached
                // execution time. The `unwrap()` is guaranteed to
                // succeed.
                let mut sched = self.heap.pop().unwrap();
                if !sched.guard.should_execute() {
                    // Execution has been cancelled, skip this item.
                    continue;
                }
                (sched.cb)();
                if let Some(delta) = sched.repeat {
                    // This is a repeating timer, so we need to
                    // enqueue the next call.
                    sleep = Sleep::NotAtAll;
                    self.heap.push(Schedule {
                        date: sched.date + delta,
                        cb: sched.cb,
                        guard: sched.guard,
                        repeat: Some(delta)
                    });
                }
            }

            match sleep {
                Sleep::UntilAwakened => {
                    let _ = waiter.condvar.wait(lock);
                },
                Sleep::AtMost(delay) => {
                    let sec = delay.num_seconds();
                    let ns = (delay - Duration::seconds(sec)).num_nanoseconds().unwrap(); // This `unwrap()` asserts that the number of ns is not > 1_000_000_000. Since we just substracted the number of seconds, the assertion should always pass.
                    let duration = std::time::Duration::new(sec as u64, ns as u32);
                    let _ = waiter.condvar.wait_timeout(lock, duration);
                },
                Sleep::NotAtAll => {}
            }
        }
    }
}

/// A timer, used to schedule execution of callbacks at a later date.
///
/// In the current implementation, each timer is executed as two
/// threads. The _Scheduler_ thread is in charge of maintaining the
/// queue of callbacks to execute and of actually executing them. The
/// _Communication_ thread is in charge of communicating with the
/// _Scheduler_ thread (which requires acquiring a possibly-long-held
/// Mutex) without blocking the caller thread.
pub struct Timer {
    /// Sender used to communicate with the _Communication_ thread. In
    /// turn, this thread will send
    tx: Sender<Op>
}

impl Drop for Timer {
    /// Stop the timer threads.
    fn drop(&mut self) {
        self.tx.send(Op::Stop).unwrap();
    }
}

impl Timer {
    /// Create a timer.
    ///
    /// This immediatey launches two threads, which will remain
    /// launched until the timer is dropped. As expected, the threads
    /// spend most of their life waiting for instructions.
    pub fn new() -> Self {
        Self::with_capacity(32)
    }

    /// As `new()`, but with a manually specified initial capaicty.
    pub fn with_capacity(capacity: usize) -> Self {
        let waiter_send = Arc::new(WaiterChannel::with_capacity(capacity));
        let waiter_recv = waiter_send.clone();

        // Spawn a first thread, whose sole role is to dispatch
        // messages to the second thread without having to wait too
        // long for the mutex.
        let (tx, rx) = channel();
        thread::spawn(move || {
            use Op::*;
            let ref waiter = *waiter_send;
            for msg in rx.iter() {
                let mut vec = waiter.messages.lock().unwrap();
                match msg {
                    Schedule(sched) => {
                        vec.push(Schedule(sched));
                        waiter.condvar.notify_one();
                    }
                    Stop => {
                        vec.clear();
                        vec.push(Op::Stop);
                        waiter.condvar.notify_one();
                        return;
                    }
                }
            }
        });

        // Spawn a second thread, in charge of scheduling.
        thread::Builder::new().name("Timer thread".to_owned()).spawn(move || {
            let mut scheduler = Scheduler::with_capacity(waiter_recv, capacity);
            scheduler.run()
        }).unwrap();
        Timer {
            tx: tx
        }
    }

    /// Schedule a callback for execution after a delay.
    ///
    /// Callbacks are guaranteed to never be called before the
    /// delay. However, it is possible that they will be called a
    /// little after the delay.
    ///
    /// If the delay is negative or 0, the callback is executed as
    /// soon as possible.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, execution is cancelled.
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    ///
    /// # Example
    ///
    /// ```
    /// extern crate timer;
    /// extern crate chrono;
    /// use std::sync::mpsc::channel;
    ///
    /// let timer = timer::Timer::new();
    /// let (tx, rx) = channel();
    ///
    /// let _guard = timer.schedule_with_delay(chrono::Duration::seconds(3), move || {
    ///   // This closure is executed on the scheduler thread,
    ///   // so we want to move it away asap.
    ///
    ///   let _ignored = tx.send(()); // Avoid unwrapping here.
    /// });
    ///
    /// rx.recv().unwrap();
    /// println!("This code has been executed after 3 seconds");
    /// ```
    pub fn schedule_with_delay<F>(&self, delay: Duration, cb: F) -> Guard
        where F: 'static + FnMut() + Send {
        self.schedule_with_date(UTC::now() + delay, cb)
    }

    /// Schedule a callback for execution at a given date.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// If the date is in the past, the callback is executed as soon
    /// as possible.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, execution is cancelled.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    pub fn schedule_with_date<F, T>(&self, date: DateTime<T>, cb: F) -> Guard
        where F: 'static + FnMut() + Send, T : chrono::offset::TimeZone
    {
        self.schedule(date, None, cb)
    }

    /// Schedule a callback for execution once per interval.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, repeat is stopped.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    ///
    /// # Example
    ///
    /// ```
    /// extern crate timer;
    /// extern crate chrono;
    /// use std::thread;
    /// use std::sync::{Arc, Mutex};
    ///
    /// let timer = timer::Timer::new();
    /// // Number of times the callback has been called.
    /// let count = Arc::new(Mutex::new(0));
    ///
    /// // Start repeating. Each callback increases `count`.
    /// let guard = {
    ///   let count = count.clone();
    ///   timer.schedule_repeating(chrono::Duration::milliseconds(5), move || {
    ///     *count.lock().unwrap() += 1;
    ///   })
    /// };
    ///
    /// // Sleep one second. The callback should be called ~200 times.
    /// thread::sleep(std::time::Duration::new(1, 0));
    /// let count_result = *count.lock().unwrap();
    /// assert!(190 <= count_result && count_result <= 210,
    ///   "The timer was called {} times", count_result);
    ///
    /// // Now drop the guard. This should stop the timer.
    /// drop(guard);
    /// thread::sleep(std::time::Duration::new(0, 100));
    ///
    /// // Let's check that the count stops increasing.
    /// let count_start = *count.lock().unwrap();
    /// thread::sleep(std::time::Duration::new(1, 0));
    /// let count_stop =  *count.lock().unwrap();
    /// assert_eq!(count_start, count_stop);
    /// ```
    pub fn schedule_repeating<F>(&self, repeat: Duration, cb: F) -> Guard
        where F: 'static + FnMut() + Send
    {
        self.schedule(UTC::now() + repeat, Some(repeat), cb)
    }

    /// Schedule a callback for execution at a given time, then once
    /// per interval. A typical use case is to execute code once per
    /// day at 12am.
    ///
    /// Callbacks are guaranteed to never be called before their
    /// date. However, it is possible that they will be called a
    /// little after it.
    ///
    /// This method returns a `Guard` object. If that `Guard` is
    /// dropped, repeat is stopped.
    ///
    ///
    /// # Performance
    ///
    /// The callback is executed on the Scheduler thread. It should
    /// therefore terminate very quickly, or risk causing delaying
    /// other callbacks.
    ///
    /// # Failures
    ///
    /// Any failure in `cb` will scheduler thread and progressively
    /// contaminate the Timer and the calling thread itself. You have
    /// been warned.
    pub fn schedule<F, T>(&self, date: DateTime<T>, repeat: Option<Duration>, cb: F) -> Guard
        where F: 'static + FnMut() + Send, T : chrono::offset::TimeZone
    {
        let guard = Guard::new();
        self.tx.send(Op::Schedule(Schedule {
            date: date.with_timezone(&UTC),
            cb: Box::new(cb),
            guard: guard.clone(),
            repeat: repeat
        })).unwrap();
        guard
    }
}

/// A value scoping a schedule. When this value is dropped, the
/// schedule is cancelled.
#[derive(Clone)]
pub struct Guard {
    should_execute: Arc<AtomicBool>
}
impl Guard {
    fn new() -> Self {
        Guard {
            should_execute: Arc::new(AtomicBool::new(true))
        }
    }
    fn should_execute(&self) -> bool {
        self.should_execute.load(AtomicOrdering::Relaxed)
    }
}
impl Drop for Guard {
    /// Cancel a schedule.
    fn drop(&mut self) {
        self.should_execute.store(false, AtomicOrdering::Relaxed)
    }
}

#[test]
fn test_schedule_with_delay() {
    let timer = Timer::new();
    let (tx, rx) = channel();
    let mut guards = vec![];

    // Schedule a number of callbacks in an arbitrary order, make sure
    // that they are executed in the right order.
    let mut delays = vec![1, 5, 3, -1];
    let start = UTC::now();
    for i in delays.clone() {
        println!("Scheduling for execution in {} seconds", i);
        let tx = tx.clone();
        guards.push(timer.schedule_with_delay(Duration::seconds(i), move || {
            println!("Callback {}", i);
            tx.send(i).unwrap();
        }));
    }

    delays.sort();
    for (i, msg) in (0..delays.len()).zip(rx.iter()) {
        let elapsed = (UTC::now() - start).num_seconds();
        println!("Received message {} after {} seconds", msg, elapsed);
        assert_eq!(msg, delays[i]);
        assert!(delays[i] <= elapsed && elapsed <= delays[i] + 3, "We have waited {} seconds, expecting [{}, {}]", elapsed, delays[i], delays[i] + 3);
    }

    // Now make sure that callbacks that are designed to be executed
    // immediately are executed quickly.
    let start = UTC::now();
    for i in vec![10, 0] {
        println!("Scheduling for execution in {} seconds", i);
        let tx = tx.clone();
        guards.push(timer.schedule_with_delay(Duration::seconds(i), move || {
            println!("Callback {}", i);
            tx.send(i).unwrap();
        }));
    }

    assert_eq!(rx.recv().unwrap(), 0);
    assert!(UTC::now() - start <= Duration::seconds(1));
}

#[test]
fn test_guards() {
    println!("Testing that callbacks aren't called if the guard is dropped");
    let timer = Timer::new();
    let called = Arc::new(Mutex::new(false));

    for i in 0..10 {
        let called = called.clone();
        timer.schedule_with_delay(Duration::milliseconds(i), move || {
            *called.lock().unwrap() = true;
        });
    }

    thread::sleep(std::time::Duration::new(1, 0));
    assert_eq!(*called.lock().unwrap(), false);
}
<|endoftext|>


<commit_before>//! libc - Raw FFI bindings to platforms' system libraries
//!
//! [Documentation for other platforms][pd].
//!
//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![allow(
    renamed_and_removed_lints, // Keep this order.
    unknown_lints, // Keep this order.
    bad_style,
    overflowing_literals,
    improper_ctypes,
    // This lint is renamed but we run CI for old stable rustc so should be here.
    redundant_semicolon,
    redundant_semicolons
)]
#![cfg_attr(libc_deny_warnings, deny(warnings))]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core, static_nobundle)
)]
#![cfg_attr(libc_thread_local, feature(thread_local))]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![no_std]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
#![cfg_attr(target_os = "redox", feature(static_nobundle))]
#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))]

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::ops;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod switch;
        pub use switch::*;
    } else if #[cfg(target_os = "psp")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod psp;
        pub use psp::*;
    } else if #[cfg(target_os = "vxworks")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod vxworks;
        pub use vxworks::*;
    } else if #[cfg(unix)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod unix;
        pub use unix::*;
    } else if #[cfg(target_os = "hermit")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod hermit;
        pub use hermit::*;
    } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod sgx;
        pub use sgx::*;
    } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod wasi;
        pub use wasi::*;
    } else {
        // non-supported targets: empty...
    }
}
<commit_msg>Fix bootstrap on redox<commit_after>//! libc - Raw FFI bindings to platforms' system libraries
//!
//! [Documentation for other platforms][pd].
//!
//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![allow(
    renamed_and_removed_lints, // Keep this order.
    unknown_lints, // Keep this order.
    bad_style,
    overflowing_literals,
    improper_ctypes,
    // This lint is renamed but we run CI for old stable rustc so should be here.
    redundant_semicolon,
    redundant_semicolons
)]
#![cfg_attr(libc_deny_warnings, deny(warnings))]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core)
)]
#![cfg_attr(libc_thread_local, feature(thread_local))]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![no_std]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
#![cfg_attr(
    any(feature = "rustc-dep-of-std", target_os = "redox"),
    feature(static_nobundle)
)]
#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))]

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::ops;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod switch;
        pub use switch::*;
    } else if #[cfg(target_os = "psp")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod psp;
        pub use psp::*;
    } else if #[cfg(target_os = "vxworks")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod vxworks;
        pub use vxworks::*;
    } else if #[cfg(unix)] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod unix;
        pub use unix::*;
    } else if #[cfg(target_os = "hermit")] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod hermit;
        pub use hermit::*;
    } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod sgx;
        pub use sgx::*;
    } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] {
        mod fixed_width_ints;
        pub use fixed_width_ints::*;

        mod wasi;
        pub use wasi::*;
    } else {
        // non-supported targets: empty...
    }
}
<|endoftext|>


<commit_before>extern crate libc;

pub mod ffi;
pub mod apr;
pub mod httpd;
pub mod wrapper;
pub mod cookie;

pub use libc::{c_void, c_char, c_int};

pub use httpd::{Request, Status, ProxyReq, server_banner, server_description, server_built, show_mpm};
pub use apr::{apr_version_string, apu_version_string, HookOrder, time_now};
pub use cookie::Cookie;

#[macro_export]
macro_rules! apache2_module {
   ($handler:ident) => {
      apache2_module!($handler, c_hello_handler, hello_module, b"mod_hello\0");
   };

   ($handler:ident, $c_handler:ident, $module:ident, $c_name:expr) => {
      apache2_module!($handler, $c_handler, $module, $c_name, ap_hook_handler, $crate::HookOrder::MIDDLE);
   };

   ($handler:ident, $c_handler:ident, $module:ident, $c_name:expr, $hook:ident, $order:expr) => {
      const C_NAME: &'static [u8] = $c_name;
      const C_NAME_PTR: *const &'static [u8] = &C_NAME;
      const C_NAME_CHAR_PTR: *const $crate::c_char = C_NAME_PTR as *const $crate::c_char;

      #[no_mangle]
      pub static mut $module: $crate::ffi::module = $crate::ffi::module {
         version: $crate::ffi::MODULE_MAGIC_NUMBER_MAJOR,
         minor_version: $crate::ffi::MODULE_MAGIC_NUMBER_MINOR,
         module_index: -1,
         name: C_NAME_CHAR_PTR,
         dynamic_load_handle: 0 as *mut $crate::c_void,
         next: 0 as *mut $crate::ffi::module,
         magic: $crate::ffi::MODULE_MAGIC_COOKIE,
         rewrite_args: None,
         create_dir_config: None,
         merge_dir_config: None,
         create_server_config: None,
         merge_server_config: None,
         cmds: 0 as *const $crate::ffi::command_rec,
         register_hooks: Some(c_module_hooks),
      };

      extern "C" fn c_module_hooks(_: *mut $crate::ffi::apr_pool_t) {
         unsafe {
            $crate::ffi::$hook(
               Some($c_handler),
               std::ptr::null(),
               std::ptr::null(),
               $order.into()
            );
         }
      }

      #[no_mangle]
      pub extern "C" fn $c_handler(r: *mut $crate::ffi::request_rec) -> $crate::c_int {
         match $crate::httpd::Request::from_raw_ptr(r) {
            None => $crate::httpd::Status::DECLINED.into(),
            Some(mut request) => $handler(&mut request).into()
         }
      }
   }
}
<commit_msg>Introducing AP_DECLARE_MODULE direct equivalent macro.<commit_after>extern crate libc;

pub mod ffi;
pub mod apr;
pub mod httpd;
pub mod wrapper;
pub mod cookie;

pub use libc::{c_void, c_char, c_int};

pub use httpd::{Request, Status, ProxyReq, server_banner, server_description, server_built, show_mpm};
pub use apr::{apr_version_string, apu_version_string, HookOrder, time_now};
pub use cookie::Cookie;

#[macro_export]
macro_rules! AP_DECLARE_MODULE {
   (
      $module:ident,
      $name:expr,
      $create_dir_config:expr,
      $merge_dir_config:expr,
      $create_server_config:expr,
      $merge_server_config:expr,
      $cmds:expr,
      $register_hooks:expr
   ) => {
      #[no_mangle]
      pub static mut $module: $crate::ffi::module = $crate::ffi::module {
         version: $crate::ffi::MODULE_MAGIC_NUMBER_MAJOR,
         minor_version: $crate::ffi::MODULE_MAGIC_NUMBER_MINOR,
         module_index: -1,
         name: $name,
         dynamic_load_handle: 0 as *mut $crate::c_void,
         next: 0 as *mut $crate::ffi::module,
         magic: $crate::ffi::MODULE_MAGIC_COOKIE,
         rewrite_args: None,
         create_dir_config: $create_dir_config,
         merge_dir_config: $merge_dir_config,
         create_server_config: $create_server_config,
         merge_server_config: $merge_server_config,
         cmds: $cmds,
         register_hooks: $register_hooks
      };
   }
}

#[macro_export]
macro_rules! apache2_module {
   ($handler:ident) => {
      apache2_module!($handler, c_hello_handler, hello_module, b"mod_hello\0");
   };

   ($handler:ident, $c_handler:ident, $module:ident, $c_name:expr) => {
      apache2_module!($handler, $c_handler, $module, $c_name, ap_hook_handler, $crate::HookOrder::MIDDLE);
   };

   ($handler:ident, $c_handler:ident, $module:ident, $c_name:expr, $hook:ident, $order:expr) => {
      AP_DECLARE_MODULE!(
         $module,
         $c_name as *const u8 as *const $crate::c_char,
         None,
         None,
         None,
         None,
         0 as *const $crate::ffi::command_rec,
         Some(c_module_hooks)
      );

      extern "C" fn c_module_hooks(_: *mut $crate::ffi::apr_pool_t) {
         unsafe {
            $crate::ffi::$hook(
               Some($c_handler),
               std::ptr::null(),
               std::ptr::null(),
               $order.into()
            );
         }
      }

      #[no_mangle]
      pub extern "C" fn $c_handler(r: *mut $crate::ffi::request_rec) -> $crate::c_int {
         match $crate::httpd::Request::from_raw_ptr(r) {
            None => $crate::httpd::Status::DECLINED.into(),
            Some(mut request) => $handler(&mut request).into()
         }
      }
   }
}
<|endoftext|>


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

#[cfg(test)]
mod test {
  #[test]
  fn test_decode() {
    assert!(1u == 1);
  }
}
<commit_msg>Add manual decoding of test message<commit_after>#![crate_name = "lifx"]
#![feature(struct_variant)]

extern crate serialize;

use std::default::Default;
use std::io::{Reader,BufReader};
use serialize::{Encodable,Decodable};

#[derive(Encodable,Decodable)]
pub struct Message {
  pub size: u16,
  pub version: u16, // encoded in 12 bits
  pub addressable: bool,
  pub tagged: bool,
  pub target: [u8, .. 8],
  pub site: [u8, .. 6],
  pub acknowledge: bool,
  pub at_time: u64,
  pub kind: u16,
  pub payload: Payload,
}

#[derive(Encodable,Decodable)]
struct HSBK {
  hue: u16,
  saturation: u16,
  brightness: u16,
  kelvin: u16,
}

#[derive(Encodable,Decodable)]
enum Payload {
  EMPTY,
  DeviceGetVersion, // 32
  DeviceStateVersion { vendor: u32, product: u32, version: u32 }, // 33
  DeviceGetInfo, // 34
  DeviceStateInfo { time: u64, uptime: u64, downtime: u64 }, // 35
  LightState { color: HSBK, dim: i16, power: u16, label: [u8, ..32], tags: u64 } // 107
}

impl Default for Payload {
  fn default() -> Payload { EMPTY }
}

impl Default for Message {
  fn default() -> Message {
    Message {
      size: 0,
      version: 0,
      addressable: false,
      tagged: false,
      target: [0, 0, 0, 0, 0, 0, 0, 0],
      site: [0, 0, 0, 0, 0, 0],
      acknowledge: false,
      at_time: 0,
      kind: 0,
      payload: EMPTY,
    }
  }
}

impl Message {

  pub fn new() -> Message {
    Message { .. Default::default() }
  }

  pub fn from_reader<T: Reader>(reader: &mut T) -> Option<Message> {
    let mut mesg = Message::new();

    // FIXME: get rid of this unwrap crap once decoding properly
    mesg.size        = reader.read_le_u16().unwrap();
    let bitfield     = reader.read_le_u16().unwrap();
    mesg.version     = bitfield & 0b0000111111111111;
    mesg.addressable = bitfield & 0b0001000000000000 > 0;
    mesg.tagged      = bitfield & 0b0010000000000000 > 0;

    reader.read_le_u32(); // unused
    reader.read(mesg.target);
    reader.read(mesg.site);
    let bitfield     = reader.read_le_u16().unwrap(); // only 1st bit used
    mesg.acknowledge = bitfield & 1 == 1;
    mesg.at_time     = reader.read_le_u64().unwrap();
    mesg.kind        = reader.read_le_u16().unwrap();
    mesg.payload     = EMPTY; // FIXME: read actual payload!

    Some(mesg)
  }

  pub fn from_bytes(bytes: &[u8]) -> Option<Message> {
    Message::from_reader(&mut BufReader::new(bytes))
  }
}

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

  #[test]
  fn test_decode() {
    let bytes: &[u8] = [0x39, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x6c, 0x69, 0x66, 0x78,
      0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67,
      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xac,
      0x0d, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00];

    let mesg = Message::from_bytes(bytes).unwrap();

    assert!(mesg.size == 57)
    assert!(mesg.version == 1024)
    assert!(mesg.target == [0, 0, 0, 0, 0, 0, 0, 0])
    assert!(mesg.site == b"1lifx1")
    assert!(mesg.tagged)
    assert!(mesg.addressable)
    assert!(mesg.kind == 103)
  }
}
<|endoftext|>


<commit_before>extern crate regex;
#[macro_use]
extern crate lazy_static;

pub mod lexer;
pub mod parser;

#[cfg(test)]
mod tests {
    use parser;
    use std::f64;
    #[test]
    fn addition() {
        let input = String::from("1 + 2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1+2) as f64);
    }
    #[test]
    fn subtraction() {
        let input = String::from("18 - 4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (18-4) as f64);
    }
    #[test]
    fn multiplication() {
        let input = String::from("3 * 6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (3*6) as f64);
    }
    #[test]
    fn divide() {
        let input = String::from("15 / 3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (15.0/3.0) as f64);
    }
    #[test]
    fn power() {
        let input = String::from("4 ^ 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (f64::powf(4.0, 7.0)) as f64);
        let input = String::from("4 ^ 7 ^ 8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (f64::powf(f64::powf(4.0, 7.0), 8.0) as f64));
    }
    #[test]
    fn numerical_negation() {
        let input = String::from("-2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (-2 as f64));
        let input = String::from("-(2)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (-2 as f64));
    }
    #[test]
    fn expression_negation() {
        let input = String::from("-(2+3)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((-1*(2+3)) as f64));
        let input = String::from("15-(-(2+3))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((15-(-1*(2+3))) as f64));
    }
    #[test]
    fn basic_modulo() {
        let input = String::from("0 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((0 % 7) as f64));
        let input = String::from("1 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((1 % 7) as f64));
    }
    #[test]
    fn negative_modulo() {
        let input = String::from("-1 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((-1 % 7) as f64));
        let input = String::from("(-1) % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (((-1) % 7) as f64));
    }
    #[test]
    fn end() {
        let input = String::from("");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn ignore_whitespace() {
        let input = String::from("   12        -  8   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (12-8) as f64);
        let input = String::from("142        -9   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (142-9) as f64);
        let input = String::from("72+  15");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (72+15) as f64);
        let input = String::from(" 12*  4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (12*4) as f64);
        let input = String::from(" 50/10");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (50.0/10.0) as f64);
    }
    #[test]
    fn long_add_expressions() {
        let input = String::from("2 -4 +6 -1 -1- 0 +8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2-4+6-1-1-0+8) as f64);
        let input = String::from("1 -1   + 2   - 2   +  4 - 4 +    6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1-1+2-2+4-4+6) as f64);
    }
    #[test]
    fn long_mult_expressions() {
        let input = String::from("2 *4 *6 *1 *1* 0 *8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2*4*6*1*1*0*8) as f64);
        let input = String::from("1 *1   * 2   * 2   *  4 * 4 *    6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1*1*2*2*4*4*6) as f64);
    }
    #[test]
    fn long_mixed() {
        let input = String::from(" 2*3 - 4*5 + 6/3 ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0-4.0*5.0+6.0/3.0) as f64);
        let input = String::from("2*3*4/8 -   5/2*4 +  6 + 0/3   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0*4.0/8.0-5.0/2.0*4.0+6.0+0.0/3.0) as f64);
    }
    #[test]
    fn floating() {
        let input = String::from("10/4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (10.0/4.0) as f64);
        let input = String::from("5/3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (5.0/3.0) as f64);
        let input = String::from("3 + 8/5 -1 -2*5");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (3.0+8.0/5.0-1.0-2.0*5.0) as f64);
    }
    #[test]
    fn bad_tokens() {
        let input = String::from("  6 + c");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from("  7 & 2");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from("  %");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn syntax_error() {
        let input = String::from(" 5 + + 6");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from(" 5 * / 6");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn divide_zero() {
        let input = String::from("5/0");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().unwrap().is_infinite());
        let input = String::from(" 2 - 1 + 14/0 + 7");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().unwrap().is_infinite());
    }
    #[test]
    fn unused_parens() {
        let input = String::from(" (2) ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2) as f64);
    }
    #[test]
    fn enclosing_parens() {
        let input = String::from("(5 + 2*3 - 1 + 7 * 8)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (5.0+2.0*3.0-1.0+7.0*8.0) as f64);
        let input = String::from("(67 + 2 * 3 - 67 + 2/1 - 7)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (67.0+2.0*3.0-67.0+2.0/1.0-7.0) as f64);
    }
    #[test]
    fn sub_expressions() {
        let input = String::from("(2) + (17*2-30) * (5)+2 - (8/2)*4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((2.0)+(17.0*2.0-30.0)*(5.0)+2.0-(8.0/2.0)*4.0) as f64);
        let input = String::from("(5*7/5) + (23) - 5 * (98-4)/(6*7-42)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((5.0*7.0/5.0)+(23.0)-5.0*(98.0-4.0)/(6.0*7.0-42.0)) as f64);
    }
    #[test]
    fn nested_parens() {
        let input = String::from("(((((5)))))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((((((5)))))) as f64);
        let input = String::from("(( ((2)) + 4))*((5))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (((((2.0))+4.0))*((5.0))) as f64);
    }
    #[test]
    fn unbalanced_parens() {
        let input = String::from("2 + (5 * 2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0+(5.0*2.0)) as f64);
        let input = String::from("(((((4))))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (4.0) as f64);
        let input = String::from("((2)) * ((3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0) as f64);
        let input = String::from("((9)) * ((1)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (9.0*1.0) as f64);
    }
}
<commit_msg>Added basic order of operations testing<commit_after>extern crate regex;
#[macro_use]
extern crate lazy_static;

pub mod lexer;
pub mod parser;

#[cfg(test)]
mod tests {
    use parser;
    use std::f64;
    #[test]
    fn addition() {
        let input = String::from("1 + 2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1+2) as f64);
    }
    #[test]
    fn subtraction() {
        let input = String::from("18 - 4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (18-4) as f64);
    }
    #[test]
    fn multiplication() {
        let input = String::from("3 * 6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (3*6) as f64);
    }
    #[test]
    fn divide() {
        let input = String::from("15 / 3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (15.0/3.0) as f64);
    }
    #[test]
    fn power() {
        let input = String::from("4 ^ 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (f64::powf(4.0, 7.0)) as f64);
        let input = String::from("4 ^ 7 ^ 8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (f64::powf(f64::powf(4.0, 7.0), 8.0) as f64));
    }
    #[test]
    fn numerical_negation() {
        let input = String::from("-2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (-2 as f64));
        let input = String::from("-(2)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (-2 as f64));
    }
    #[test]
    fn expression_negation() {
        let input = String::from("-(2+3)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((-1*(2+3)) as f64));
        let input = String::from("15-(-(2+3))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((15-(-1*(2+3))) as f64));
    }
    #[test]
    fn basic_modulo() {
        let input = String::from("0 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((0 % 7) as f64));
        let input = String::from("1 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((1 % 7) as f64));
    }
    #[test]
    fn negative_modulo() {
        let input = String::from("-1 % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((-1 % 7) as f64));
        let input = String::from("(-1) % 7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (((-1) % 7) as f64));
    }
    #[test]
    fn order_of_operations() {
        let input = String::from("4+5*7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((4+(5*7)) as f64));
        let input = String::from("-15/7");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (((-15.0)/7.0) as f64));
        let input = String::from("-2^0.5");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((-1.0*f64::powf(2.0, 0.5)) as f64));
        let input = String::from("(-2)^0.5");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap().is_nan(), ((f64::powf(-2.0, 0.5)) as f64).is_nan());
    }
    #[test]
    fn end() {
        let input = String::from("");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn ignore_whitespace() {
        let input = String::from("   12        -  8   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (12-8) as f64);
        let input = String::from("142        -9   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (142-9) as f64);
        let input = String::from("72+  15");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (72+15) as f64);
        let input = String::from(" 12*  4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (12*4) as f64);
        let input = String::from(" 50/10");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (50.0/10.0) as f64);
    }
    #[test]
    fn long_add_expressions() {
        let input = String::from("2 -4 +6 -1 -1- 0 +8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2-4+6-1-1-0+8) as f64);
        let input = String::from("1 -1   + 2   - 2   +  4 - 4 +    6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1-1+2-2+4-4+6) as f64);
    }
    #[test]
    fn long_mult_expressions() {
        let input = String::from("2 *4 *6 *1 *1* 0 *8");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2*4*6*1*1*0*8) as f64);
        let input = String::from("1 *1   * 2   * 2   *  4 * 4 *    6");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (1*1*2*2*4*4*6) as f64);
    }
    #[test]
    fn long_mixed() {
        let input = String::from(" 2*3 - 4*5 + 6/3 ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0-4.0*5.0+6.0/3.0) as f64);
        let input = String::from("2*3*4/8 -   5/2*4 +  6 + 0/3   ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0*4.0/8.0-5.0/2.0*4.0+6.0+0.0/3.0) as f64);
    }
    #[test]
    fn floating() {
        let input = String::from("10/4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (10.0/4.0) as f64);
        let input = String::from("5/3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (5.0/3.0) as f64);
        let input = String::from("3 + 8/5 -1 -2*5");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (3.0+8.0/5.0-1.0-2.0*5.0) as f64);
    }
    #[test]
    fn bad_tokens() {
        let input = String::from("  6 + c");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from("  7 & 2");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from("  %");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn syntax_error() {
        let input = String::from(" 5 + + 6");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
        let input = String::from(" 5 * / 6");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().is_err());
    }
    #[test]
    fn divide_zero() {
        let input = String::from("5/0");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().unwrap().is_infinite());
        let input = String::from(" 2 - 1 + 14/0 + 7");
        let mut my_parser = parser::Parser::new(input);
        assert!(my_parser.parse().unwrap().is_infinite());
    }
    #[test]
    fn unused_parens() {
        let input = String::from(" (2) ");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2) as f64);
    }
    #[test]
    fn enclosing_parens() {
        let input = String::from("(5 + 2*3 - 1 + 7 * 8)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (5.0+2.0*3.0-1.0+7.0*8.0) as f64);
        let input = String::from("(67 + 2 * 3 - 67 + 2/1 - 7)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (67.0+2.0*3.0-67.0+2.0/1.0-7.0) as f64);
    }
    #[test]
    fn sub_expressions() {
        let input = String::from("(2) + (17*2-30) * (5)+2 - (8/2)*4");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((2.0)+(17.0*2.0-30.0)*(5.0)+2.0-(8.0/2.0)*4.0) as f64);
        let input = String::from("(5*7/5) + (23) - 5 * (98-4)/(6*7-42)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((5.0*7.0/5.0)+(23.0)-5.0*(98.0-4.0)/(6.0*7.0-42.0)) as f64);
    }
    #[test]
    fn nested_parens() {
        let input = String::from("(((((5)))))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), ((((((5)))))) as f64);
        let input = String::from("(( ((2)) + 4))*((5))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (((((2.0))+4.0))*((5.0))) as f64);
    }
    #[test]
    fn unbalanced_parens() {
        let input = String::from("2 + (5 * 2");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0+(5.0*2.0)) as f64);
        let input = String::from("(((((4))))");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (4.0) as f64);
        let input = String::from("((2)) * ((3");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (2.0*3.0) as f64);
        let input = String::from("((9)) * ((1)");
        let mut my_parser = parser::Parser::new(input);
        assert_eq!(my_parser.parse().unwrap(), (9.0*1.0) as f64);
    }
}
<|endoftext|>