<commit_before>//! Trait for nearly equality comparisons.
//!
//! # Overview
//! Implementing the `NearlyEq` traits, Can asserts that the two expressions are nearly(approximately) equal to each other.
//!
//! # Licensing
//! This Source Code is subject to the terms of the Mozilla Public License
//! version 2.0 (the "License"). You can obtain a copy of the License at
//! [http://mozilla.org/MPL/2.0/](http://mozilla.org/MPL/2.0/).
//!
//! # Examples
//!
//! ```rust
//! # #[macro_use] extern crate nearly_eq;
//! # fn main() {
//! assert_nearly_eq!(1f64, 1.5f64, 0.6f64); // does not panic
//! assert_nearly_eq!(0f64, 1e-12f64); // does not panic
//! # }
//! ```
//! ```should_panic
//! # #[macro_use] extern crate nearly_eq;
//! # fn main() {
//! assert_nearly_eq!(1f64, 2f64); // panics
//! # }
//! ```

#![cfg_attr(feature = "docs", feature(staged_api))]
#![cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]

#[cfg(feature = "num-complex")]
extern crate num_complex;

#[cfg(feature = "num-rational")]
extern crate num_rational;

#[cfg(feature = "num-integer")]
extern crate num_integer;

#[cfg(feature = "num-traits")]
extern crate num_traits;

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

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

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

#[macro_use]
mod assert;

#[cfg(feature = "num-complex")]
mod complex_impl;

#[cfg(feature = "num-traits")]
#[cfg(feature = "num-rational")]
#[cfg(feature = "num-integer")]
mod rational_impl;

#[cfg(feature = "ndarray")]
mod ndarray_impl;

#[cfg(feature = "fpa")]
mod fpa_impl;

use std::rc::{Rc, Weak};

use std::sync::Arc;

use std::cell::{Cell, RefCell};

/// Trait for nearly(approximately) equality comparisons.
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
pub trait NearlyEq<Rhs: ?Sized = Self, Diff: ?Sized = Self> {
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn eps() -> Diff;

    /// This method tests for self and other values to be nearly(approximately) equal.
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn eq(&self, other: &Rhs, eps: &Diff) -> bool;

    /// This method tests for not nearly(approximately) equal.
    #[inline]
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn ne(&self, other: &Rhs, eps: &Diff) -> bool {
        !self.eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl NearlyEq for f32 {
    fn eps() -> f32 {
        1e-6
    }

    fn eq(&self, other: &f32, eps: &f32) -> bool {
        let diff = (*self - *other).abs();

        if *self == *other {
            true
        } else {
            diff < *eps
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl NearlyEq for f64 {
    fn eps() -> f64 {
        1e-11
    }

    fn eq(&self, other: &f64, eps: &f64) -> bool {
        let diff = (*self - *other).abs();

        if *self == *other {
            true
        } else {
            diff < *eps
        }
    }
}

macro_rules! itype_impls {
    ($($T:ty)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
            impl NearlyEq for $T {
                fn eps() -> $T {
                    0
                }

                fn eq(&self, other: &$T, eps: &$T) -> bool {
                    let diff = (*self - *other).abs();

                    if *self == *other {
                        true
                    } else {
                        diff < *eps
                    }
                }
            }
        )+
    }
}

itype_impls! { i8 i16 i32 i64 }

#[cfg(feature = "i128")]
itype_impls! { i128 }

macro_rules! utype_impls {
    ($($T:ty)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
            impl NearlyEq for $T {
                fn eps() -> $T {
                    0
                }

                fn eq(&self, other: &$T, eps: &$T) -> bool {
                    let diff = if *self > *other { *self - *other } else { *other - *self };

                    if *self == *other {
                        true
                    } else {
                        diff < *eps
                    }
                }
            }
        )+
    }
}

utype_impls! { u8 u16 u32 u64 }

#[cfg(feature = "i128")]
utype_impls! { u128 }

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<[A], B> for [C] {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &[A], eps: &B) -> bool {
        if self.len() != other.len() {
            false
        } else {
            for i in 0..self.len() {
                if self[i].ne(&other[i], eps) {
                    return false;
                }
            }
            true
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Vec<A>, B> for Vec<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Vec<A>, eps: &B) -> bool {
        if self.len() != other.len() {
            false
        } else {
            for i in 0..self.len() {
                if self[i].ne(&other[i], eps) {
                    return false;
                }
            }
            true
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<'a, A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<A, B> for &'a C {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &A, eps: &B) -> bool {
        (**self).eq(&other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
impl<'a, A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<A, B> for &'a mut C {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &A, eps: &B) -> bool {
        (**self).eq(&other, eps)
    }
}

macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
            impl<A, B, C: NearlyEq<A, B>> NearlyEq<[A; $N], B> for [C; $N] {
                fn eps() -> B {
                    C::eps()
                }

                fn eq(&self, other: &[A; $N], eps: &B) -> bool {
                    for i in 0..$N {
                        if self[i].ne(&other[i], eps) {
                            return false;
                        }
                    }
                    true
                }
            }
        )+
    }
}

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

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.1"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Option<A>, B> for Option<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Option<A>, eps: &B) -> bool {
            match (self, other) {
                (&None, &None) => return true,
                (&None, _) | (_, &None) => return false,
                (&Some(ref x), &Some(ref y)) => x.eq(y, eps),
            }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Rc<A>, B> for Rc<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Rc<A>, eps: &B) -> bool {
        self.as_ref().eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Arc<A>, B> for Arc<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Arc<A>, eps: &B) -> bool {
        self.as_ref().eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Weak<A>, B> for Weak<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Weak<A>, eps: &B) -> bool {
        self.upgrade().eq(&other.upgrade(), eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A: Copy + ?Sized, B, C: NearlyEq<A, B> +  Copy + ?Sized> NearlyEq<Cell<A>, B> for Cell<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Cell<A>, eps: &B) -> bool {
        (*self).get().eq(&(*other).get(), eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<RefCell<A>, B> for RefCell<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &RefCell<A>, eps: &B) -> bool {
        (*self).borrow().eq(&(*other).borrow(), eps)
    }
}
<commit_msg>Fix i128_type feature fot stable docs<commit_after>//! Trait for nearly equality comparisons.
//!
//! # Overview
//! Implementing the `NearlyEq` traits, Can asserts that the two expressions are nearly(approximately) equal to each other.
//!
//! # Licensing
//! This Source Code is subject to the terms of the Mozilla Public License
//! version 2.0 (the "License"). You can obtain a copy of the License at
//! [http://mozilla.org/MPL/2.0/](http://mozilla.org/MPL/2.0/).
//!
//! # Examples
//!
//! ```rust
//! # #[macro_use] extern crate nearly_eq;
//! # fn main() {
//! assert_nearly_eq!(1f64, 1.5f64, 0.6f64); // does not panic
//! assert_nearly_eq!(0f64, 1e-12f64); // does not panic
//! # }
//! ```
//! ```should_panic
//! # #[macro_use] extern crate nearly_eq;
//! # fn main() {
//! assert_nearly_eq!(1f64, 2f64); // panics
//! # }
//! ```

#![cfg_attr(feature = "docs", feature(staged_api))]
#![cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
#![cfg_attr(feature = "docs", feature(i128_type))]

#[cfg(feature = "num-complex")]
extern crate num_complex;

#[cfg(feature = "num-rational")]
extern crate num_rational;

#[cfg(feature = "num-integer")]
extern crate num_integer;

#[cfg(feature = "num-traits")]
extern crate num_traits;

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

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

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

#[macro_use]
mod assert;

#[cfg(feature = "num-complex")]
mod complex_impl;

#[cfg(feature = "num-traits")]
#[cfg(feature = "num-rational")]
#[cfg(feature = "num-integer")]
mod rational_impl;

#[cfg(feature = "ndarray")]
mod ndarray_impl;

#[cfg(feature = "fpa")]
mod fpa_impl;

use std::rc::{Rc, Weak};

use std::sync::Arc;

use std::cell::{Cell, RefCell};

/// Trait for nearly(approximately) equality comparisons.
#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
pub trait NearlyEq<Rhs: ?Sized = Self, Diff: ?Sized = Self> {
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn eps() -> Diff;

    /// This method tests for self and other values to be nearly(approximately) equal.
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn eq(&self, other: &Rhs, eps: &Diff) -> bool;

    /// This method tests for not nearly(approximately) equal.
    #[inline]
    #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
    fn ne(&self, other: &Rhs, eps: &Diff) -> bool {
        !self.eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl NearlyEq for f32 {
    fn eps() -> f32 {
        1e-6
    }

    fn eq(&self, other: &f32, eps: &f32) -> bool {
        let diff = (*self - *other).abs();

        if *self == *other {
            true
        } else {
            diff < *eps
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl NearlyEq for f64 {
    fn eps() -> f64 {
        1e-11
    }

    fn eq(&self, other: &f64, eps: &f64) -> bool {
        let diff = (*self - *other).abs();

        if *self == *other {
            true
        } else {
            diff < *eps
        }
    }
}

macro_rules! itype_impls {
    ($($T:ty)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
            impl NearlyEq for $T {
                fn eps() -> $T {
                    0
                }

                fn eq(&self, other: &$T, eps: &$T) -> bool {
                    let diff = (*self - *other).abs();

                    if *self == *other {
                        true
                    } else {
                        diff < *eps
                    }
                }
            }
        )+
    }
}

itype_impls! { i8 i16 i32 i64 }

#[cfg(feature = "i128")]
itype_impls! { i128 }

macro_rules! utype_impls {
    ($($T:ty)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
            impl NearlyEq for $T {
                fn eps() -> $T {
                    0
                }

                fn eq(&self, other: &$T, eps: &$T) -> bool {
                    let diff = if *self > *other { *self - *other } else { *other - *self };

                    if *self == *other {
                        true
                    } else {
                        diff < *eps
                    }
                }
            }
        )+
    }
}

utype_impls! { u8 u16 u32 u64 }

#[cfg(feature = "i128")]
utype_impls! { u128 }

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<[A], B> for [C] {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &[A], eps: &B) -> bool {
        if self.len() != other.len() {
            false
        } else {
            for i in 0..self.len() {
                if self[i].ne(&other[i], eps) {
                    return false;
                }
            }
            true
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Vec<A>, B> for Vec<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Vec<A>, eps: &B) -> bool {
        if self.len() != other.len() {
            false
        } else {
            for i in 0..self.len() {
                if self[i].ne(&other[i], eps) {
                    return false;
                }
            }
            true
        }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
impl<'a, A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<A, B> for &'a C {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &A, eps: &B) -> bool {
        (**self).eq(&other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.0"))]
impl<'a, A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<A, B> for &'a mut C {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &A, eps: &B) -> bool {
        (**self).eq(&other, eps)
    }
}

macro_rules! array_impls {
    ($($N:expr)+) => {
        $(
            #[cfg_attr(feature = "docs", stable(feature = "default", since = "0.1.0"))]
            impl<A, B, C: NearlyEq<A, B>> NearlyEq<[A; $N], B> for [C; $N] {
                fn eps() -> B {
                    C::eps()
                }

                fn eq(&self, other: &[A; $N], eps: &B) -> bool {
                    for i in 0..$N {
                        if self[i].ne(&other[i], eps) {
                            return false;
                        }
                    }
                    true
                }
            }
        )+
    }
}

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

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.1"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Option<A>, B> for Option<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Option<A>, eps: &B) -> bool {
            match (self, other) {
                (&None, &None) => return true,
                (&None, _) | (_, &None) => return false,
                (&Some(ref x), &Some(ref y)) => x.eq(y, eps),
            }
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Rc<A>, B> for Rc<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Rc<A>, eps: &B) -> bool {
        self.as_ref().eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Arc<A>, B> for Arc<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Arc<A>, eps: &B) -> bool {
        self.as_ref().eq(other, eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A, B, C: NearlyEq<A, B>> NearlyEq<Weak<A>, B> for Weak<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Weak<A>, eps: &B) -> bool {
        self.upgrade().eq(&other.upgrade(), eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A: Copy + ?Sized, B, C: NearlyEq<A, B> +  Copy + ?Sized> NearlyEq<Cell<A>, B> for Cell<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &Cell<A>, eps: &B) -> bool {
        (*self).get().eq(&(*other).get(), eps)
    }
}

#[cfg_attr(feature = "docs", stable(feature = "default", since = "0.2.2"))]
impl<A: ?Sized, B, C: NearlyEq<A, B> + ?Sized> NearlyEq<RefCell<A>, B> for RefCell<C> {
    fn eps() -> B {
        C::eps()
    }

    fn eq(&self, other: &RefCell<A>, eps: &B) -> bool {
        (*self).borrow().eq(&(*other).borrow(), eps)
    }
}
<|endoftext|>


<commit_before>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/persistent")]
#![license = "MIT"]
//#![deny(missing_doc)]
#![deny(warnings)]
#![feature(default_type_params)]

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate typemap;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use std::sync::{Arc, RWLock, Mutex};
use typemap::Assoc;
use plugin::{PluginFor, Phantom};

pub struct State<P, D> {
    data: Arc<RWLock<D>>
}

pub struct Read<P, D> {
    data: Arc<D>
}

pub struct Write<P, D> {
    data: Arc<Mutex<D>>
}

impl<P, D: Send + Sync> Clone for Read<P, D> {
    fn clone(&self) -> Read<P, D> {
        Read { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for State<P, D> {
    fn clone(&self) -> State<P, D> {
        State { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for Write<P, D> {
    fn clone(&self) -> Write<P, D> {
        Write { data: self.data.clone() }
    }
}

impl<P, D> Assoc<Arc<RWLock<D>>> for State<P, D> where P: Assoc<D> {}
impl<P, D> Assoc<Arc<D>> for Read<P, D> where P: Assoc<D> {}
impl<P, D> Assoc<Arc<Mutex<D>>> for Write<P, D> where P: Assoc<D> {}

impl<P, D> PluginFor<Request, Arc<RWLock<D>>> for State<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<State<P, D>>) -> Option<Arc<RWLock<D>>> {
        req.extensions.find::<State<P, D>, Arc<RWLock<D>>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<D>> for Read<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<Read<P, D>>) -> Option<Arc<D>> {
        req.extensions.find::<Read<P, D>, Arc<D>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<Mutex<D>>> for Write<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<Write<P, D>>) -> Option<Arc<Mutex<D>>> {
        req.extensions.find::<Write<P, D>, Arc<Mutex<D>>>()
            .map(|x| x.clone())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for State<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for State<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Read<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Read<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Write<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Write<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<P, D> State<P, D> where D: Send + Sync, P: Assoc<D> {
    pub fn new(start: D) -> (State<P, D>, State<P, D>) {
        let x = State { data: Arc::new(RWLock::new(start)) };
        (x.clone(), x)
    }
}

impl<P, D> Read<P, D> where D: Send + Sync, P: Assoc<D> {
    pub fn new(start: D) -> (Read<P, D>, Read<P, D>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }
}

impl<P, D> Write<P, D> where D: Send + Sync, P: Assoc<D> {
    pub fn new(start: D) -> (Write<P, D>, Write<P, D>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }
}

<commit_msg>(doc) Documented the new Persistent.<commit_after>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/persistent")]
#![license = "MIT"]
#![deny(missing_doc)]
#![deny(warnings)]
#![feature(default_type_params)]

//! A set of middleware for sharing data between requests in the Iron
//! framework.

extern crate iron;
extern crate typemap;
extern crate plugin;

use iron::{Request, Response, BeforeMiddleware, AfterMiddleware, IronResult};
use std::sync::{Arc, RWLock, Mutex};
use typemap::Assoc;
use plugin::{PluginFor, Phantom};

/// Middleware for data that persists between requests with read and write capabilities.
///
/// The data is stored behind a `RWLock`, so multiple read locks
/// can be taken out concurrently.
///
/// If most threads need to take out a write lock, you may want to
/// consider `Write`, which stores the data behind a `Mutex`, which
/// has a faster locking speed.
///
/// `State` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `State` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<State<P, D>>()` as an `Arc<RWLock<D>>`.
pub struct State<P, D> {
    data: Arc<RWLock<D>>
}

/// Middleware for data that persists between Requests with read-only capabilities.
///
/// The data is stored behind an Arc, so multiple threads can have
/// concurrent, non-blocking access.
///
/// `Read` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Read` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Read<P, D>>()` as an `Arc<D>`.
pub struct Read<P, D> {
    data: Arc<D>
}

/// Middleware for data that persists between Requests for data which mostly
/// needs to be written instead of read.
///
/// The data is stored behind a `Mutex`, so only one request at a time can
/// access the data. This is more performant than `State` in the case where
/// most uses of the data require a write lock.
///
/// `Write` can be linked as `BeforeMiddleware` to add data to the `Request`
/// extensions and it can be linked as an `AfterMiddleware` to add data to
/// the `Response` extensions.
///
/// `Write` also implements `PluginFor`, so the data stored within can be
/// accessed through `request.get::<Write<P, D>>()` as an `Arc<Mutex<D>>`.
pub struct Write<P, D> {
    data: Arc<Mutex<D>>
}

impl<P, D: Send + Sync> Clone for Read<P, D> {
    fn clone(&self) -> Read<P, D> {
        Read { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for State<P, D> {
    fn clone(&self) -> State<P, D> {
        State { data: self.data.clone() }
    }
}

impl<P, D: Send + Sync> Clone for Write<P, D> {
    fn clone(&self) -> Write<P, D> {
        Write { data: self.data.clone() }
    }
}

impl<P, D> Assoc<Arc<RWLock<D>>> for State<P, D> where P: Assoc<D> {}
impl<P, D> Assoc<Arc<D>> for Read<P, D> where P: Assoc<D> {}
impl<P, D> Assoc<Arc<Mutex<D>>> for Write<P, D> where P: Assoc<D> {}

impl<P, D> PluginFor<Request, Arc<RWLock<D>>> for State<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<State<P, D>>) -> Option<Arc<RWLock<D>>> {
        req.extensions.find::<State<P, D>, Arc<RWLock<D>>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<D>> for Read<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<Read<P, D>>) -> Option<Arc<D>> {
        req.extensions.find::<Read<P, D>, Arc<D>>()
            .map(|x| x.clone())
    }
}

impl<P, D> PluginFor<Request, Arc<Mutex<D>>> for Write<P, D>
    where D: Send + Sync,
          P: Assoc<D> {
    fn eval(req: &Request, _: Phantom<Write<P, D>>) -> Option<Arc<Mutex<D>>> {
        req.extensions.find::<Write<P, D>, Arc<Mutex<D>>>()
            .map(|x| x.clone())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for State<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for State<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<State<P, D>, Arc<RWLock<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Read<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Read<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Read<P, D>, Arc<D>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> BeforeMiddleware for Write<P, D> {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<D: Send + Sync, P: Assoc<D>> AfterMiddleware for Write<P, D> {
    fn after(&self, _: &mut Request, res: &mut Response) -> IronResult<()> {
        res.extensions.insert::<Write<P, D>, Arc<Mutex<D>>>(self.data.clone());
        Ok(())
    }
}

impl<P, D> State<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `State` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (State<P, D>, State<P, D>) {
        let x = State { data: Arc::new(RWLock::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `State` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> State<P, D> {
        State { data: Arc::new(RWLock::new(start)) }
    }
}

impl<P, D> Read<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `Read` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Read<P, D>, Read<P, D>) {
        let x = Read { data: Arc::new(start) };
        (x.clone(), x)
    }

    /// Construct a new `Read` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Read<P, D> {
        Read { data: Arc::new(start) }
    }
}

impl<P, D> Write<P, D> where D: Send + Sync, P: Assoc<D> {
    /// Construct a new pair of `Write` that can be passed directly to `Chain::link`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn both(start: D) -> (Write<P, D>, Write<P, D>) {
        let x = Write { data: Arc::new(Mutex::new(start)) };
        (x.clone(), x)
    }

    /// Construct a new `Write` that can be passed directly to
    /// `Chain::link_before` or `Chain::link_after`.
    ///
    /// The data is initialized with the passed-in value.
    pub fn one(start: D) -> Write<P, D> {
        Write { data: Arc::new(Mutex::new(start)) }
    }
}

<|endoftext|>


<commit_before>// lib.rs
// Copyright 2016 Alexander Altman
//
// 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.

use std::ops::Index;
use std::marker::PhantomData;
use std::fmt;

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub enum Position {
  White,
  Black,
  Empty,
}

impl Position {
  pub fn is_occupied(&self) -> bool { self != &Position::Empty }

  pub fn is_empty(&self) -> bool { self == &Position::Empty }

  pub fn is_white(&self) -> bool { self == &Position::White }

  pub fn is_black(&self) -> bool { self == &Position::Black }
}

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub struct Papamu {
  board: [[Position; 10]; 10],
}

impl Default for Papamu {
  fn default() -> Papamu {
    let mut board = [[Position::White; 10]; 10];
    for (_, pos) in board.iter_mut().enumerate().flat_map(|(x, part)| {
      part.iter_mut().enumerate().filter(move |&(y, _)| (x + y) % 2 == 0)
    }) {
      *pos = Position::Black;
    }
    Papamu { board: board }
  }
}

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub struct Ix {
  x: u8,
  y: u8,
}

impl Ix {
  pub fn mk(x: u8, y: u8) -> Option<Ix> { if x <= 9 && y <= 9 { Some(Ix { x: x, y: y }) } else { None } }

  pub fn x(&self) -> u8 { self.x }

  pub fn set_x(&mut self, new_x: u8) -> bool {
    if new_x <= 9 {
      self.x = new_x;
      true
    } else {
      false
    }
  }

  pub fn y(&self) -> u8 { self.y }

  pub fn set_y(&mut self, new_y: u8) -> bool {
    if new_y <= 9 {
      self.y = new_y;
      true
    } else {
      false
    }
  }
}

impl From<Ix> for (u8, u8) {
  fn from(ix: Ix) -> (u8, u8) { (ix.x, ix.y) }
}

impl Index<Ix> for Papamu {
  type Output = Position;

  fn index(&self, ix: Ix) -> &Position { &self.board[usize::from(ix.x)][usize::from(ix.y)] }
}

pub mod turn {
  pub enum Black {}

  pub enum White {}

  pub trait Turn {
    type Next: Turn;

    fn piece_type() -> super::Position;
  }

  impl Turn for Black {
    type Next = White;

    fn piece_type() -> super::Position { super::Position::Black }
  }

  impl Turn for White {
    type Next = Black;

    fn piece_type() -> super::Position { super::Position::White }
  }
}

pub struct Game<Tn: turn::Turn> {
  papamu: Papamu,
  phantom_turn: PhantomData<Tn>,
}

impl<Tn: turn::Turn> fmt::Debug for Game<Tn> {
  fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
    fmtr.debug_struct("Game").field("papamu", &self.papamu).field("phantom_turn", &self.phantom_turn).finish()
  }
}

impl<Tn: turn::Turn> Default for Game<Tn> {
  fn default() -> Game<Tn> {
    Game {
      papamu: Papamu::default(),
      phantom_turn: PhantomData,
    }
  }
}

#[allow(unknown_lints, expl_impl_clone_on_copy)]
impl<Tn: turn::Turn> Clone for Game<Tn> {
  fn clone(&self) -> Game<Tn> { *self }
}

impl<Tn: turn::Turn> Copy for Game<Tn> {}

impl<Tn: turn::Turn> Index<Ix> for Game<Tn> {
  type Output = Position;

  fn index(&self, ix: Ix) -> &Position { &self.papamu[ix] }
}

impl<Tn: turn::Turn> Game<Tn> {
  pub fn papamu(&self) -> Papamu {
    self.papamu
  }
}
<commit_msg>Formatting<commit_after>// lib.rs
// Copyright 2016 Alexander Altman
//
// 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.

use std::ops::Index;
use std::marker::PhantomData;
use std::fmt;

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub enum Position {
  White,
  Black,
  Empty,
}

impl Position {
  pub fn is_occupied(&self) -> bool { self != &Position::Empty }

  pub fn is_empty(&self) -> bool { self == &Position::Empty }

  pub fn is_white(&self) -> bool { self == &Position::White }

  pub fn is_black(&self) -> bool { self == &Position::Black }
}

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub struct Papamu {
  board: [[Position; 10]; 10],
}

impl Default for Papamu {
  fn default() -> Papamu {
    let mut board = [[Position::White; 10]; 10];
    for (_, pos) in board.iter_mut().enumerate().flat_map(|(x, part)| {
      part.iter_mut().enumerate().filter(move |&(y, _)| (x + y) % 2 == 0)
    }) {
      *pos = Position::Black;
    }
    Papamu { board: board }
  }
}

#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
pub struct Ix {
  x: u8,
  y: u8,
}

impl Ix {
  pub fn mk(x: u8, y: u8) -> Option<Ix> { if x <= 9 && y <= 9 { Some(Ix { x: x, y: y }) } else { None } }

  pub fn x(&self) -> u8 { self.x }

  pub fn set_x(&mut self, new_x: u8) -> bool {
    if new_x <= 9 {
      self.x = new_x;
      true
    } else {
      false
    }
  }

  pub fn y(&self) -> u8 { self.y }

  pub fn set_y(&mut self, new_y: u8) -> bool {
    if new_y <= 9 {
      self.y = new_y;
      true
    } else {
      false
    }
  }
}

impl From<Ix> for (u8, u8) {
  fn from(ix: Ix) -> (u8, u8) { (ix.x, ix.y) }
}

impl Index<Ix> for Papamu {
  type Output = Position;

  fn index(&self, ix: Ix) -> &Position { &self.board[usize::from(ix.x)][usize::from(ix.y)] }
}

pub mod turn {
  pub enum Black {}

  pub enum White {}

  pub trait Turn {
    type Next: Turn;

    fn piece_type() -> super::Position;
  }

  impl Turn for Black {
    type Next = White;

    fn piece_type() -> super::Position { super::Position::Black }
  }

  impl Turn for White {
    type Next = Black;

    fn piece_type() -> super::Position { super::Position::White }
  }
}

pub struct Game<Tn: turn::Turn> {
  papamu: Papamu,
  phantom_turn: PhantomData<Tn>,
}

impl<Tn: turn::Turn> fmt::Debug for Game<Tn> {
  fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
    fmtr.debug_struct("Game").field("papamu", &self.papamu).field("phantom_turn", &self.phantom_turn).finish()
  }
}

impl<Tn: turn::Turn> Default for Game<Tn> {
  fn default() -> Game<Tn> {
    Game {
      papamu: Papamu::default(),
      phantom_turn: PhantomData,
    }
  }
}

#[allow(unknown_lints, expl_impl_clone_on_copy)]
impl<Tn: turn::Turn> Clone for Game<Tn> {
  fn clone(&self) -> Game<Tn> { *self }
}

impl<Tn: turn::Turn> Copy for Game<Tn> {}

impl<Tn: turn::Turn> Index<Ix> for Game<Tn> {
  type Output = Position;

  fn index(&self, ix: Ix) -> &Position { &self.papamu[ix] }
}

impl<Tn: turn::Turn> Game<Tn> {
  pub fn papamu(&self) -> Papamu { self.papamu }
}
<|endoftext|>


<commit_before>
extern crate crc16;
extern crate time;
extern crate serial;

mod stub;
mod protocol;

use std::io::prelude::*;
use std::io;
use time::Duration;
use serial::prelude::*;
use std::rc::Rc;
use std::cell::RefCell;

pub use protocol::ProtocolSnoop;

struct PlugwiseInner<'a, I> {
    protocol: Rc<RefCell<protocol::Protocol<'a, I>>>
}

struct CircleInner<'a, I> {
    protocol: Rc<RefCell<protocol::Protocol<'a, I>>>,
    mac: u64,
    calibration_data: protocol::ResCalibration
}

impl<'a, I: Read+Write+'a> PlugwiseInner<'a, I> {
    fn initialize(port: I) -> io::Result<PlugwiseInner<'a, I>> {
        let plugwise = PlugwiseInner {
            protocol: Rc::new(RefCell::new(protocol::Protocol::new(port)))
        };

        let result = try!(plugwise.protocol.borrow_mut().initialize());

        if !result.is_online {
            return Err(io::Error::new(io::ErrorKind::Other, "not online"));
        }

        Ok(plugwise)
    }
}

pub trait Plugwise<'a> {
    fn create_circle(&self, mac: u64) -> io::Result<Box<Circle + 'a>>;
    fn set_snoop(&self, snoop: ProtocolSnoop<'a>);
}

pub trait Circle {
    fn switch_on(&self) -> io::Result<()>;
    fn switch_off(&self) -> io::Result<()>;
    fn is_switched_on(&self) -> io::Result<bool>;
    fn get_actual_watt_usage(&self) -> io::Result<f64>;
    fn get_clock(&self) -> io::Result<time::Tm>;
    fn set_clock(&self, tm: time::Tm) -> io::Result<()>;
}

impl<'a, I:Read+Write+'a> Plugwise<'a> for PlugwiseInner<'a, I> {
    fn create_circle(&self, mac: u64) -> io::Result<Box<Circle+ 'a>> {
        let calibration_data = try!(self.protocol.borrow_mut().calibrate(mac));
        Ok(Box::new(CircleInner {
            protocol: self.protocol.clone(),
            mac: mac,
            calibration_data: calibration_data
        }))
    }

    fn set_snoop(&self, snoop: ProtocolSnoop<'a>) {
        self.protocol.borrow_mut().set_snoop(snoop);
    }
}

impl<'a, I:Read+Write+'a> Circle for CircleInner<'a, I> {
    fn switch_on(&self) -> io::Result<()> {
        try!(self.protocol.borrow_mut().switch(self.mac, true));
        Ok(())
    }

    fn switch_off(&self) -> io::Result<()> {
        try!(self.protocol.borrow_mut().switch(self.mac, false));
        Ok(())
    }

    fn is_switched_on(&self) -> io::Result<bool> {
        let info = try!(self.protocol.borrow_mut().get_info(self.mac));
        Ok(info.relay_state)
    }

    fn get_actual_watt_usage(&self) -> io::Result<f64> {
        let power_usage = try!(self.protocol.borrow_mut().get_power_usage(self.mac));
        Ok(power_usage.pulse_8s.to_watts(self.calibration_data))
    }

    fn get_clock(&self) -> io::Result<time::Tm> {
        let info = try!(self.protocol.borrow_mut().get_info(self.mac));
        let clock = try!(self.protocol.borrow_mut().get_clock_info(self.mac));

        let mut tm = match info.datetime.to_tm() {
            Some(tm) => tm,
            None => return Err(io::Error::new(io::ErrorKind::Other, "circle returns an invalid timestamp"))
        };
        tm.tm_sec = clock.second as i32;
        tm.tm_min = clock.minute as i32;
        tm.tm_hour = clock.hour as i32;
        tm.tm_wday = (clock.day_of_week % 7) as i32;
        Ok(tm)
    }

    fn set_clock(&self, tm: time::Tm) -> io::Result<()> {
        let clock_set = protocol::ReqClockSet::new_from_tm(tm);
        try!(self.protocol.borrow_mut().set_clock(self.mac, clock_set));
        Ok(())
    }
}

pub fn plugwise_device<'a>(device: &str) -> io::Result<Box<Plugwise<'a>+ 'a>> {
    let mut port = try!(serial::open(device));
    try!(port.configure(|settings| {
        settings.set_baud_rate(serial::Baud115200);
        settings.set_char_size(serial::Bits8);
        settings.set_parity(serial::ParityNone);
        settings.set_stop_bits(serial::Stop1);
    }));

    port.set_timeout(Duration::milliseconds(1000));
    let plugwise = try!(PlugwiseInner::initialize(port));

    Ok(Box::new(plugwise))
}

pub fn plugwise_simulator<'a>() -> io::Result<Box<Plugwise<'a>+ 'a>> {
    let port = stub::Stub::new();

    let plugwise = try!(PlugwiseInner::initialize(port));

    Ok(Box::new(plugwise))
}
<commit_msg>Add smoke tester for external interface<commit_after>
extern crate crc16;
extern crate time;
extern crate serial;

mod stub;
mod protocol;

use std::io::prelude::*;
use std::io;
use time::Duration;
use serial::prelude::*;
use std::rc::Rc;
use std::cell::RefCell;

pub use protocol::ProtocolSnoop;

struct PlugwiseInner<'a, I> {
    protocol: Rc<RefCell<protocol::Protocol<'a, I>>>
}

struct CircleInner<'a, I> {
    protocol: Rc<RefCell<protocol::Protocol<'a, I>>>,
    mac: u64,
    calibration_data: protocol::ResCalibration
}

impl<'a, I: Read+Write+'a> PlugwiseInner<'a, I> {
    fn initialize(port: I) -> io::Result<PlugwiseInner<'a, I>> {
        let plugwise = PlugwiseInner {
            protocol: Rc::new(RefCell::new(protocol::Protocol::new(port)))
        };

        let result = try!(plugwise.protocol.borrow_mut().initialize());

        if !result.is_online {
            return Err(io::Error::new(io::ErrorKind::Other, "not online"));
        }

        Ok(plugwise)
    }
}

pub trait Plugwise<'a> {
    fn create_circle(&self, mac: u64) -> io::Result<Box<Circle + 'a>>;
    fn set_snoop(&self, snoop: ProtocolSnoop<'a>);
}

pub trait Circle {
    fn switch_on(&self) -> io::Result<()>;
    fn switch_off(&self) -> io::Result<()>;
    fn is_switched_on(&self) -> io::Result<bool>;
    fn get_actual_watt_usage(&self) -> io::Result<f64>;
    fn get_clock(&self) -> io::Result<time::Tm>;
    fn set_clock(&self, tm: time::Tm) -> io::Result<()>;
}

impl<'a, I:Read+Write+'a> Plugwise<'a> for PlugwiseInner<'a, I> {
    fn create_circle(&self, mac: u64) -> io::Result<Box<Circle+ 'a>> {
        let calibration_data = try!(self.protocol.borrow_mut().calibrate(mac));
        Ok(Box::new(CircleInner {
            protocol: self.protocol.clone(),
            mac: mac,
            calibration_data: calibration_data
        }))
    }

    fn set_snoop(&self, snoop: ProtocolSnoop<'a>) {
        self.protocol.borrow_mut().set_snoop(snoop);
    }
}

impl<'a, I:Read+Write+'a> Circle for CircleInner<'a, I> {
    fn switch_on(&self) -> io::Result<()> {
        try!(self.protocol.borrow_mut().switch(self.mac, true));
        Ok(())
    }

    fn switch_off(&self) -> io::Result<()> {
        try!(self.protocol.borrow_mut().switch(self.mac, false));
        Ok(())
    }

    fn is_switched_on(&self) -> io::Result<bool> {
        let info = try!(self.protocol.borrow_mut().get_info(self.mac));
        Ok(info.relay_state)
    }

    fn get_actual_watt_usage(&self) -> io::Result<f64> {
        let power_usage = try!(self.protocol.borrow_mut().get_power_usage(self.mac));
        Ok(power_usage.pulse_8s.to_watts(self.calibration_data))
    }

    fn get_clock(&self) -> io::Result<time::Tm> {
        let info = try!(self.protocol.borrow_mut().get_info(self.mac));
        let clock = try!(self.protocol.borrow_mut().get_clock_info(self.mac));

        let mut tm = match info.datetime.to_tm() {
            Some(tm) => tm,
            None => return Err(io::Error::new(io::ErrorKind::Other, "circle returns an invalid timestamp"))
        };
        tm.tm_sec = clock.second as i32;
        tm.tm_min = clock.minute as i32;
        tm.tm_hour = clock.hour as i32;
        tm.tm_wday = (clock.day_of_week % 7) as i32;
        Ok(tm)
    }

    fn set_clock(&self, tm: time::Tm) -> io::Result<()> {
        let clock_set = protocol::ReqClockSet::new_from_tm(tm);
        try!(self.protocol.borrow_mut().set_clock(self.mac, clock_set));
        Ok(())
    }
}

pub fn plugwise_device<'a>(device: &str) -> io::Result<Box<Plugwise<'a>+ 'a>> {
    let mut port = try!(serial::open(device));
    try!(port.configure(|settings| {
        settings.set_baud_rate(serial::Baud115200);
        settings.set_char_size(serial::Bits8);
        settings.set_parity(serial::ParityNone);
        settings.set_stop_bits(serial::Stop1);
    }));

    port.set_timeout(Duration::milliseconds(1000));
    let plugwise = try!(PlugwiseInner::initialize(port));

    Ok(Box::new(plugwise))
}

pub fn plugwise_simulator<'a>() -> io::Result<Box<Plugwise<'a>+ 'a>> {
    let port = stub::Stub::new();

    let plugwise = try!(PlugwiseInner::initialize(port));

    Ok(Box::new(plugwise))
}

#[test]
fn smoke_external_stub() {
    let stub = plugwise_simulator().unwrap();
    let circle = stub.create_circle(0x01234567890ABCDEF).unwrap();
    circle.switch_on().unwrap();
    assert_eq!(circle.is_switched_on().unwrap(), true);
    circle.switch_off().unwrap();
    assert_eq!(circle.is_switched_on().unwrap(), false);
    circle.get_actual_watt_usage().unwrap();
    let tm = circle.get_clock().unwrap();
    circle.set_clock(tm).unwrap();
}
<|endoftext|>


<commit_before>mod parser;

use std::path::Path;
use std::collections::HashMap;
use std::io::{BufReader, Read};
use std::fs::File;
use std::str::FromStr;

use parser::{parse_line, Parsed};

type IniParsed = HashMap<String, HashMap<String, String>>;

#[derive(Debug)]
pub struct Ini(IniParsed);

impl<'a> Ini {
    fn new() -> Ini {
        Ini(HashMap::new())
    }
    fn from_string(string: &str) -> Ini {
        let mut result = Ini::new();
        let mut section_name = String::new();
        let mut entry_list = HashMap::new();
        for (i, line) in string.lines().enumerate() {
            match parse_line(&line) {
                Parsed::Section(name) => {
                    if section_name.len() != 0 {
                        result.0.insert(section_name, entry_list.clone());
                        entry_list.clear();
                    }
                    section_name = name;
                }
                Parsed::Value(name, value) => {
                    entry_list.insert(name, value);
                }
                Parsed::Error(msg) => println!("line {}: error: {}", i, msg),
                _ => (),
            };
        }
        // add last section
        if section_name.len() != 0 {
            result.0.insert(section_name, entry_list.clone());
            entry_list.clear();
        }
        result
    }

    pub fn from_file<S: AsRef<Path> + ?Sized>(path: &S) -> Ini {
        let file = File::open(path)
                       .expect(&format!("Can't open `{}`!", path.as_ref().display()));
        let mut reader = BufReader::new(file);
        let mut buffer = String::new();
        let _ = reader.read_to_string(&mut buffer)
                      .expect(&format!("Can't read `{}`!", path.as_ref().display()));
        Ini::from_string(&buffer)
    }
    pub fn from_buffer<S: Into<String>>(buf: S) -> Ini {
        Ini::from_string(&buf.into())
    }
    fn get_raw(&'a self, section: &str, key: &str) -> Option<&String> {
        let s = self.0.get(section);
        match s {
            Some(hm) => hm.get(key),
            None => None,
        }
    }
    pub fn get<T: FromStr>(&'a self, section: &str, key: &str) -> Option<T> {
        let data = self.get_raw(section, key);
        match data {
            Some(x) => x.parse().ok(),
            None => None
        }
    }
    pub fn get_def<T: FromStr>(&'a self, section: &str, key: &str, default: T) -> T {
        let s = self.get_raw(section, key);
        match s {
            Some(x) => x.parse().unwrap_or(default),
            None => default,
        }
    }
    pub fn get_vec<T>(&'a self, section: &str, key: &str, default: &[T]) -> Vec<T>
        where T: FromStr + Copy + Clone
    {
        let s = self.get_raw(section, key);
        match s {
            Some(x) => {
                x.split(',')
                 .zip(default)
                 .map(|(s, &d)| s.trim().parse().unwrap_or(d))
                 .collect()
            }
            None => default.to_vec(),
        }
    }
}

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

    #[test]
    fn test_int() {
        let input: String = "[string]\nabc = 10".to_owned();
        let ini = Ini::from_buffer(input);
        let abc: Option<u32> = ini.get("string", "abc");
        assert_eq!(abc, Some(10));
    }

    #[test]
    fn test_float_def() {
        let ini = Ini::from_string("[section]\nname=10.5");
        let name: f64 = ini.get_def("section", "name", 0.0);
        assert_eq!(name, 10.5);
    }

    #[test]
    fn test_float_vec() {
        let ini = Ini::from_string("[section]\nname=1.2, 3.4, 5.6");
        let name: Vec<f64> = ini.get_vec("section", "name", &[0.0, 0.0, 0.0]);
        assert_eq!(name, [1.2, 3.4, 5.6]);
    }
}
<commit_msg>[rm] lifetime parameter<commit_after>mod parser;

use std::path::Path;
use std::collections::HashMap;
use std::io::{BufReader, Read};
use std::fs::File;
use std::str::FromStr;

use parser::{parse_line, Parsed};

type IniParsed = HashMap<String, HashMap<String, String>>;

#[derive(Debug)]
pub struct Ini(IniParsed);

impl Ini {
    fn new() -> Ini {
        Ini(HashMap::new())
    }
    fn from_string(string: &str) -> Ini {
        let mut result = Ini::new();
        let mut section_name = String::new();
        let mut entry_list = HashMap::new();
        for (i, line) in string.lines().enumerate() {
            match parse_line(&line) {
                Parsed::Section(name) => {
                    if section_name.len() != 0 {
                        result.0.insert(section_name, entry_list.clone());
                        entry_list.clear();
                    }
                    section_name = name;
                }
                Parsed::Value(name, value) => {
                    entry_list.insert(name, value);
                }
                Parsed::Error(msg) => println!("line {}: error: {}", i, msg),
                _ => (),
            };
        }
        // add last section
        if section_name.len() != 0 {
            result.0.insert(section_name, entry_list.clone());
            entry_list.clear();
        }
        result
    }

    pub fn from_file<S: AsRef<Path> + ?Sized>(path: &S) -> Ini {
        let file = File::open(path).expect(&format!("Can't open `{}`!", path.as_ref().display()));
        let mut reader = BufReader::new(file);
        let mut buffer = String::new();
        let _ = reader.read_to_string(&mut buffer)
                      .expect(&format!("Can't read `{}`!", path.as_ref().display()));
        Ini::from_string(&buffer)
    }
    pub fn from_buffer<S: Into<String>>(buf: S) -> Ini {
        Ini::from_string(&buf.into())
    }
    fn get_raw(&self, section: &str, key: &str) -> Option<&String> {
        let s = self.0.get(section);
        match s {
            Some(hm) => hm.get(key),
            None => None,
        }
    }
    pub fn get<T: FromStr>(&self, section: &str, key: &str) -> Option<T> {
        let data = self.get_raw(section, key);
        match data {
            Some(x) => x.parse().ok(),
            None => None,
        }
    }
    pub fn get_def<T: FromStr>(&self, section: &str, key: &str, default: T) -> T {
        let s = self.get_raw(section, key);
        match s {
            Some(x) => x.parse().unwrap_or(default),
            None => default,
        }
    }
    pub fn get_vec<T>(&self, section: &str, key: &str, default: &[T]) -> Vec<T>
        where T: FromStr + Copy + Clone
    {
        let s = self.get_raw(section, key);
        match s {
            Some(x) => {
                x.split(',')
                 .zip(default)
                 .map(|(s, &d)| s.trim().parse().unwrap_or(d))
                 .collect()
            }
            None => default.to_vec(),
        }
    }
}

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

    #[test]
    fn test_int() {
        let input: String = "[string]\nabc = 10".to_owned();
        let ini = Ini::from_buffer(input);
        let abc: Option<u32> = ini.get("string", "abc");
        assert_eq!(abc, Some(10));
    }

    #[test]
    fn test_float_def() {
        let ini = Ini::from_string("[section]\nname=10.5");
        let name: f64 = ini.get_def("section", "name", 0.0);
        assert_eq!(name, 10.5);
    }

    #[test]
    fn test_float_vec() {
        let ini = Ini::from_string("[section]\nname=1.2, 3.4, 5.6");
        let name: Vec<f64> = ini.get_vec("section", "name", &[0.0, 0.0, 0.0]);
        assert_eq!(name, [1.2, 3.4, 5.6]);
    }
}
<|endoftext|>


<commit_before>extern crate cookie as _cookie;
#[macro_use] extern crate error_chain;
#[macro_use] extern crate iron;
extern crate rand;
#[cfg(feature = "redis-backend")] extern crate redis;
#[cfg(feature = "redis-backend")] extern crate r2d2;
#[cfg(feature = "redis-backend")] extern crate r2d2_redis;

use iron::prelude::*;
use iron::middleware::{AroundMiddleware,Handler};
use iron::typemap;

pub mod backends;
pub mod errors;

/// Re-export of the cookie crate
pub mod cookie {
    pub use _cookie::*;
}

/// A simple key-value storage interface that is internally used by `Session`. After request
/// handling the `write` method is called where the session backend has the chance to e.g. set
/// cookies or otherwise modify the response.
pub trait RawSession {
    fn get_raw(&self, key: &str) -> IronResult<Option<String>>;
    fn set_raw(&mut self, key: &str, value: String) -> IronResult<()>;
    fn clear(&mut self) -> IronResult<()>;
    fn write(&self, response: &mut Response) -> IronResult<()>;
}

pub trait SessionBackend: Send + Sync + 'static {
    type S: RawSession;

    /// Parse the session before request handling and return the data in parsed form.
    fn from_request(&self, request: &mut Request) -> Self::S;
}

/// The most important type, the middleware you need to register.
///
/// First parameter is a session backend, which determines how your session data is actually
/// stored. Depending on whether you store your data clientside (signed cookies) or serverside
/// (e.g. Redis and a session key) you're going to have different security properties.
pub struct SessionStorage<B: SessionBackend> {
    backend: B
}

impl<B: SessionBackend> SessionStorage<B> {
    pub fn new(backend: B) -> Self {
        SessionStorage {
            backend: backend
        }
    }
}

/// The high-level interface you use to modify session data. You obtain this object with
/// `request.session()`.
pub struct Session {
    inner: Box<RawSession>,
    has_changed: bool,
}

impl Session {
    fn new(s: Box<RawSession>) -> Self {
        Session {
            inner: s,
            has_changed: false
        }
    }
}

/// A typed interface to the string-to-string mapping. Each type represents a key, each instance of
/// a type can be serialized into a value.
pub trait Value: Sized + 'static {
    fn get_key() -> &'static str;
    fn into_raw(self) -> String;
    fn from_raw(value: String) -> Option<Self>;
}

impl Session {
    /// Get a `Value` from the session.
    pub fn get<T: Value + Sized + 'static>(&self) -> IronResult<Option<T>> {
        Ok(try!(self.inner.get_raw(T::get_key())).and_then(T::from_raw))
    }

    /// Set a `Value` in the session.
    pub fn set<T: Value>(&mut self, t: T) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.set_raw(T::get_key(), t.into_raw())
    }

    /// Clear/delete the session
    pub fn clear(&mut self) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.clear()
    }
}

struct SessionKey;
impl typemap::Key for SessionKey { type Value = Session; }

impl<B: SessionBackend> AroundMiddleware for SessionStorage<B> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(move |req: &mut Request| -> IronResult<Response> {
            let s = self.backend.from_request(req);
            req.extensions.insert::<SessionKey>(Session::new(Box::new(s)));
            let mut res = handler.handle(req);
            let s = req.extensions.remove::<SessionKey>().unwrap();
            if s.has_changed {
                match res {
                    Ok(ref mut r) => try!(s.inner.write(r)),
                    Err(ref mut e) => try!(s.inner.write(&mut e.response))
                }
            };
            res
        })
    }
}

/// The helper trait to obtain your session data from a request.
pub trait SessionRequestExt {
    fn session(&mut self) -> &mut Session;
}

impl<'a, 'b> SessionRequestExt for Request<'a, 'b> {
    fn session(&mut self) -> &mut Session {
        self.extensions.get_mut::<SessionKey>().unwrap()
    }
}

fn get_default_cookie(key: String, value: String) -> cookie::Cookie {
    let mut rv = cookie::Cookie::new(key, value);
    rv.httponly = true;
    rv.path = Some("/".to_owned());
    rv
}

/// A module with some important traits to star-import.
pub mod traits {
    pub use super::{SessionRequestExt};
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Refine iron include<commit_after>extern crate cookie as _cookie;
#[macro_use] extern crate error_chain;
#[cfg(feature = "redis-backend")] #[macro_use] extern crate iron;
#[cfg(not(feature = "redis-backend"))] extern crate iron;
extern crate rand;
#[cfg(feature = "redis-backend")] extern crate redis;
#[cfg(feature = "redis-backend")] extern crate r2d2;
#[cfg(feature = "redis-backend")] extern crate r2d2_redis;

use iron::prelude::*;
use iron::middleware::{AroundMiddleware,Handler};
use iron::typemap;

pub mod backends;
pub mod errors;

/// Re-export of the cookie crate
pub mod cookie {
    pub use _cookie::*;
}

/// A simple key-value storage interface that is internally used by `Session`. After request
/// handling the `write` method is called where the session backend has the chance to e.g. set
/// cookies or otherwise modify the response.
pub trait RawSession {
    fn get_raw(&self, key: &str) -> IronResult<Option<String>>;
    fn set_raw(&mut self, key: &str, value: String) -> IronResult<()>;
    fn clear(&mut self) -> IronResult<()>;
    fn write(&self, response: &mut Response) -> IronResult<()>;
}

pub trait SessionBackend: Send + Sync + 'static {
    type S: RawSession;

    /// Parse the session before request handling and return the data in parsed form.
    fn from_request(&self, request: &mut Request) -> Self::S;
}

/// The most important type, the middleware you need to register.
///
/// First parameter is a session backend, which determines how your session data is actually
/// stored. Depending on whether you store your data clientside (signed cookies) or serverside
/// (e.g. Redis and a session key) you're going to have different security properties.
pub struct SessionStorage<B: SessionBackend> {
    backend: B
}

impl<B: SessionBackend> SessionStorage<B> {
    pub fn new(backend: B) -> Self {
        SessionStorage {
            backend: backend
        }
    }
}

/// The high-level interface you use to modify session data. You obtain this object with
/// `request.session()`.
pub struct Session {
    inner: Box<RawSession>,
    has_changed: bool,
}

impl Session {
    fn new(s: Box<RawSession>) -> Self {
        Session {
            inner: s,
            has_changed: false
        }
    }
}

/// A typed interface to the string-to-string mapping. Each type represents a key, each instance of
/// a type can be serialized into a value.
pub trait Value: Sized + 'static {
    fn get_key() -> &'static str;
    fn into_raw(self) -> String;
    fn from_raw(value: String) -> Option<Self>;
}

impl Session {
    /// Get a `Value` from the session.
    pub fn get<T: Value + Sized + 'static>(&self) -> IronResult<Option<T>> {
        Ok(try!(self.inner.get_raw(T::get_key())).and_then(T::from_raw))
    }

    /// Set a `Value` in the session.
    pub fn set<T: Value>(&mut self, t: T) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.set_raw(T::get_key(), t.into_raw())
    }

    /// Clear/delete the session
    pub fn clear(&mut self) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.clear()
    }
}

struct SessionKey;
impl typemap::Key for SessionKey { type Value = Session; }

impl<B: SessionBackend> AroundMiddleware for SessionStorage<B> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(move |req: &mut Request| -> IronResult<Response> {
            let s = self.backend.from_request(req);
            req.extensions.insert::<SessionKey>(Session::new(Box::new(s)));
            let mut res = handler.handle(req);
            let s = req.extensions.remove::<SessionKey>().unwrap();
            if s.has_changed {
                match res {
                    Ok(ref mut r) => try!(s.inner.write(r)),
                    Err(ref mut e) => try!(s.inner.write(&mut e.response))
                }
            };
            res
        })
    }
}

/// The helper trait to obtain your session data from a request.
pub trait SessionRequestExt {
    fn session(&mut self) -> &mut Session;
}

impl<'a, 'b> SessionRequestExt for Request<'a, 'b> {
    fn session(&mut self) -> &mut Session {
        self.extensions.get_mut::<SessionKey>().unwrap()
    }
}

fn get_default_cookie(key: String, value: String) -> cookie::Cookie {
    let mut rv = cookie::Cookie::new(key, value);
    rv.httponly = true;
    rv.path = Some("/".to_owned());
    rv
}

/// A module with some important traits to star-import.
pub mod traits {
    pub use super::{SessionRequestExt};
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>use std::f64::consts::PI;

/// Calculates the volume of the n-sphere.
pub fn sphere_volume(radius: f64, dim: u64) -> f64 {
    let gamma = if dim % 2 == 0 {
        // This works because dim / 2 is a whole number.
        fact(dim / 2) as f64
    } else {
        // This works because the function is gamma(1/2 + n) where n = dim / 2 + 1
        let n = dim / 2 + 1;
        (fact(2 * n) as f64 / (4u64.pow(n as u32) * fact(n)) as f64) * PI.sqrt()
    };
    (PI.powf(0.5 * dim as f64) * radius.powf(dim as f64)) / gamma
}

#[test]
fn volume_of_1_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = PI * radius.powi(2);
        let actual = sphere_volume(radius, 2);
        let diff = (expected - actual).abs();
        let delta = 10f64.powi(-5);
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[test]
fn volume_of_2_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = (4. / 3.) * PI * radius.powi(3);
        let actual = sphere_volume(radius, 3);
        let diff = f64::abs_sub(expected, actual);
        let delta = 10f64.powi(-5);
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[test]
fn volume_of_3_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = (1. / 2.) * PI.powi(2) * radius.powi(4);
        let actual = sphere_volume(radius, 4);
        let diff = f64::abs_sub(expected, actual);
        let delta = 10f64.powi(-5);
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[inline]
fn fact(n: u64) -> u64 {
    //TODO: This could be made faster with better algorithm, but it's called with low values so it doesn't matter much.
    if n < 2 {
        1
    } else {
        n * fact(n - 1)
    }
}

#[test]
fn factorial_works() {
    assert_eq!(1, fact(0));
    let mut x = 1;
    for n in 1..21 {
        x *= n;
        assert_eq!(x, fact(n));
    }
}
<commit_msg>Changed tests.<commit_after>use std::f64::consts::PI;

/// Calculates the volume of the n-sphere.
pub fn sphere_volume(radius: f64, dim: u64) -> f64 {
    let gamma = if dim % 2 == 0 {
        // This works because dim / 2 is a whole number.
        fact(dim / 2) as f64
    } else {
        // This works because the function is gamma(1/2 + n) where n = dim / 2 + 1
        let n = dim / 2 + 1;
        (fact(2 * n) as f64 / (4u64.pow(n as u32) * fact(n)) as f64) * PI.sqrt()
    };
    (PI.powf(0.5 * dim as f64) * radius.powf(dim as f64)) / gamma
}

#[test]
fn volume_of_1_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = PI * radius.powi(2);
        let actual = sphere_volume(radius, 2);
        let diff = (expected - actual).abs();
        let delta = 0.0001;
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[test]
fn volume_of_2_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = (4. / 3.) * PI * radius.powi(3);
        let actual = sphere_volume(radius, 3);
        let diff = f64::abs_sub(expected, actual);
        let delta = 0.0001;
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[test]
fn volume_of_3_sphere_works() {
    for radius in (0..1000000).map(|n| n as f64 / 1000.) {
        let expected = (1. / 2.) * PI.powi(2) * radius.powi(4);
        let actual = sphere_volume(radius, 4);
        let diff = f64::abs_sub(expected, actual);
        let delta = 0.0001;
        assert!(diff < delta, "Expected: {}, Actual: {}, Difference {:e} >= {:e}", expected, actual, diff, delta);
    }
}

#[inline]
fn fact(n: u64) -> u64 {
    //TODO: This could be made faster with better algorithm, but it's called with low values so it doesn't matter much.
    if n < 2 {
        1
    } else {
        n * fact(n - 1)
    }
}

#[test]
fn factorial_works() {
    assert_eq!(1, fact(0));
    let mut x = 1;
    for n in 1..21 {
        x *= n;
        assert_eq!(x, fact(n));
    }
}
<|endoftext|>


<commit_before>//! A FAT filesystem library implemented in Rust.
//!
//! # Usage
//!
//! This crate is [on crates.io](https://crates.io/crates/fatfs) and can be
//! used by adding `fatfs` to the dependencies in your project's `Cargo.toml`.
//!
//! ```toml
//! [dependencies]
//! fatfs = "0.3"
//! ```
//!
//! And this in your crate root:
//!
//! ```rust
//! extern crate fatfs;
//! ```
//!
//! # Examples
//!
//! Initialize a filesystem object (note: `fscommon` crate is used to speedup IO operations):
//! ```rust
//! let img_file = File::open("fat.img")?;
//! let buf_stream = fscommon::BufStream::new(img_file);
//! let fs = fatfs::FileSystem::new(buf_stream, fatfs::FsOptions::new())?;
//! ```
//! Write a file:
//! ```rust
//! let root_dir = fs.root_dir();
//! root_dir.create_dir("foo/bar")?;
//! let mut file = root_dir.create_file("foo/bar/hello.txt")?;
//! file.truncate()?;
//! file.write_all(b"Hello World!")?;
//! ```
//! Read a directory:
//! ```rust
//! let root_dir = fs.root_dir();
//! let dir = root_dir.open_dir("foo/bar")?;
//! for r in dir.iter()? {
//!     let entry = r?;
//!     println!(entry.file_name());
//! }
//! ```

#![crate_type = "lib"]
#![crate_name = "fatfs"]

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

// Disable warnings to not clutter code with cfg too much
#![cfg_attr(not(feature="alloc"), allow(dead_code, unused_imports))]

extern crate byteorder;

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate log;

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

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

#[cfg(all(not(feature = "std"), feature = "alloc"))]
extern crate alloc;

mod fs;
mod dir;
mod dir_entry;
mod file;
mod table;

#[cfg(not(feature = "std"))]
mod byteorder_core_io;

#[cfg(not(feature = "std"))]
use byteorder_core_io as byteorder_ext;
#[cfg(feature = "std")]
use byteorder as byteorder_ext;
#[cfg(feature = "std")]
use std as core;
#[cfg(not(feature = "std"))]
use core_io as io;

#[cfg(feature = "std")]
use std::io as io;

pub use fs::*;
pub use dir::*;
pub use dir_entry::*;
pub use file::*;
<commit_msg>Fix doc-tests<commit_after>//! A FAT filesystem library implemented in Rust.
//!
//! # Usage
//!
//! This crate is [on crates.io](https://crates.io/crates/fatfs) and can be
//! used by adding `fatfs` to the dependencies in your project's `Cargo.toml`.
//!
//! ```toml
//! [dependencies]
//! fatfs = "0.3"
//! ```
//!
//! And this in your crate root:
//!
//! ```rust
//! extern crate fatfs;
//! ```
//!
//! # Examples
//!
//! ```rust
//! // Declare external crates
//! // Note: `fscommon` crate is used to speedup IO operations
//! extern crate fatfs;
//! extern crate fscommon;
//!
//! use std::io::prelude::*;
//!
//! fn main() -> std::io::Result<()> {
//!     # std::fs::copy("resources/fat16.img", "tmp/fat.img")?;
//!     // Initialize a filesystem object
//!     let img_file = std::fs::OpenOptions::new().read(true).write(true)
//!         .open("tmp/fat.img")?;
//!     let buf_stream = fscommon::BufStream::new(img_file);
//!     let fs = fatfs::FileSystem::new(buf_stream, fatfs::FsOptions::new())?;
//!     let root_dir = fs.root_dir();
//!
//!     // Write a file
//!     root_dir.create_dir("foo")?;
//!     let mut file = root_dir.create_file("foo/hello.txt")?;
//!     file.truncate()?;
//!     file.write_all(b"Hello World!")?;
//!
//!     // Read a directory
//!     let dir = root_dir.open_dir("foo")?;
//!     for r in dir.iter() {
//!         let entry = r?;
//!         println!("{}", entry.file_name());
//!     }
//!     # std::fs::remove_file("tmp/fat.img")?;
//!     # Ok(())
//! }
//! ```

#![crate_type = "lib"]
#![crate_name = "fatfs"]

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

// Disable warnings to not clutter code with cfg too much
#![cfg_attr(not(feature="alloc"), allow(dead_code, unused_imports))]

extern crate byteorder;

#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate log;

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

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

#[cfg(all(not(feature = "std"), feature = "alloc"))]
extern crate alloc;

mod fs;
mod dir;
mod dir_entry;
mod file;
mod table;

#[cfg(not(feature = "std"))]
mod byteorder_core_io;

#[cfg(not(feature = "std"))]
use byteorder_core_io as byteorder_ext;
#[cfg(feature = "std")]
use byteorder as byteorder_ext;
#[cfg(feature = "std")]
use std as core;
#[cfg(not(feature = "std"))]
use core_io as io;

#[cfg(feature = "std")]
use std::io as io;

pub use fs::*;
pub use dir::*;
pub use dir_entry::*;
pub use file::*;
<|endoftext|>


<commit_before>//!
//! # Example:
//!
//! ```rust
//! use to_string::*;
//! assert_eq!("0b1111000", 120.to_bin());
//! assert_eq!("0xcafe", 51966.to_hexa());
//! assert_eq!("0xdeadbeef", (-559038737).to_hexa());
//! assert_eq!("0o1747", 999.to_octal_string());
//! assert_eq!("4.21e1", (42.1).to_exp());
//! ```

use std::fmt::{Debug, Binary, LowerHex, Octal, LowerExp, Pointer};

pub trait BinaryDisplay {
    /// ```
    /// use to_string::BinaryDisplay;
    /// assert_eq!("0b0", 0.to_binary_string())
    /// ```
    fn to_binary_string(&self) -> String;
    /// ```
    /// use to_string::BinaryDisplay;
    /// assert_eq!("0b0", 0.to_bin())
    /// ```
    fn to_bin(&self) -> String { self.to_binary_string() }
}

impl<T : Binary> BinaryDisplay for T {
    fn to_binary_string(&self) -> String {
        format!("{:#b}", self)
    }
}

pub trait HexaDisplay {
    /// ```
    /// use to_string::HexaDisplay;
    /// assert_eq!("0x12", 0x12.to_hexa_string());
    /// assert_eq!("0xffffffee", (-0x12).to_hexa_string())
    /// ```
    fn to_hexa_string(&self) -> String;
    /// ```
    /// use to_string::HexaDisplay;
    /// assert_eq!("0x12", 0x12.to_hexa());
    /// assert_eq!("0xffffffee", (-0x12).to_hexa())
    /// ```
    fn to_hexa(&self) -> String { self.to_hexa_string() }
}

impl<T : LowerHex> HexaDisplay for T {
    fn to_hexa_string(&self) -> String {
        format!("{:#x}", self)
    }
}

pub trait OctalDisplay {
    /// ```
    /// use to_string::OctalDisplay;
    /// assert_eq!("0o12", 0o12.to_octal_string())
    /// ```
    fn to_octal_string(&self) -> String;
    /// ```
    /// use to_string::OctalDisplay;
    /// assert_eq!("0o12", 0o12.to_octal())
    /// ```
    fn to_octal(&self) -> String { self.to_octal_string() }

}

impl<T : Octal> OctalDisplay for T {
    fn to_octal_string(&self) -> String {
        format!("{:#o}", self)
    }
}

pub trait ExpDisplay {
    /// ```
    /// use to_string::ExpDisplay;
    /// assert_eq!("4.21e1", (42.1).to_exp_string())
    /// ```
    fn to_exp_string(&self) -> String;
    /// ```
    /// use to_string::ExpDisplay;
    /// assert_eq!("4.21e1", (42.1).to_exp())
    /// ```
    fn to_exp(&self) -> String { self.to_exp_string() }
}

impl<T : LowerExp> ExpDisplay for T {
    fn to_exp_string(&self) -> String {
        format!("{:#e}", self)
    }
}

pub trait PointerDisplay {
    /// ```
    /// use to_string::PointerDisplay;
    /// let val = 12;
    /// println!("{}", (&val).to_pointer()) // something like "0x00007fff5af30fa8"
    /// ```
    fn to_pointer_string(&self) -> String;
    /// ```
    /// use to_string::PointerDisplay;
    /// let val = 12;
    /// println!("{}", (&val).to_pointer()) // something like "0x00007fff5af30fa8"
    /// ```
    fn to_pointer(&self) -> String { self.to_pointer_string() }
}

impl<T : Pointer> PointerDisplay for T {
    fn to_pointer_string(&self) -> String {
        format!("{:#p}", self)
    }
}

pub trait DebugDisplay {
    /// ```
    /// use to_string::DebugDisplay;
    /// assert_eq!("12", 12.to_debug_string())
    /// ```
    fn to_debug_string(&self) -> String;
    /// ```
    /// use to_string::DebugDisplay;
    /// assert_eq!("12", 12.to_debug_string())
    /// ```
    fn to_debug(&self) -> String { self.to_debug_string() }
}

impl<T : Debug> DebugDisplay for T {
    fn to_debug_string(&self) -> String {
        format!("{:#?}", self)
    }
}

<commit_msg>Fix semicolons<commit_after>//!
//! # Example:
//!
//! ```rust
//! use to_string::*;
//! assert_eq!("0b1111000", 120.to_bin());
//! assert_eq!("0xcafe", 51966.to_hexa());
//! assert_eq!("0xdeadbeef", (-559038737).to_hexa());
//! assert_eq!("0o1747", 999.to_octal_string());
//! assert_eq!("4.21e1", (42.1).to_exp());
//! ```

use std::fmt::{Debug, Binary, LowerHex, Octal, LowerExp, Pointer};

pub trait BinaryDisplay {
    /// ```
    /// use to_string::BinaryDisplay;
    /// assert_eq!("0b0", 0.to_binary_string());
    /// ```
    fn to_binary_string(&self) -> String;
    /// ```
    /// use to_string::BinaryDisplay;
    /// assert_eq!("0b0", 0.to_bin());
    /// ```
    fn to_bin(&self) -> String { self.to_binary_string() }
}

impl<T : Binary> BinaryDisplay for T {
    fn to_binary_string(&self) -> String {
        format!("{:#b}", self)
    }
}

pub trait HexaDisplay {
    /// ```
    /// use to_string::HexaDisplay;
    /// assert_eq!("0x12", 0x12.to_hexa_string());
    /// assert_eq!("0xffffffee", (-0x12).to_hexa_string());
    /// ```
    fn to_hexa_string(&self) -> String;
    /// ```
    /// use to_string::HexaDisplay;
    /// assert_eq!("0x12", 0x12.to_hexa());
    /// assert_eq!("0xffffffee", (-0x12).to_hexa());
    /// assert_eq!("[0xfa, 0xfb, 0xfc]", [0xfa, 0xfb, 0xfc].to_hexa());
    /// ```
    fn to_hexa(&self) -> String { self.to_hexa_string() }
}

impl<T : LowerHex> HexaDisplay for T {
    fn to_hexa_string(&self) -> String {
        format!("{:#x}", self)
    }
}

pub trait OctalDisplay {
    /// ```
    /// use to_string::OctalDisplay;
    /// assert_eq!("0o12", 0o12.to_octal_string());
    /// ```
    fn to_octal_string(&self) -> String;
    /// ```
    /// use to_string::OctalDisplay;
    /// assert_eq!("0o12", 0o12.to_octal());
    /// ```
    fn to_octal(&self) -> String { self.to_octal_string() }

}

impl<T : Octal> OctalDisplay for T {
    fn to_octal_string(&self) -> String {
        format!("{:#o}", self)
    }
}

pub trait ExpDisplay {
    /// ```
    /// use to_string::ExpDisplay;
    /// assert_eq!("4.21e1", (42.1).to_exp_string());
    /// ```
    fn to_exp_string(&self) -> String;
    /// ```
    /// use to_string::ExpDisplay;
    /// assert_eq!("4.21e1", (42.1).to_exp());
    /// ```
    fn to_exp(&self) -> String { self.to_exp_string() }
}

impl<T : LowerExp> ExpDisplay for T {
    fn to_exp_string(&self) -> String {
        format!("{:#e}", self)
    }
}

pub trait PointerDisplay {
    /// ```
    /// use to_string::PointerDisplay;
    /// let val = 12;
    /// println!("{}", (&val).to_pointer()) // something like "0x00007fff5af30fa8"
    /// ```
    fn to_pointer_string(&self) -> String;
    /// ```
    /// use to_string::PointerDisplay;
    /// let val = 12;
    /// println!("{}", (&val).to_pointer()) // something like "0x00007fff5af30fa8"
    /// ```
    fn to_pointer(&self) -> String { self.to_pointer_string() }
}

impl<T : Pointer> PointerDisplay for T {
    fn to_pointer_string(&self) -> String {
        format!("{:#p}", self)
    }
}

pub trait DebugDisplay {
    /// ```
    /// use to_string::DebugDisplay;
    /// assert_eq!("12", 12.to_debug_string());
    /// ```
    fn to_debug_string(&self) -> String;
    /// ```
    /// use to_string::DebugDisplay;
    /// assert_eq!("12", 12.to_debug_string());
    /// ```
    fn to_debug(&self) -> String { self.to_debug_string() }
}

impl<T : Debug> DebugDisplay for T {
    fn to_debug_string(&self) -> String {
        format!("{:#?}", self)
    }
}

<|endoftext|>


<commit_before>//! High level buffer management.

use libc::{size_t, c_void};
use std::mem;
use std::ptr;
use std::vec::Vec;
use std::num::zero;

use CL::*;
use CL::ll::*;

use hl::KernelArg;
use error::check;

pub trait Buffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem;

    fn id(&self) -> cl_mem {
        unsafe {
            *self.id_ptr()
        }
    }

    fn byte_len(&self) -> size_t
    {
        unsafe {
            let mut size : size_t = 0;
            let err = clGetMemObjectInfo(self.id(),
                                         CL_MEM_SIZE,
                                         mem::size_of::<size_t>() as size_t,
                                         (&mut size as *mut u64) as *mut c_void,
                                         ptr::mut_null());

            check(err, "Failed to read memory size");
            size
        }
    }

    fn len(&self) -> uint { self.byte_len() as uint / mem::size_of::<T>() }
}

pub struct CLBuffer<T> {
    pub cl_buffer: cl_mem
}

#[unsafe_destructor]
impl<T> Drop for CLBuffer<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.cl_buffer);
        }
    }
}

impl<T> Buffer<T> for CLBuffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem
    {
        &self.cl_buffer as *const cl_mem
    }
}

impl<T> KernelArg for CLBuffer<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        unsafe {
            (mem::size_of::<cl_mem>() as size_t,
             self.id_ptr() as *const c_void)
        }
    }
}

/* memory life cycle
 * | Trait  | Exists in rust | Exists in OpenCL | Direction      |
 * | Put    | X              |                  | rust -> opencl |
 * | Get    |                | X                | opencl -> rust |
 * | Write  | X              | X                | rust -> opencl |
 * | Read   | X              | X                | opencl -> rust |
 *mut */

pub trait Put<T, B> {
    fn put(&self, |ptr: *const c_void, size: size_t| -> cl_mem) -> B;
}

pub trait Get<B, T> {
    fn get(mem: &B, |offset: size_t, ptr: *mut c_void, size: size_t|) -> Self;
}

pub trait Write {
    fn write(&self, |offset: size_t, ptr: *const c_void, size: size_t|);
}

pub trait Read {
    fn read(&mut self, |offset: size_t, ptr: *mut c_void, size: size_t|);
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r [T]
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r Vec<T>
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<T> Put<T, CLBuffer<T>> for Vec<T>
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<T> Get<CLBuffer<T>, T> for Vec<T>
{
    fn get(mem: &CLBuffer<T>, f: |offset: size_t, ptr: *mut c_void, size: size_t|) -> Vec<T>
    {
        let mut v: Vec<T> = Vec::with_capacity(mem.len());
        unsafe {
            v.set_len(mem.len());
        }
        f(0, v.as_ptr() as *mut c_void, (v.len() * mem::size_of::<T>()) as size_t);
        v
    }
}

impl<'r, T> Write for &'r [T]
{
    fn write(&self, f: |offset: size_t, ptr: *const c_void, size: size_t|)
    {
        f(0, self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
    }
}

impl<'r, T> Read for &'r mut [T]
{
    fn read(&mut self, f: |offset: size_t, ptr: *mut c_void, size: size_t|)
    {
        let p = (*self).as_mut_ptr();
        let len = self.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

macro_rules! get_arg (
    ($t:ty) => (impl Get<CLBuffer<$t>, $t> for $t
        {
            fn get(_: &CLBuffer<$t>, f: |offset: size_t, ptr: *mut c_void, size: size_t|) -> $t {
                let mut v: $t = zero();
                f(0, (&mut v as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t);
                v as $t
            }
        })
)

get_arg!(int)
get_arg!(uint)
get_arg!(u32)
get_arg!(u64)
get_arg!(i32)
get_arg!(i64)
get_arg!(f32)
get_arg!(f64)

macro_rules! put_arg (
    ($t:ty) => (impl Put<$t, CLBuffer<$t>> for $t
        {
            fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<$t> {
                CLBuffer {
                    cl_buffer: f((self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t)
                }
            }
        })
)

put_arg!(int)
put_arg!(uint)
put_arg!(u32)
put_arg!(u64)
put_arg!(i32)
put_arg!(i64)
put_arg!(f32)
put_arg!(f64)

macro_rules! read_arg (
    ($t:ty) => (
        impl<'a> Read for $t
        {
            fn read(&mut self, f: |offset: size_t, ptr: *mut c_void, size: size_t|) {
                f(0, (self as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t)
            }
        }
    )
)

read_arg!(int)
read_arg!(uint)
read_arg!(u32)
read_arg!(u64)
read_arg!(i32)
read_arg!(i64)
read_arg!(f32)
read_arg!(f64)

macro_rules! write_arg (
    ($t:ty) => (impl Write for $t
        {
            fn write(&self, f: |offset: size_t, ptr: *const c_void, size: size_t|) {
                f(0, (self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t)
            }
        })
)

write_arg!(int)
write_arg!(uint)
write_arg!(u32)
write_arg!(u64)
write_arg!(i32)
write_arg!(i64)
write_arg!(f32)
write_arg!(f64)
<commit_msg>Removed superfluous lifetime<commit_after>//! High level buffer management.

use libc::{size_t, c_void};
use std::mem;
use std::ptr;
use std::vec::Vec;
use std::num::zero;

use CL::*;
use CL::ll::*;

use hl::KernelArg;
use error::check;

pub trait Buffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem;

    fn id(&self) -> cl_mem {
        unsafe {
            *self.id_ptr()
        }
    }

    fn byte_len(&self) -> size_t
    {
        unsafe {
            let mut size : size_t = 0;
            let err = clGetMemObjectInfo(self.id(),
                                         CL_MEM_SIZE,
                                         mem::size_of::<size_t>() as size_t,
                                         (&mut size as *mut u64) as *mut c_void,
                                         ptr::mut_null());

            check(err, "Failed to read memory size");
            size
        }
    }

    fn len(&self) -> uint { self.byte_len() as uint / mem::size_of::<T>() }
}

pub struct CLBuffer<T> {
    pub cl_buffer: cl_mem
}

#[unsafe_destructor]
impl<T> Drop for CLBuffer<T> {
    fn drop(&mut self) {
        unsafe {
            clReleaseMemObject(self.cl_buffer);
        }
    }
}

impl<T> Buffer<T> for CLBuffer<T> {
    unsafe fn id_ptr(&self) -> *const cl_mem
    {
        &self.cl_buffer as *const cl_mem
    }
}

impl<T> KernelArg for CLBuffer<T> {
    fn get_value(&self) -> (size_t, *const c_void)
    {
        unsafe {
            (mem::size_of::<cl_mem>() as size_t,
             self.id_ptr() as *const c_void)
        }
    }
}

/* memory life cycle
 * | Trait  | Exists in rust | Exists in OpenCL | Direction      |
 * | Put    | X              |                  | rust -> opencl |
 * | Get    |                | X                | opencl -> rust |
 * | Write  | X              | X                | rust -> opencl |
 * | Read   | X              | X                | opencl -> rust |
 *mut */

pub trait Put<T, B> {
    fn put(&self, |ptr: *const c_void, size: size_t| -> cl_mem) -> B;
}

pub trait Get<B, T> {
    fn get(mem: &B, |offset: size_t, ptr: *mut c_void, size: size_t|) -> Self;
}

pub trait Write {
    fn write(&self, |offset: size_t, ptr: *const c_void, size: size_t|);
}

pub trait Read {
    fn read(&mut self, |offset: size_t, ptr: *mut c_void, size: size_t|);
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r [T]
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<'r, T> Put<T, CLBuffer<T>> for &'r Vec<T>
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<T> Put<T, CLBuffer<T>> for Vec<T>
{
    fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<T>
    {
        CLBuffer {
            cl_buffer: f(self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
        }
    }
}

impl<T> Get<CLBuffer<T>, T> for Vec<T>
{
    fn get(mem: &CLBuffer<T>, f: |offset: size_t, ptr: *mut c_void, size: size_t|) -> Vec<T>
    {
        let mut v: Vec<T> = Vec::with_capacity(mem.len());
        unsafe {
            v.set_len(mem.len());
        }
        f(0, v.as_ptr() as *mut c_void, (v.len() * mem::size_of::<T>()) as size_t);
        v
    }
}

impl<'r, T> Write for &'r [T]
{
    fn write(&self, f: |offset: size_t, ptr: *const c_void, size: size_t|)
    {
        f(0, self.as_ptr() as *const c_void, (self.len() * mem::size_of::<T>()) as size_t)
    }
}

impl<'r, T> Read for &'r mut [T]
{
    fn read(&mut self, f: |offset: size_t, ptr: *mut c_void, size: size_t|)
    {
        let p = (*self).as_mut_ptr();
        let len = self.len();
        f(0, p as *mut c_void, (len * mem::size_of::<T>()) as size_t)
    }
}

macro_rules! get_arg (
    ($t:ty) => (impl Get<CLBuffer<$t>, $t> for $t
        {
            fn get(_: &CLBuffer<$t>, f: |offset: size_t, ptr: *mut c_void, size: size_t|) -> $t {
                let mut v: $t = zero();
                f(0, (&mut v as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t);
                v as $t
            }
        })
)

get_arg!(int)
get_arg!(uint)
get_arg!(u32)
get_arg!(u64)
get_arg!(i32)
get_arg!(i64)
get_arg!(f32)
get_arg!(f64)

macro_rules! put_arg (
    ($t:ty) => (impl Put<$t, CLBuffer<$t>> for $t
        {
            fn put(&self, f: |ptr: *const c_void, size: size_t| -> cl_mem) -> CLBuffer<$t> {
                CLBuffer {
                    cl_buffer: f((self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t)
                }
            }
        })
)

put_arg!(int)
put_arg!(uint)
put_arg!(u32)
put_arg!(u64)
put_arg!(i32)
put_arg!(i64)
put_arg!(f32)
put_arg!(f64)

macro_rules! read_arg (
    ($t:ty) => (impl Read for $t
        {
            fn read(&mut self, f: |offset: size_t, ptr: *mut c_void, size: size_t|) {
                f(0, (self as *mut $t) as *mut c_void, mem::size_of::<$t>() as size_t)
            }
        }
    )
)

read_arg!(int)
read_arg!(uint)
read_arg!(u32)
read_arg!(u64)
read_arg!(i32)
read_arg!(i64)
read_arg!(f32)
read_arg!(f64)

macro_rules! write_arg (
    ($t:ty) => (impl Write for $t
        {
            fn write(&self, f: |offset: size_t, ptr: *const c_void, size: size_t|) {
                f(0, (self as *const $t) as *const c_void, mem::size_of::<$t>() as size_t)
            }
        })
)

write_arg!(int)
write_arg!(uint)
write_arg!(u32)
write_arg!(u64)
write_arg!(i32)
write_arg!(i64)
write_arg!(f32)
write_arg!(f64)
<|endoftext|>