<commit_before>use super::{c32, c64};
use super::aligned_vec::AlignedVec;
use super::enums::*;
use super::util::FFTW_MUTEX;
use ffi;

use std::marker::PhantomData;
use std::os::raw::c_void;
use std::ptr::null;

pub struct Plan<A, B> {
    plan: RawPlan,
    phantom: PhantomData<(A, B)>,
}

impl<A, B> Plan<A, B> {
    /// this function modifys the array referred in plan creation
    pub unsafe fn execute(&self) {
        self.plan.execute()
    }
}

impl<T: R2RPlanCreate> Plan<T, T> {
    pub fn r2r_1d(
        n: usize,
        mut in_: &mut AlignedVec<T>,
        mut out: &mut AlignedVec<T>,
        kind: R2R_KIND,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::r2r_1d(n, &mut in_, &mut out, kind, flag) },
            phantom: PhantomData,
        }
    }
    pub fn r2r_2d(
        n0: usize,
        n1: usize,
        mut in_: &mut AlignedVec<T>,
        mut out: &mut AlignedVec<T>,
        k0: R2R_KIND,
        k1: R2R_KIND,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::r2r_2d(n0, n1, &mut in_, &mut out, k0, k1, flag) },
            phantom: PhantomData,
        }
    }
    pub fn r2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        mut in_: &mut AlignedVec<T>,
        mut out: &mut AlignedVec<T>,
        k0: R2R_KIND,
        k1: R2R_KIND,
        k2: R2R_KIND,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::r2r_3d(n0, n1, n2, &mut in_, &mut out, k0, k1, k2, flag) },
            phantom: PhantomData,
        }
    }
}

impl<T: C2CPlanCreate> Plan<T, T> {
    pub fn c2c_1d(n: usize, mut in_: &mut AlignedVec<T>, mut out: &mut AlignedVec<T>, sign: SIGN, flag: FLAG) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::c2c_1d(n, &mut in_, &mut out, sign, flag) },
            phantom: PhantomData,
        }
    }
    pub fn c2c_2d(
        n0: usize,
        n1: usize,
        mut in_: &mut AlignedVec<T>,
        mut out: &mut AlignedVec<T>,
        sign: SIGN,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::c2c_2d(n0, n1, &mut in_, &mut out, sign, flag) },
            phantom: PhantomData,
        }
    }
    pub fn c2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        mut in_: &mut AlignedVec<T>,
        mut out: &mut AlignedVec<T>,
        sign: SIGN,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { T::c2c_3d(n0, n1, n2, &mut in_, &mut out, sign, flag) },
            phantom: PhantomData,
        }
    }
}

impl<C, R> Plan<C, R>
where
    (C, R): C2RPlanCreate<Real = R, Complex = C>,
{
    pub fn c2r_1d(n: usize, in_: &mut AlignedVec<C>, out: &mut AlignedVec<R>, flag: FLAG) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::c2r_1d(n, in_, out, flag) },
            phantom: PhantomData,
        }
    }
    pub fn c2r_2d(n0: usize, n1: usize, in_: &mut AlignedVec<C>, out: &mut AlignedVec<R>, flag: FLAG) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::c2r_2d(n0, n1, in_, out, flag) },
            phantom: PhantomData,
        }
    }
    pub fn c2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<C>,
        out: &mut AlignedVec<R>,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::c2r_3d(n0, n1, n2, in_, out, flag) },
            phantom: PhantomData,
        }
    }
}

impl<R, C> Plan<R, C>
where
    (C, R): C2RPlanCreate<Real = R, Complex = C>,
{
    pub fn r2c_1d(n: usize, in_: &mut AlignedVec<R>, out: &mut AlignedVec<C>, flag: FLAG) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::r2c_1d(n, in_, out, flag) },
            phantom: PhantomData,
        }
    }
    pub fn r2c_2d(n0: usize, n1: usize, in_: &mut AlignedVec<R>, out: &mut AlignedVec<C>, flag: FLAG) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::r2c_2d(n0, n1, in_, out, flag) },
            phantom: PhantomData,
        }
    }
    pub fn r2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<R>,
        out: &mut AlignedVec<C>,
        flag: FLAG,
    ) -> Self {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        Plan {
            plan: unsafe { <(C, R)>::r2c_3d(n0, n1, n2, in_, out, flag) },
            phantom: PhantomData,
        }
    }
}

pub enum RawPlan {
    _64(ffi::fftw_plan),
    _32(ffi::fftwf_plan),
}

impl RawPlan {
    pub unsafe fn execute(&self) {
        self.null_check();
        match *self {
            RawPlan::_64(p) => ffi::fftw_execute(p),
            RawPlan::_32(p) => ffi::fftwf_execute(p),
        }
    }

    fn null_check(&self) {
        let p = match *self {
            RawPlan::_64(p) => p as *const c_void,
            RawPlan::_32(p) => p as *const c_void,
        };
        if p == null() {
            panic!(
                "Plan is NULL. If you use MKL binding, check here: https://software.intel.com/en-us/mkl-developer-reference-c-using-fftw3-wrappers"
            );
        }
    }
}

impl Drop for RawPlan {
    fn drop(&mut self) {
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        unsafe {
            match *self {
                RawPlan::_64(p) => ffi::fftw_destroy_plan(p),
                RawPlan::_32(p) => ffi::fftwf_destroy_plan(p),
            }
        }
    }
}

pub trait R2RPlanCreate: Sized {
    unsafe fn r2r_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, R2R_KIND, FLAG) -> RawPlan;
    unsafe fn r2r_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        R2R_KIND,
        R2R_KIND,
        FLAG,
    ) -> RawPlan;
    unsafe fn r2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        R2R_KIND,
        R2R_KIND,
        R2R_KIND,
        FLAG,
    ) -> RawPlan;
}
pub trait C2CPlanCreate: Sized {
    unsafe fn c2c_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, SIGN, FLAG) -> RawPlan;
    unsafe fn c2c_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        SIGN,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        SIGN,
        FLAG,
    ) -> RawPlan;
}

pub trait C2RPlanCreate {
    type Real: Sized;
    type Complex: Sized;
    unsafe fn r2c_1d(n: usize, in_: &mut AlignedVec<Self::Real>, out: &mut AlignedVec<Self::Complex>, FLAG) -> RawPlan;
    unsafe fn c2r_1d(n: usize, in_: &mut AlignedVec<Self::Complex>, out: &mut AlignedVec<Self::Real>, FLAG) -> RawPlan;
    unsafe fn r2c_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self::Real>,
        out: &mut AlignedVec<Self::Complex>,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2r_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self::Complex>,
        out: &mut AlignedVec<Self::Real>,
        FLAG,
    ) -> RawPlan;
    unsafe fn r2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self::Real>,
        out: &mut AlignedVec<Self::Complex>,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self::Complex>,
        out: &mut AlignedVec<Self::Real>,
        FLAG,
    ) -> RawPlan;
}

macro_rules! impl_plan_create {
    ($bit:ident, $float:ty, $complex:ty,
     $r2r_1d:ident, $r2c_1d:ident, $c2r_1d:ident, $c2c_1d:ident,
     $r2r_2d:ident, $r2c_2d:ident, $c2r_2d:ident, $c2c_2d:ident,
     $r2r_3d:ident, $r2c_3d:ident, $c2r_3d:ident, $c2c_3d:ident) => {

impl R2RPlanCreate for $float {
    unsafe fn r2r_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, kind: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_1d(n as i32, in_.as_mut_ptr(), out.as_mut_ptr(), kind, flag as u32))
    }
    unsafe fn r2r_2d(n0: usize, n1: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, k0: R2R_KIND, k1: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_2d(n0 as i32, n1 as i32, in_.as_mut_ptr(), out.as_mut_ptr(), k0, k1, flag as u32))
    }
    unsafe fn r2r_3d(n0: usize, n1: usize, n2: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, k0: R2R_KIND, k1: R2R_KIND, k2: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_3d(n0 as i32, n1 as i32, n2 as i32, in_.as_mut_ptr(), out.as_mut_ptr(), k0, k1, k2, flag as u32))
    }
}

impl C2CPlanCreate for $complex {
    unsafe fn c2c_1d(n: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
    unsafe fn c2c_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
    unsafe fn c2c_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
}

impl C2RPlanCreate for ($complex, $float) {
    type Real = $float;
    type Complex = $complex;
    unsafe fn r2c_1d(n: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_1d(n: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn r2c_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn r2c_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
}

}} // impl_plan_create

impl_plan_create!(
    _64,
    f64,
    c64,
    fftw_plan_r2r_1d,
    fftw_plan_dft_r2c_1d,
    fftw_plan_dft_c2r_1d,
    fftw_plan_dft_1d,
    fftw_plan_r2r_2d,
    fftw_plan_dft_r2c_2d,
    fftw_plan_dft_c2r_2d,
    fftw_plan_dft_2d,
    fftw_plan_r2r_3d,
    fftw_plan_dft_r2c_3d,
    fftw_plan_dft_c2r_3d,
    fftw_plan_dft_3d
);
impl_plan_create!(
    _32,
    f32,
    c32,
    fftwf_plan_r2r_1d,
    fftwf_plan_dft_r2c_1d,
    fftwf_plan_dft_c2r_1d,
    fftwf_plan_dft_1d,
    fftwf_plan_r2r_2d,
    fftwf_plan_dft_r2c_2d,
    fftwf_plan_dft_c2r_2d,
    fftwf_plan_dft_2d,
    fftwf_plan_r2r_3d,
    fftwf_plan_dft_r2c_3d,
    fftwf_plan_dft_c2r_3d,
    fftwf_plan_dft_3d
);
<commit_msg>Drop plan::Plan struct<commit_after>use super::{c32, c64};
use super::aligned_vec::AlignedVec;
use super::enums::*;
use super::util::FFTW_MUTEX;
use ffi;

use std::os::raw::c_void;
use std::ptr::null;

pub enum RawPlan {
    _64(ffi::fftw_plan),
    _32(ffi::fftwf_plan),
}

impl RawPlan {
    pub unsafe fn execute(&self) {
        self.null_check();
        match *self {
            RawPlan::_64(p) => ffi::fftw_execute(p),
            RawPlan::_32(p) => ffi::fftwf_execute(p),
        }
    }

    fn null_check(&self) {
        let p = match *self {
            RawPlan::_64(p) => p as *const c_void,
            RawPlan::_32(p) => p as *const c_void,
        };
        if p == null() {
            panic!(
                "Plan is NULL. If you use MKL binding, check here: https://software.intel.com/en-us/mkl-developer-reference-c-using-fftw3-wrappers"
            );
        }
    }
}

impl Drop for RawPlan {
    fn drop(&mut self) {
        self.null_check();
        let _lock = FFTW_MUTEX.lock().expect("Cannot get lock");
        unsafe {
            match *self {
                RawPlan::_64(p) => ffi::fftw_destroy_plan(p),
                RawPlan::_32(p) => ffi::fftwf_destroy_plan(p),
            }
        }
    }
}

pub trait R2R: Sized {
    unsafe fn r2r_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, R2R_KIND, FLAG) -> RawPlan;
    unsafe fn r2r_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        R2R_KIND,
        R2R_KIND,
        FLAG,
    ) -> RawPlan;
    unsafe fn r2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        R2R_KIND,
        R2R_KIND,
        R2R_KIND,
        FLAG,
    ) -> RawPlan;
}
pub trait C2C: Sized {
    unsafe fn c2c_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, SIGN, FLAG) -> RawPlan;
    unsafe fn c2c_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        SIGN,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self>,
        out: &mut AlignedVec<Self>,
        SIGN,
        FLAG,
    ) -> RawPlan;
}

pub trait C2R {
    type Real: Sized;
    type Complex: Sized;
    unsafe fn r2c_1d(n: usize, in_: &mut AlignedVec<Self::Real>, out: &mut AlignedVec<Self::Complex>, FLAG) -> RawPlan;
    unsafe fn c2r_1d(n: usize, in_: &mut AlignedVec<Self::Complex>, out: &mut AlignedVec<Self::Real>, FLAG) -> RawPlan;
    unsafe fn r2c_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self::Real>,
        out: &mut AlignedVec<Self::Complex>,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2r_2d(
        n0: usize,
        n1: usize,
        in_: &mut AlignedVec<Self::Complex>,
        out: &mut AlignedVec<Self::Real>,
        FLAG,
    ) -> RawPlan;
    unsafe fn r2c_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self::Real>,
        out: &mut AlignedVec<Self::Complex>,
        FLAG,
    ) -> RawPlan;
    unsafe fn c2r_3d(
        n0: usize,
        n1: usize,
        n2: usize,
        in_: &mut AlignedVec<Self::Complex>,
        out: &mut AlignedVec<Self::Real>,
        FLAG,
    ) -> RawPlan;
}

macro_rules! impl_plan_create {
    ($bit:ident, $float:ty, $complex:ty,
     $r2r_1d:ident, $r2c_1d:ident, $c2r_1d:ident, $c2c_1d:ident,
     $r2r_2d:ident, $r2c_2d:ident, $c2r_2d:ident, $c2c_2d:ident,
     $r2r_3d:ident, $r2c_3d:ident, $c2r_3d:ident, $c2c_3d:ident) => {

impl R2R for $float {
    unsafe fn r2r_1d(n: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, kind: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_1d(n as i32, in_.as_mut_ptr(), out.as_mut_ptr(), kind, flag as u32))
    }
    unsafe fn r2r_2d(n0: usize, n1: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, k0: R2R_KIND, k1: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_2d(n0 as i32, n1 as i32, in_.as_mut_ptr(), out.as_mut_ptr(), k0, k1, flag as u32))
    }
    unsafe fn r2r_3d(n0: usize, n1: usize, n2: usize, in_: &mut AlignedVec<Self>, out: &mut AlignedVec<Self>, k0: R2R_KIND, k1: R2R_KIND, k2: R2R_KIND, flag: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2r_3d(n0 as i32, n1 as i32, n2 as i32, in_.as_mut_ptr(), out.as_mut_ptr(), k0, k1, k2, flag as u32))
    }
}

impl C2C for $complex {
    unsafe fn c2c_1d(n: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
    unsafe fn c2c_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
    unsafe fn c2c_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self>, o: &mut AlignedVec<Self>, s: SIGN, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2c_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), s as i32, f as u32))
    }
}

impl C2R for ($complex, $float) {
    type Real = $float;
    type Complex = $complex;
    unsafe fn r2c_1d(n: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_1d(n: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_1d(n as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn r2c_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_2d(n0: usize, n1: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_2d(n0 as i32, n1 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn r2c_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self::Real>, o: &mut AlignedVec<Self::Complex>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$r2c_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
    unsafe fn c2r_3d(n0: usize, n1: usize, n2: usize, i: &mut AlignedVec<Self::Complex>, o: &mut AlignedVec<Self::Real>, f: FLAG) -> RawPlan {
        RawPlan::$bit(ffi::$c2r_3d(n0 as i32, n1 as i32, n2 as i32, i.as_mut_ptr(), o.as_mut_ptr(), f as u32))
    }
}

}} // impl_plan_create

impl_plan_create!(
    _64,
    f64,
    c64,
    fftw_plan_r2r_1d,
    fftw_plan_dft_r2c_1d,
    fftw_plan_dft_c2r_1d,
    fftw_plan_dft_1d,
    fftw_plan_r2r_2d,
    fftw_plan_dft_r2c_2d,
    fftw_plan_dft_c2r_2d,
    fftw_plan_dft_2d,
    fftw_plan_r2r_3d,
    fftw_plan_dft_r2c_3d,
    fftw_plan_dft_c2r_3d,
    fftw_plan_dft_3d
);
impl_plan_create!(
    _32,
    f32,
    c32,
    fftwf_plan_r2r_1d,
    fftwf_plan_dft_r2c_1d,
    fftwf_plan_dft_c2r_1d,
    fftwf_plan_dft_1d,
    fftwf_plan_r2r_2d,
    fftwf_plan_dft_r2c_2d,
    fftwf_plan_dft_c2r_2d,
    fftwf_plan_dft_2d,
    fftwf_plan_r2r_3d,
    fftwf_plan_dft_r2c_3d,
    fftwf_plan_dft_c2r_3d,
    fftwf_plan_dft_3d
);
<|endoftext|>


<commit_before>
use ffi;
use super::r2r::*;
use super::{c64, FLAG, SIGN};

#[derive(Debug)]
pub struct Plan<'a, 'b, A, B>
    where A: 'a,
          B: 'b
{
    pub field: &'a mut [A],
    pub coef: &'b mut [B],
    logical_size: usize,
    forward: ffi::fftw_plan,
    backward: ffi::fftw_plan,
}

impl<'a, 'b, A, B> Plan<'a, 'b, A, B> {
    /// [field] -> [coef]
    pub fn forward(&self) {
        unsafe {
            ffi::fftw_execute(self.forward);
        }
    }
    /// [field] <- [coef]
    pub fn backward(&self) {
        unsafe {
            ffi::fftw_execute(self.backward);
        }
    }
}

impl<'a, 'b, A, B> Drop for Plan<'a, 'b, A, B> {
    fn drop(&mut self) {
        unsafe {
            ffi::fftw_destroy_plan(self.forward);
            ffi::fftw_destroy_plan(self.backward);
        }
    }
}

impl<'a, 'b> Plan<'a, 'b, f64, f64> {
    pub fn r2r_1d(field: &'a mut [f64], coef: &'b mut [f64], kind: R2R_KIND, flag: FLAG) -> Self {
        let n = field.len();
        let forward = unsafe {
            ffi::fftw_plan_r2r_1d(n as i32,
                                  field.as_mut_ptr(),
                                  coef.as_mut_ptr(),
                                  forward(kind),
                                  flag as u32)
        };
        let backward = unsafe {
            ffi::fftw_plan_r2r_1d(n as i32,
                                  coef.as_mut_ptr(),
                                  field.as_mut_ptr(),
                                  backward(kind),
                                  flag as u32)
        };
        Plan {
            field: field,
            coef: coef,
            logical_size: logical_size(n, kind),
            forward: forward,
            backward: backward,
        }
    }
}

impl<'a, 'b> Plan<'a, 'b, c64, c64> {
    pub fn dft_1d(field: &'a mut [c64], coef: &'b mut [c64], sign: SIGN, flag: FLAG) -> Self {
        let n = field.len();
        let forward = unsafe {
            ffi::fftw_plan_dft_1d(n as i32,
                                  field.as_mut_ptr() as *mut ffi::fftw_complex,
                                  coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                  sign as i32,
                                  flag as u32)
        };
        let backward = unsafe {
            ffi::fftw_plan_dft_1d(n as i32,
                                  coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                  field.as_mut_ptr() as *mut ffi::fftw_complex,
                                  -(sign as i32),
                                  flag as u32)
        };
        Plan {
            field: field,
            coef: coef,
            logical_size: n,
            forward: forward,
            backward: backward,
        }

    }
}
<commit_msg>Add plan for r2c/c2r transform<commit_after>
use ffi;
use super::r2r::*;
use super::{c64, FLAG, SIGN};

#[derive(Debug)]
pub struct Plan<'a, 'b, A, B>
    where A: 'a,
          B: 'b
{
    pub field: &'a mut [A],
    pub coef: &'b mut [B],
    logical_size: usize,
    forward: ffi::fftw_plan,
    backward: ffi::fftw_plan,
}

impl<'a, 'b, A, B> Plan<'a, 'b, A, B> {
    /// [field] -> [coef]
    pub fn forward(&self) {
        unsafe {
            ffi::fftw_execute(self.forward);
        }
    }
    /// [field] <- [coef]
    pub fn backward(&self) {
        unsafe {
            ffi::fftw_execute(self.backward);
        }
    }
}

impl<'a, 'b, A, B> Drop for Plan<'a, 'b, A, B> {
    fn drop(&mut self) {
        unsafe {
            ffi::fftw_destroy_plan(self.forward);
            ffi::fftw_destroy_plan(self.backward);
        }
    }
}

impl<'a, 'b> Plan<'a, 'b, f64, f64> {
    pub fn r2r_1d(field: &'a mut [f64], coef: &'b mut [f64], kind: R2R_KIND, flag: FLAG) -> Self {
        let n = field.len();
        let forward = unsafe {
            ffi::fftw_plan_r2r_1d(n as i32,
                                  field.as_mut_ptr(),
                                  coef.as_mut_ptr(),
                                  forward(kind),
                                  flag as u32)
        };
        let backward = unsafe {
            ffi::fftw_plan_r2r_1d(n as i32,
                                  coef.as_mut_ptr(),
                                  field.as_mut_ptr(),
                                  backward(kind),
                                  flag as u32)
        };
        Plan {
            field: field,
            coef: coef,
            logical_size: logical_size(n, kind),
            forward: forward,
            backward: backward,
        }
    }
}

impl<'a, 'b> Plan<'a, 'b, c64, c64> {
    pub fn dft_1d(field: &'a mut [c64], coef: &'b mut [c64], sign: SIGN, flag: FLAG) -> Self {
        let n = field.len();
        let forward = unsafe {
            ffi::fftw_plan_dft_1d(n as i32,
                                  field.as_mut_ptr() as *mut ffi::fftw_complex,
                                  coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                  sign as i32,
                                  flag as u32)
        };
        let backward = unsafe {
            ffi::fftw_plan_dft_1d(n as i32,
                                  coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                  field.as_mut_ptr() as *mut ffi::fftw_complex,
                                  -(sign as i32),
                                  flag as u32)
        };
        Plan {
            field: field,
            coef: coef,
            logical_size: n,
            forward: forward,
            backward: backward,
        }

    }
}

impl<'a, 'b> Plan<'a, 'b, f64, c64> {
    pub fn r2c_1d(field: &'a mut [f64], coef: &'b mut [c64], flag: FLAG) -> Self {
        let n = field.len();
        let forward = unsafe {
            ffi::fftw_plan_dft_r2c_1d(n as i32,
                                      field.as_mut_ptr(),
                                      coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                      flag as u32)
        };
        let backward = unsafe {
            ffi::fftw_plan_dft_c2r_1d(n as i32,
                                      coef.as_mut_ptr() as *mut ffi::fftw_complex,
                                      field.as_mut_ptr(),
                                      flag as u32)
        };
        Plan {
            field: field,
            coef: coef,
            logical_size: n,
            forward: forward,
            backward: backward,
        }

    }
}
<|endoftext|>


<commit_before>use af;
use af::Array;
use na::{DMat, DVec};

use utils;
//use error::HALError;

pub fn plot_array(values: &Array, title: &'static str, window_x: u16, window_y: u16) {
  assert!(values.dims().unwrap()[1] == 1);

  // create a window
  //let title_str = String::from(title).clone(); // if we don't clone we get a bug
  let title_str = String::from("Plot").clone(); //above is causing issues on 3.0.2
  let wnd = match af::Window::new(window_x as i32, window_y as i32, title_str) {
    Ok(v)  => v,
    Err(e) => panic!("Window creation failed: {}", e), //XXX: handle better
  };

  //af::print(&af::min(&values, 0).unwrap());
  //af::print(&af::max(&values, 0).unwrap());

  // display till closed
  loop {
    wnd.draw_plot(&af::range(values.dims().unwrap().clone()
                             , 0, af::Aftype::F32).unwrap(), &values, None);
    if wnd.is_closed().unwrap() == true { break; }
  }
}

pub fn plot_dmat<T>(raw_values: &DMat<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from DMat to Array
  assert!(raw_values.ncols() == 1);
  let values = utils::dmat_to_array(raw_values);
  plot_array(&values, title, window_x, window_y);
}

pub fn plot_dvec<T>(raw_values: &DVec<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from DMat to Array
  let values = utils::dvec_to_array(raw_values);
  plot_array(&values, title, window_x, window_y);
}

pub fn plot_vec<T>(raw_values: Vec<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from float vector to Array
  let num_rows = raw_values.len();
  let values = utils::vec_to_array(raw_values, num_rows, 1);
  plot_array(&values, title, window_x, window_y);
}
<commit_msg>fix plotting title issue by internal clone<commit_after>use af;
use af::Array;
use na::{DMat, DVec};

use utils;
//use error::HALError;

pub fn plot_array(values: &Array, title: &'static str, window_x: u16, window_y: u16) {
  assert!(values.dims().unwrap()[1] == 1);

  // create a window
  let title_str = String::from(title);
  let wnd = match af::Window::new(window_x as i32, window_y as i32, title_str.clone()) {
    Ok(v)  => v,
    Err(e) => panic!("Window creation failed: {}", e), //XXX: handle better
  };

  //af::print(&af::min(&values, 0).unwrap());
  //af::print(&af::max(&values, 0).unwrap());

  // display till closed
  loop {
    wnd.draw_plot(&af::range(values.dims().unwrap().clone()
                             , 0, af::Aftype::F32).unwrap(), &values, None);
    if wnd.is_closed().unwrap() == true { break; }
  }
}

pub fn plot_dmat<T>(raw_values: &DMat<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from DMat to Array
  assert!(raw_values.ncols() == 1);
  let values = utils::dmat_to_array(raw_values);
  plot_array(&values, title, window_x, window_y);
}

pub fn plot_dvec<T>(raw_values: &DVec<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from DMat to Array
  let values = utils::dvec_to_array(raw_values);
  plot_array(&values, title, window_x, window_y);
}

pub fn plot_vec<T>(raw_values: Vec<T>, title: &'static str, window_x: u16, window_y: u16) {
  // copy from float vector to Array
  let num_rows = raw_values.len();
  let values = utils::vec_to_array(raw_values, num_rows, 1);
  plot_array(&values, title, window_x, window_y);
}
<|endoftext|>


<commit_before>use super::{Connection, Message, MessageItem, Error};
use std::collections::BTreeMap;

/// Client side properties - get and set properties on a remote application.
pub struct Props<'a> {
    name: String,
    path: String,
    interface: String,
    timeout_ms: i32,
    conn: &'a Connection,
}

impl<'a> Props<'a> {
    pub fn new(conn: &'a Connection, name: &str, path: &str, interface: &str, timeout_ms: i32) -> Props<'a> {
        Props {
            name: name.to_string(),
            path: path.to_string(),
            interface: interface.to_string(),
            timeout_ms: timeout_ms,
            conn: conn,
        }
    }

    pub fn get(&self, propname: &str) -> Result<MessageItem, Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "Get").unwrap();
        m.append_items(&[
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string())
        ]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            if let &MessageItem::Variant(ref v) = &reply[0] {
                return Ok((**v).clone())
            }
       }
       let f = format!("Invalid reply for property get {}: '{:?}'", propname, reply);
       return Err(Error::new_custom("InvalidReply", &f));
    }

    pub fn set(&self, propname: &str, value: MessageItem) -> Result<(), Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "Set").unwrap();
        m.append_items(&[
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string()),
            MessageItem::Variant(Box::new(value)),
        ]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        try!(r.as_result());
        Ok(())
    }

    pub fn get_all(&self) -> Result<BTreeMap<String, MessageItem>, Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "GetAll").unwrap();
        m.append_items(&[MessageItem::Str(self.interface.clone())]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            if let &MessageItem::Array(ref a, _) = &reply[0] {
                let mut t = BTreeMap::new();
                let mut haserr = false;
                for p in a.iter() {
                    if let &MessageItem::DictEntry(ref k, ref v) = p {
                        if let &MessageItem::Str(ref ks) = &**k {
                            if let &MessageItem::Variant(ref vv) = &**v {
                                t.insert(ks.to_string(), (**vv).clone());
                            } else { haserr = true; };
                        } else { haserr = true; };
                    } else { haserr = true; };
                }
                if !haserr { return Ok(t) };
            }
        }
        let f = format!("Invalid reply for property GetAll: '{:?}'", reply);
        return Err(Error::new_custom("InvalidReply", &f));
    }
}

/// Wrapper around Props that keeps a map of fetched properties.
pub struct PropHandler<'a> {
    p: Props<'a>,
    map: BTreeMap<String, MessageItem>,
}

impl<'a> PropHandler<'a> {
    pub fn new(p: Props) -> PropHandler {
        PropHandler { p: p, map: BTreeMap::new() }
    }

    pub fn get_all(&mut self) -> Result<(), Error> {
        self.map = try!(self.p.get_all());
        Ok(())
    }

    pub fn map_mut(&mut self) -> &mut BTreeMap<String, MessageItem> { &mut self.map }
    pub fn map(&self) -> &BTreeMap<String, MessageItem> { &self.map }

    pub fn get(&mut self, propname: &str) -> Result<&MessageItem, Error> {
        let v = try!(self.p.get(propname));
        self.map.insert(propname.to_string(), v);
        Ok(self.map.get(propname).unwrap())
    }

    pub fn set(&mut self, propname: &str, value: MessageItem) -> Result<(), Error> {
        try!(self.p.set(propname, value.clone()));
        self.map.insert(propname.to_string(), value);
        Ok(())
    }

    fn invalid_args(m: &Message) -> Message {
        Message::new_error(m, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid arguments").unwrap()
    }

    #[deprecated(reason = "use objpath instead")]
    fn handle_get(&self, msg: &mut Message) -> Message {
        let items = msg.get_items();
        let name = if let Some(s) = items.get(1) { s } else { return PropHandler::invalid_args(msg) };
        let name = if let &MessageItem::Str(ref s) = name { s } else { return PropHandler::invalid_args(msg) };
        let value = if let Some(s) = self.map.get(name) { s } else { return PropHandler::invalid_args(msg) };

        let mut reply = Message::new_method_return(msg).unwrap();
        reply.append_items(&[MessageItem::Variant(Box::new(value.clone()))]);
        reply
    }

    #[deprecated(reason = "Broken. Use objpath instead")]
    fn handle_getall(&self, msg: &mut Message) -> Message {
        let mut reply = Message::new_method_return(msg).unwrap();
        for (k, v) in self.map.iter() {
            reply.append_items(&[MessageItem::DictEntry(Box::new(MessageItem::Str(k.clone())), Box::new(v.clone()))]);
        }
        reply
    }

    /* Return value:
       None => not handled,
       Some(Err(())) => message reply send failed,
       Some(Ok()) => message reply send ok */
    pub fn handle_message(&mut self, msg: &mut Message) -> Option<Result<(), ()>> {
        let (_, path, iface, method) = msg.headers();
        if iface.is_none() || &*iface.unwrap() != "org.freedesktop.DBus.Properties" { return None; }
        if path.is_none() || path.unwrap() != self.p.path { return None; }
        if method.is_none() { return None; }

        let items = msg.get_items();
        if let Some(i) = items.get(0) {
            if let &MessageItem::Str(ref s) = i {
                if *s != self.p.interface { return None; }
            } else { return None; } // Hmm, invalid message
        } else { return None }; // Hmm, invalid message

        // Ok, we have a match
        let reply = match &*method.unwrap() {
            "Get" => self.handle_get(msg),
//            "Set" => self.handle_set(msg),
            "GetAll" => self.handle_getall(msg),
            _ => PropHandler::invalid_args(msg)
        };
        Some(self.p.conn.send(reply).map(|_| ()))
    }
}

/* Unfortunately org.freedesktop.DBus has no properties we can use for testing, but PolicyKit should be around on most distros. */
#[test]
fn test_get_policykit_version() {
    use super::BusType;
    let c = Connection::get_private(BusType::System).unwrap();
    let p = Props::new(&c, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority",
        "org.freedesktop.PolicyKit1.Authority", 10000);

    /* Let's use both the get and getall methods and see if we get the same result */
    let v = p.get("BackendVersion").unwrap();
    let vall = p.get_all().unwrap();
    let v2 = vall.get("BackendVersion").unwrap();

    assert_eq!(&v, &*v2);
    match v {
        MessageItem::Str(ref s) => { println!("Policykit Backend version is {}", s); }
        _ => { panic!("Invalid Get: {:?}", v); }
    };
}

<commit_msg>#[deprecated] is now blocked outside stdlib<commit_after>use super::{Connection, Message, MessageItem, Error};
use std::collections::BTreeMap;

/// Client side properties - get and set properties on a remote application.
pub struct Props<'a> {
    name: String,
    path: String,
    interface: String,
    timeout_ms: i32,
    conn: &'a Connection,
}

impl<'a> Props<'a> {
    pub fn new(conn: &'a Connection, name: &str, path: &str, interface: &str, timeout_ms: i32) -> Props<'a> {
        Props {
            name: name.to_string(),
            path: path.to_string(),
            interface: interface.to_string(),
            timeout_ms: timeout_ms,
            conn: conn,
        }
    }

    pub fn get(&self, propname: &str) -> Result<MessageItem, Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "Get").unwrap();
        m.append_items(&[
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string())
        ]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            if let &MessageItem::Variant(ref v) = &reply[0] {
                return Ok((**v).clone())
            }
       }
       let f = format!("Invalid reply for property get {}: '{:?}'", propname, reply);
       return Err(Error::new_custom("InvalidReply", &f));
    }

    pub fn set(&self, propname: &str, value: MessageItem) -> Result<(), Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "Set").unwrap();
        m.append_items(&[
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string()),
            MessageItem::Variant(Box::new(value)),
        ]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        try!(r.as_result());
        Ok(())
    }

    pub fn get_all(&self) -> Result<BTreeMap<String, MessageItem>, Error> {
        let mut m = Message::new_method_call(&self.name, &self.path,
            "org.freedesktop.DBus.Properties", "GetAll").unwrap();
        m.append_items(&[MessageItem::Str(self.interface.clone())]);
        let mut r = try!(self.conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            if let &MessageItem::Array(ref a, _) = &reply[0] {
                let mut t = BTreeMap::new();
                let mut haserr = false;
                for p in a.iter() {
                    if let &MessageItem::DictEntry(ref k, ref v) = p {
                        if let &MessageItem::Str(ref ks) = &**k {
                            if let &MessageItem::Variant(ref vv) = &**v {
                                t.insert(ks.to_string(), (**vv).clone());
                            } else { haserr = true; };
                        } else { haserr = true; };
                    } else { haserr = true; };
                }
                if !haserr { return Ok(t) };
            }
        }
        let f = format!("Invalid reply for property GetAll: '{:?}'", reply);
        return Err(Error::new_custom("InvalidReply", &f));
    }
}

/// Wrapper around Props that keeps a map of fetched properties.
pub struct PropHandler<'a> {
    p: Props<'a>,
    map: BTreeMap<String, MessageItem>,
}

impl<'a> PropHandler<'a> {
    pub fn new(p: Props) -> PropHandler {
        PropHandler { p: p, map: BTreeMap::new() }
    }

    pub fn get_all(&mut self) -> Result<(), Error> {
        self.map = try!(self.p.get_all());
        Ok(())
    }

    pub fn map_mut(&mut self) -> &mut BTreeMap<String, MessageItem> { &mut self.map }
    pub fn map(&self) -> &BTreeMap<String, MessageItem> { &self.map }

    pub fn get(&mut self, propname: &str) -> Result<&MessageItem, Error> {
        let v = try!(self.p.get(propname));
        self.map.insert(propname.to_string(), v);
        Ok(self.map.get(propname).unwrap())
    }

    pub fn set(&mut self, propname: &str, value: MessageItem) -> Result<(), Error> {
        try!(self.p.set(propname, value.clone()));
        self.map.insert(propname.to_string(), value);
        Ok(())
    }

    fn invalid_args(m: &Message) -> Message {
        Message::new_error(m, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid arguments").unwrap()
    }

    /// Deprecated: use objpath instead
    fn handle_get(&self, msg: &mut Message) -> Message {
        let items = msg.get_items();
        let name = if let Some(s) = items.get(1) { s } else { return PropHandler::invalid_args(msg) };
        let name = if let &MessageItem::Str(ref s) = name { s } else { return PropHandler::invalid_args(msg) };
        let value = if let Some(s) = self.map.get(name) { s } else { return PropHandler::invalid_args(msg) };

        let mut reply = Message::new_method_return(msg).unwrap();
        reply.append_items(&[MessageItem::Variant(Box::new(value.clone()))]);
        reply
    }

    /// Deprecated: Broken. Use objpath instead
    fn handle_getall(&self, msg: &mut Message) -> Message {
        let mut reply = Message::new_method_return(msg).unwrap();
        for (k, v) in self.map.iter() {
            reply.append_items(&[MessageItem::DictEntry(Box::new(MessageItem::Str(k.clone())), Box::new(v.clone()))]);
        }
        reply
    }

    /* Return value:
       None => not handled,
       Some(Err(())) => message reply send failed,
       Some(Ok()) => message reply send ok */
    pub fn handle_message(&mut self, msg: &mut Message) -> Option<Result<(), ()>> {
        let (_, path, iface, method) = msg.headers();
        if iface.is_none() || &*iface.unwrap() != "org.freedesktop.DBus.Properties" { return None; }
        if path.is_none() || path.unwrap() != self.p.path { return None; }
        if method.is_none() { return None; }

        let items = msg.get_items();
        if let Some(i) = items.get(0) {
            if let &MessageItem::Str(ref s) = i {
                if *s != self.p.interface { return None; }
            } else { return None; } // Hmm, invalid message
        } else { return None }; // Hmm, invalid message

        // Ok, we have a match
        let reply = match &*method.unwrap() {
            "Get" => self.handle_get(msg),
//            "Set" => self.handle_set(msg),
            "GetAll" => self.handle_getall(msg),
            _ => PropHandler::invalid_args(msg)
        };
        Some(self.p.conn.send(reply).map(|_| ()))
    }
}

/* Unfortunately org.freedesktop.DBus has no properties we can use for testing, but PolicyKit should be around on most distros. */
#[test]
fn test_get_policykit_version() {
    use super::BusType;
    let c = Connection::get_private(BusType::System).unwrap();
    let p = Props::new(&c, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority",
        "org.freedesktop.PolicyKit1.Authority", 10000);

    /* Let's use both the get and getall methods and see if we get the same result */
    let v = p.get("BackendVersion").unwrap();
    let vall = p.get_all().unwrap();
    let v2 = vall.get("BackendVersion").unwrap();

    assert_eq!(&v, &*v2);
    match v {
        MessageItem::Str(ref s) => { println!("Policykit Backend version is {}", s); }
        _ => { panic!("Invalid Get: {:?}", v); }
    };
}

<|endoftext|>


<commit_before>use super::base::{BaseRand, RAND_MAX};
use std::f64::consts::PI;

pub enum Style {
    Normal,
    Gauss(u32),
    BMgauss(f64, f64, bool),
    Marsaglia(f64, f64, f64, bool),
}

pub struct Rand {
    base: BaseRand,
    style: Style,
}

impl Rand {
    /// a lazy way to get a random solver
    pub fn new() -> Self {
        Rand {
            base: BaseRand::new(),
            style: Style::Normal,
        }
    }

    pub fn set_style(&mut self, style: Style) {
        self.style = style;
    }

    pub fn srand(&mut self, seed: usize) {
        self.base.srand(seed);
    }

    pub fn lazy_srand(&mut self) {
        self.base.lazy_srand();
    }

    pub fn set_function(&mut self, style: &str) {
        self.base.set_function(style);
    }

    /// get a random number
    pub fn rand(&mut self) -> f64 {
        match self.style {
            Style::Normal => self.base.rand() as f64,
            Style::Gauss(nsum) => gauss(&mut self.base, nsum),
            Style::BMgauss(u, v, phase) => {
                let mut _u = u;
                let mut _v = v;
                let mut _phase = phase;
                let _return = bmgauss(&mut self.base, &mut _u, &mut _v, &mut _phase);
                self.style = Style::BMgauss(_u, _v, _phase);
                _return
            }
            Style::Marsaglia(v1, v2, s, phase) => {
                let mut _v1 = v1;
                let mut _v2 = v2;
                let mut _s = s;
                let mut _phase = phase;
                let _return = marsaglia(&mut self.base, &mut _v1, &mut _v2, &mut _s, &mut _phase);
                self.style = Style::Marsaglia(_v1, _v2, _s, _phase);
                _return
            }
        }
    }
}

fn gauss(base: &mut BaseRand, nsum: u32) -> f64 {
    let mut x = 0.0;
    for _ in 0..nsum {
        x += base.rand() as f64 / RAND_MAX as f64;
    }
    x -= nsum as f64 / 2.0;
    x /= (nsum as f64 / 12.0).sqrt();
    x
}

fn bmgauss(base: &mut BaseRand, u: &mut f64, v: &mut f64, phase: &mut bool) -> f64 {
    if *phase {
        *phase = false;
        *u = (base.rand() + 1) as f64 / (RAND_MAX + 2) as f64;
        *v = base.rand() as f64 / (RAND_MAX + 1) as f64;
        (-2.0 * (*u).log10()).sqrt() * (2.0 * PI * (*v)).sin()
    } else {
        *phase = true;
        (-2.0 * (*u).log10()).sqrt() * (2.0 * PI * (*v)).cos()
    }
}

fn marsaglia(base: &mut BaseRand,
             v1: &mut f64,
             v2: &mut f64,
             s: &mut f64,
             phase: &mut bool)
             -> f64 {
    if *phase {
        *phase = false;
        let u1 = base.rand() as f64 / RAND_MAX as f64;
        let u2 = base.rand() as f64 / RAND_MAX as f64;
        *v1 = 2.0 * u1 - 1.0;
        *v2 = 2.0 * u2 - 1.0;
        *v1 * (-2.0 * (*s).log10() / (*s)).sqrt()
    } else {
        *phase = true;
        *v2 * (-2.0 * (*s).log10() / (*s)).sqrt()
    }
}
<commit_msg>Rebuild<commit_after>use super::base::{BaseRand, RAND_MAX};
use std::f64::consts::PI;

pub enum Style {
    Normal,
    Gauss(u32),
    BMgauss(f64, f64, bool),
    Marsaglia(f64, f64, f64, bool),
}

pub struct Rand {
    base: Vec<BaseRand>,
    handle: Option<usize>,
    style: Style,
}

impl Rand {
    /// a lazy way to get a random solver
    pub fn new() -> Self {
        Rand {
            base: vec![BaseRand::new()],
            handle: Some(0),
            style: Style::Normal,
        }
    }

    pub fn set_style(&mut self, style: Style) {
        self.style = style;
    }

    pub fn srand(&mut self, seed: Vec<usize>) {
        for i in 0..self.base.len() {
            self.base[i].srand(seed[i]);
        }
    }

    pub fn lazy_srand(&mut self) {
        for i in 0..self.base.len() {
            self.base[i].lazy_srand();
        }
    }

    pub fn set_function(&mut self, handle: usize, style: &str) {
        self.base[handle].set_function(style);
    }

    /// get a random number
    pub fn rand(&mut self) -> f64 {
        match self.style {
            Style::Normal => self.base() as f64,
            Style::Gauss(nsum) => gauss(self, nsum),
            Style::BMgauss(u, v, phase) => {
                let mut _u = u;
                let mut _v = v;
                let mut _phase = phase;
                let _return = bmgauss(self, &mut _u, &mut _v, &mut _phase);
                self.style = Style::BMgauss(_u, _v, _phase);
                _return
            }
            Style::Marsaglia(v1, v2, s, phase) => {
                let mut _v1 = v1;
                let mut _v2 = v2;
                let mut _s = s;
                let mut _phase = phase;
                let _return = marsaglia(self, &mut _v1, &mut _v2, &mut _s, &mut _phase);
                self.style = Style::Marsaglia(_v1, _v2, _s, _phase);
                _return
            }
        }
    }

    pub fn base(&mut self) -> usize {
        match self.handle {
            Some(e) => self.base[e].rand(),
            _ => {
                let mut _base = 0;
                for i in 0..self.base.len() {
                    _base += self.base[i].rand()/self.base.len();
                }
                _base
            }
        }
    }
}

fn gauss(base: &mut Rand, nsum: u32) -> f64 {
    let mut x = 0.0;
    for _ in 0..nsum {
        x += base.base() as f64 / RAND_MAX as f64;
    }
    x -= nsum as f64 / 2.0;
    x /= (nsum as f64 / 12.0).sqrt();
    x
}

fn bmgauss(base: &mut Rand, u: &mut f64, v: &mut f64, phase: &mut bool) -> f64 {
    if *phase {
        *phase = false;
        *u = (base.base() + 1) as f64 / (RAND_MAX + 2) as f64;
        *v = base.base() as f64 / (RAND_MAX + 1) as f64;
        (-2.0 * (*u).log10()).sqrt() * (2.0 * PI * (*v)).sin()
    } else {
        *phase = true;
        (-2.0 * (*u).log10()).sqrt() * (2.0 * PI * (*v)).cos()
    }
}

fn marsaglia(base: &mut Rand,
             v1: &mut f64,
             v2: &mut f64,
             s: &mut f64,
             phase: &mut bool)
             -> f64 {
    if *phase {
        *phase = false;
        let u1 = base.base() as f64 / RAND_MAX as f64;
        let u2 = base.base() as f64 / RAND_MAX as f64;
        *v1 = 2.0 * u1 - 1.0;
        *v2 = 2.0 * u2 - 1.0;
        *v1 * (-2.0 * (*s).log10() / (*s)).sqrt()
    } else {
        *phase = true;
        *v2 * (-2.0 * (*s).log10() / (*s)).sqrt()
    }
}
<|endoftext|>


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

use length::Length;

use point::Point2D;
use size::Size2D;
use std::cmp::{PartialEq, PartialOrd};
use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, PartialEq)]
pub struct Rect<T> {
    pub origin: Point2D<T>,
    pub size: Size2D<T>,
}

impl<T: fmt::Show> fmt::Show for Rect<T> {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Rect({} at {})", self.size, self.origin)
    }
}

pub fn Rect<T:Clone>(origin: Point2D<T>, size: Size2D<T>) -> Rect<T> {
    Rect {
        origin: origin,
        size: size
    }
}

impl<T: Clone + PartialOrd + Add<T,T> + Sub<T,T>> Rect<T> {
    #[inline]
    pub fn intersects(&self, other: &Rect<T>) -> bool {
        self.origin.x < other.origin.x + other.size.width &&
       other.origin.x <  self.origin.x + self.size.width &&
        self.origin.y < other.origin.y + other.size.height &&
       other.origin.y <  self.origin.y + self.size.height
    }

    #[inline]
    pub fn intersection(&self, other: &Rect<T>) -> Option<Rect<T>> {
        if !self.intersects(other) {
            return None;
        }

        let upper_left = Point2D(max(self.origin.x.clone(), other.origin.x.clone()),
                                 max(self.origin.y.clone(), other.origin.y.clone()));

        let lower_right = Point2D(min(self.origin.x + self.size.width,
                                      other.origin.x + other.size.width),
                                  min(self.origin.y + self.size.height,
                                      other.origin.y + other.size.height));

        Some(Rect(upper_left.clone(), Size2D(lower_right.x - upper_left.x,
                                             lower_right.y - upper_left.y)))
    }

    #[inline]
    pub fn union(&self, other: &Rect<T>) -> Rect<T> {
        let upper_left = Point2D(min(self.origin.x.clone(), other.origin.x.clone()),
                                 min(self.origin.y.clone(), other.origin.y.clone()));

        let lower_right = Point2D(max(self.origin.x + self.size.width,
                                      other.origin.x + other.size.width),
                                  max(self.origin.y + self.size.height,
                                      other.origin.y + other.size.height));

        Rect {
            origin: upper_left.clone(),
            size: Size2D(lower_right.x - upper_left.x, lower_right.y - upper_left.y)
        }
    }

    #[inline]
    pub fn translate(&self, other: &Point2D<T>) -> Rect<T> {
        Rect {
            origin: Point2D(self.origin.x + other.x, self.origin.y + other.y),
            size: self.size.clone()
        }
    }

    #[inline]
    pub fn contains(&self, other: &Point2D<T>) -> bool {
        self.origin.x <= other.x && other.x < self.origin.x + self.size.width &&
        self.origin.y <= other.y && other.y < self.origin.y + self.size.height
    }
}

impl<T:Clone + Zero> Rect<T> {
    pub fn zero() -> Rect<T> {
        Rect {
            origin: Zero::zero(),
            size: Size2D::zero(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.size.is_empty()
    }
}

pub fn min<T:Clone + PartialOrd>(x: T, y: T) -> T {
    if x <= y { x } else { y }
}

pub fn max<T:Clone + PartialOrd>(x: T, y: T) -> T {
    if x >= y { x } else { y }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Rect<T1>> for Rect<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Rect<T1> {
        Rect(self.origin * *scale, self.size * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Rect<T1>> for Rect<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Rect<T1> {
        Rect(self.origin / *scale, self.size / *scale)
    }
}

// Convenient aliases for Rect with typed units
pub type TypedRect<Unit, T> = Rect<Length<Unit, T>>;

impl<Unit, T: Clone> Rect<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Rect<T> {
        Rect(self.origin.to_untyped(), self.size.to_untyped())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(r: &Rect<T>) -> TypedRect<Unit, T> {
        Rect(Point2D::from_untyped(&r.origin), Size2D::from_untyped(&r.size))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Rect<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Rect<Length<Unit, T1>>> {
        match (self.origin.cast(), self.size.cast()) {
            (Some(origin), Some(size)) => Some(Rect(origin, size)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Rect<Length<Unit, T>> {
    pub fn as_f32(&self) -> Rect<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Rect<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}

#[test]
fn test_min_max() {
    assert!(min(0u32, 1u32) == 0u32);
    assert!(min(-1.0f32, 0.0f32) == -1.0f32);

    assert!(max(0u32, 1u32) == 1u32);
    assert!(max(-1.0f32, 0.0f32) == 0.0f32);
}

#[test]
fn test_translate() {
    let p = Rect(Point2D(0u32, 0u32), Size2D(50u32, 40u32));
    let pp = p.translate(&Point2D(10,15));

    assert!(pp.size.width == 50);
    assert!(pp.size.height == 40);
    assert!(pp.origin.x == 10);
    assert!(pp.origin.y == 15);

    let r = Rect(Point2D(-10i32, -5i32), Size2D(50i32, 40i32));
    let rr = r.translate(&Point2D(0,-10));

    assert!(rr.size.width == 50);
    assert!(rr.size.height == 40);
    assert!(rr.origin.x == -10);
    assert!(rr.origin.y == -15);
}

#[test]
fn test_union() {
    let p = Rect(Point2D(0i32, 0i32), Size2D(50i32, 40i32));
    let q = Rect(Point2D(20i32 ,20i32), Size2D(5i32, 5i32));
    let r = Rect(Point2D(-15i32, -30i32), Size2D(200i32, 15i32));
    let s = Rect(Point2D(20i32, -15i32), Size2D(250i32, 200i32));

    let pq = p.union(&q);
    assert!(pq.origin == Point2D(0, 0));
    assert!(pq.size == Size2D(50, 40));

    let pr = p.union(&r);
    assert!(pr.origin == Point2D(-15, -30));
    assert!(pr.size == Size2D(200, 70));

    let ps = p.union(&s);
    assert!(ps.origin == Point2D(0, -15));
    assert!(ps.size == Size2D(270, 200));

}

#[test]
fn test_intersection() {
    let p = Rect(Point2D(0i32, 0i32), Size2D(10i32, 20i32));
    let q = Rect(Point2D(5i32, 15i32), Size2D(10i32, 10i32));
    let r = Rect(Point2D(-5i32, -5i32), Size2D(8i32, 8i32));

    let pq = p.intersection(&q);
    assert!(pq.is_some());
    let pq = pq.unwrap();
    assert!(pq.origin == Point2D(5, 15));
    assert!(pq.size == Size2D(5, 5));

    let pr = p.intersection(&r);
    assert!(pr.is_some());
    let pr = pr.unwrap();
    assert!(pr.origin == Point2D(0, 0));
    assert!(pr.size == Size2D(3, 3));

    let qr = q.intersection(&r);
    assert!(qr.is_none());
}

#[test]
fn test_contains() {
    let r = Rect(Point2D(-20i32, 15i32), Size2D(100i32, 200i32));

    assert!(r.contains(&Point2D(0, 50)));
    assert!(r.contains(&Point2D(-10, 200)));

    // The `contains` method is inclusive of the top/left edges, but not the
    // bottom/right edges.
    assert!(r.contains(&Point2D(-20, 15)));
    assert!(!r.contains(&Point2D(80, 15)));
    assert!(!r.contains(&Point2D(80, 215)));
    assert!(!r.contains(&Point2D(-20, 215)));

    // Points beyond the top-left corner.
    assert!(!r.contains(&Point2D(-25, 15)));
    assert!(!r.contains(&Point2D(-15, 10)));

    // Points beyond the top-right corner.
    assert!(!r.contains(&Point2D(85, 20)));
    assert!(!r.contains(&Point2D(75, 10)));

    // Points beyond the bottom-right corner.
    assert!(!r.contains(&Point2D(85, 210)));
    assert!(!r.contains(&Point2D(75, 220)));

    // Points beyond the bottom-left corner.
    assert!(!r.contains(&Point2D(-25, 210)));
    assert!(!r.contains(&Point2D(-15, 220)));
}
<commit_msg>Add some helpers to Rect<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use length::Length;

use point::Point2D;
use size::Size2D;
use std::cmp::{PartialEq, PartialOrd};
use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, PartialEq)]
pub struct Rect<T> {
    pub origin: Point2D<T>,
    pub size: Size2D<T>,
}

impl<T: fmt::Show> fmt::Show for Rect<T> {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Rect({} at {})", self.size, self.origin)
    }
}

pub fn Rect<T:Clone>(origin: Point2D<T>, size: Size2D<T>) -> Rect<T> {
    Rect {
        origin: origin,
        size: size
    }
}

impl<T: Clone + PartialOrd + Add<T,T> + Sub<T,T>> Rect<T> {
    #[inline]
    pub fn intersects(&self, other: &Rect<T>) -> bool {
        self.origin.x < other.origin.x + other.size.width &&
       other.origin.x <  self.origin.x + self.size.width &&
        self.origin.y < other.origin.y + other.size.height &&
       other.origin.y <  self.origin.y + self.size.height
    }

    #[inline]
    pub fn max_x(&self) -> T {
        self.origin.x + self.size.width
    }

    #[inline]
    pub fn min_x(&self) -> T {
        self.origin.x.clone()
    }

    #[inline]
    pub fn max_y(&self) -> T {
        self.origin.y + self.size.height
    }

    #[inline]
    pub fn min_y(&self) -> T {
        self.origin.y.clone()
    }

    #[inline]
    pub fn intersection(&self, other: &Rect<T>) -> Option<Rect<T>> {
        if !self.intersects(other) {
            return None;
        }

        let upper_left = Point2D(max(self.min_x(), other.min_x()),
                                 max(self.min_y(), other.min_y()));

        let lower_right = Point2D(min(self.max_x(), other.max_x()),
                                  min(self.max_y(), other.max_y()));

        Some(Rect(upper_left.clone(), Size2D(lower_right.x - upper_left.x,
                                             lower_right.y - upper_left.y)))
    }

    #[inline]
    pub fn union(&self, other: &Rect<T>) -> Rect<T> {
        let upper_left = Point2D(min(self.min_x(), other.min_x()),
                                 min(self.min_y(), other.min_y()));

        let lower_right = Point2D(max(self.max_x(), other.max_x()),
                                  max(self.max_y(), other.max_y()));

        Rect {
            origin: upper_left.clone(),
            size: Size2D(lower_right.x - upper_left.x, lower_right.y - upper_left.y)
        }
    }

    #[inline]
    pub fn translate(&self, other: &Point2D<T>) -> Rect<T> {
        Rect {
            origin: Point2D(self.origin.x + other.x, self.origin.y + other.y),
            size: self.size.clone()
        }
    }

    #[inline]
    pub fn contains(&self, other: &Point2D<T>) -> bool {
        self.origin.x <= other.x && other.x < self.origin.x + self.size.width &&
        self.origin.y <= other.y && other.y < self.origin.y + self.size.height
    }
}

impl<Scale, T: Clone + Mul<Scale,T>> Rect<T> {
    #[inline]
    pub fn scale(&self, x: Scale, y: Scale) -> Rect<T> {
        Rect {
            origin: Point2D { x: self.origin.x * x, y: self.origin.y * y},
            size: Size2D { width: self.size.width * x, height: self.size.height * y}
        }
    }
}

impl<T:Clone + Zero> Rect<T> {
    pub fn zero() -> Rect<T> {
        Rect {
            origin: Zero::zero(),
            size: Size2D::zero(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.size.is_empty()
    }
}

pub fn min<T:Clone + PartialOrd>(x: T, y: T) -> T {
    if x <= y { x } else { y }
}

pub fn max<T:Clone + PartialOrd>(x: T, y: T) -> T {
    if x >= y { x } else { y }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Rect<T1>> for Rect<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Rect<T1> {
        Rect(self.origin * *scale, self.size * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Rect<T1>> for Rect<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Rect<T1> {
        Rect(self.origin / *scale, self.size / *scale)
    }
}

// Convenient aliases for Rect with typed units
pub type TypedRect<Unit, T> = Rect<Length<Unit, T>>;

impl<Unit, T: Clone> Rect<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Rect<T> {
        Rect(self.origin.to_untyped(), self.size.to_untyped())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(r: &Rect<T>) -> TypedRect<Unit, T> {
        Rect(Point2D::from_untyped(&r.origin), Size2D::from_untyped(&r.size))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Rect<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Rect<Length<Unit, T1>>> {
        match (self.origin.cast(), self.size.cast()) {
            (Some(origin), Some(size)) => Some(Rect(origin, size)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Rect<Length<Unit, T>> {
    pub fn as_f32(&self) -> Rect<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Rect<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}

#[test]
fn test_min_max() {
    assert!(min(0u32, 1u32) == 0u32);
    assert!(min(-1.0f32, 0.0f32) == -1.0f32);

    assert!(max(0u32, 1u32) == 1u32);
    assert!(max(-1.0f32, 0.0f32) == 0.0f32);
}

#[test]
fn test_translate() {
    let p = Rect(Point2D(0u32, 0u32), Size2D(50u32, 40u32));
    let pp = p.translate(&Point2D(10,15));

    assert!(pp.size.width == 50);
    assert!(pp.size.height == 40);
    assert!(pp.origin.x == 10);
    assert!(pp.origin.y == 15);

    let r = Rect(Point2D(-10i32, -5i32), Size2D(50i32, 40i32));
    let rr = r.translate(&Point2D(0,-10));

    assert!(rr.size.width == 50);
    assert!(rr.size.height == 40);
    assert!(rr.origin.x == -10);
    assert!(rr.origin.y == -15);
}

#[test]
fn test_union() {
    let p = Rect(Point2D(0i32, 0i32), Size2D(50i32, 40i32));
    let q = Rect(Point2D(20i32 ,20i32), Size2D(5i32, 5i32));
    let r = Rect(Point2D(-15i32, -30i32), Size2D(200i32, 15i32));
    let s = Rect(Point2D(20i32, -15i32), Size2D(250i32, 200i32));

    let pq = p.union(&q);
    assert!(pq.origin == Point2D(0, 0));
    assert!(pq.size == Size2D(50, 40));

    let pr = p.union(&r);
    assert!(pr.origin == Point2D(-15, -30));
    assert!(pr.size == Size2D(200, 70));

    let ps = p.union(&s);
    assert!(ps.origin == Point2D(0, -15));
    assert!(ps.size == Size2D(270, 200));

}

#[test]
fn test_intersection() {
    let p = Rect(Point2D(0i32, 0i32), Size2D(10i32, 20i32));
    let q = Rect(Point2D(5i32, 15i32), Size2D(10i32, 10i32));
    let r = Rect(Point2D(-5i32, -5i32), Size2D(8i32, 8i32));

    let pq = p.intersection(&q);
    assert!(pq.is_some());
    let pq = pq.unwrap();
    assert!(pq.origin == Point2D(5, 15));
    assert!(pq.size == Size2D(5, 5));

    let pr = p.intersection(&r);
    assert!(pr.is_some());
    let pr = pr.unwrap();
    assert!(pr.origin == Point2D(0, 0));
    assert!(pr.size == Size2D(3, 3));

    let qr = q.intersection(&r);
    assert!(qr.is_none());
}

#[test]
fn test_contains() {
    let r = Rect(Point2D(-20i32, 15i32), Size2D(100i32, 200i32));

    assert!(r.contains(&Point2D(0, 50)));
    assert!(r.contains(&Point2D(-10, 200)));

    // The `contains` method is inclusive of the top/left edges, but not the
    // bottom/right edges.
    assert!(r.contains(&Point2D(-20, 15)));
    assert!(!r.contains(&Point2D(80, 15)));
    assert!(!r.contains(&Point2D(80, 215)));
    assert!(!r.contains(&Point2D(-20, 215)));

    // Points beyond the top-left corner.
    assert!(!r.contains(&Point2D(-25, 15)));
    assert!(!r.contains(&Point2D(-15, 10)));

    // Points beyond the top-right corner.
    assert!(!r.contains(&Point2D(85, 20)));
    assert!(!r.contains(&Point2D(75, 10)));

    // Points beyond the bottom-right corner.
    assert!(!r.contains(&Point2D(85, 210)));
    assert!(!r.contains(&Point2D(75, 220)));

    // Points beyond the bottom-left corner.
    assert!(!r.contains(&Point2D(-25, 210)));
    assert!(!r.contains(&Point2D(-15, 220)));
}

#[test]
fn test_scale() {
    let p = Rect(Point2D(0u32, 0u32), Size2D(50u32, 40u32));
    let pp = p.scale(10, 15);

    assert!(pp.size.width == 500);
    assert!(pp.size.height == 600);
    assert!(pp.origin.x == 0);
    assert!(pp.origin.y == 0);

    let r = Rect(Point2D(-10i32, -5i32), Size2D(50i32, 40i32));
    let rr = r.scale(1, 20);

    assert!(rr.size.width == 50);
    assert!(rr.size.height == 800);
    assert!(rr.origin.x == -10);
    assert!(rr.origin.y == -100);
}

#[test]
fn test_min_max_x_y() {
    let p = Rect(Point2D(0u32, 0u32), Size2D(50u32, 40u32));
    assert!(p.max_y() == 40);
    assert!(p.min_y() == 0);
    assert!(p.max_x() == 50);
    assert!(p.min_x() == 0);

    let r = Rect(Point2D(-10i32, -5i32), Size2D(50i32, 40i32));
    assert!(r.max_y() == 35);
    assert!(r.min_y() == -5);
    assert!(r.max_x() == 40);
    assert!(r.min_x() == -10);
}
<|endoftext|>


<commit_before>// mrusty. mruby bindings for Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use rl_sys::readline;
use rl_sys::history::{listmgmt, mgmt};

use super::mruby::*;

/// A `struct` that exposes an `MRuby` to a REPL. Requires `repl` build feature.
///
/// # Examples
///
/// ```no-run
/// # use mrusty::MRuby;
/// # use mrusty::Repl;
/// let mruby = MRuby::new();
/// let repl = Repl::new(mruby);
///
/// repl.start();
/// ```
#[cfg(feature = "repl")]
pub struct Repl {
    mruby: MRubyType
}

impl Repl {
    /// Creates a new `Repl`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::MRuby;
    /// # use mrusty::Repl;
    /// let mruby = MRuby::new();
    /// let repl = Repl::new(mruby);
    /// ```
    pub fn new(mruby: MRubyType) -> Repl {
        mruby.filename("repl");

        Repl {
            mruby: mruby
        }
    }

    /// Starts a `Repl`.
    ///
    /// Use `'\'` for multiline statements.
    ///
    /// # Examples
    ///
    /// ```no-run
    /// # use mrusty::MRuby;
    /// # use mrusty::Repl;
    /// let mruby = MRuby::new();
    /// let repl = Repl::new(mruby);
    ///
    /// repl.start();
    /// ```
    pub fn start(&self) {
        let mut command = String::new();

        loop {
            let head = if command.is_empty() {
                "mrusty> "
            } else {
                "mrusty* "
            };

            let input = match readline::readline(head) {
                Ok(Some(s)) => s,
                Ok(None) => break,
                Err(e) => {
                    println!("{}", e);

                    break
                }
            };

            if input.ends_with("\\") {
                let trimmed = input.trim_right_matches("\\");

                command = command + trimmed + "\n";
                listmgmt::add(&trimmed).unwrap();

                continue
            }

            if command == "" {
                command = input;
            } else {
                command = command + &input;
            }

            match self.mruby.run(&command) {
                Ok(value) => {
                    let result = value.call("to_s", vec![]).unwrap().to_str().unwrap();

                    println!("{}", result);
                },
                Err(message) => {
                    println!("{}", message);
                }
            }

            if !command.is_empty() {
                command = String::new();
            }
        }

        mgmt::cleanup();
    }
}
<commit_msg>Fixed an issue with Repl history.<commit_after>// mrusty. mruby bindings for Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use rl_sys::readline;
use rl_sys::history::{listmgmt, mgmt};

use super::mruby::*;

/// A `struct` that exposes an `MRuby` to a REPL. Requires `repl` build feature.
///
/// # Examples
///
/// ```no-run
/// # use mrusty::MRuby;
/// # use mrusty::Repl;
/// let mruby = MRuby::new();
/// let repl = Repl::new(mruby);
///
/// repl.start();
/// ```
#[cfg(feature = "repl")]
pub struct Repl {
    mruby: MRubyType
}

impl Repl {
    /// Creates a new `Repl`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use mrusty::MRuby;
    /// # use mrusty::Repl;
    /// let mruby = MRuby::new();
    /// let repl = Repl::new(mruby);
    /// ```
    pub fn new(mruby: MRubyType) -> Repl {
        mruby.filename("repl");

        Repl {
            mruby: mruby
        }
    }

    /// Starts a `Repl`.
    ///
    /// Use `'\'` for multiline statements.
    ///
    /// # Examples
    ///
    /// ```no-run
    /// # use mrusty::MRuby;
    /// # use mrusty::Repl;
    /// let mruby = MRuby::new();
    /// let repl = Repl::new(mruby);
    ///
    /// repl.start();
    /// ```
    pub fn start(&self) {
        let mut command = String::new();

        loop {
            let head = if command.is_empty() {
                "mrusty> "
            } else {
                "mrusty* "
            };

            let input = match readline::readline(head) {
                Ok(Some(s)) => s,
                Ok(None) => break,
                Err(e) => {
                    println!("{}", e);

                    break
                }
            };

            if input.ends_with("\\") {
                let trimmed = input.trim_right_matches("\\");

                command = command + trimmed + "\n";
                listmgmt::add(&trimmed).unwrap();

                continue
            } else {
                listmgmt::add(&input).unwrap();
            }

            if command == "" {
                command = input;
            } else {
                command = command + &input;
            }

            match self.mruby.run(&command) {
                Ok(value) => {
                    let result = value.call("to_s", vec![]).unwrap().to_str().unwrap();

                    println!("{}", result);
                },
                Err(message) => {
                    println!("{}", message);
                }
            }

            if !command.is_empty() {
                command = String::new();
            }
        }

        mgmt::cleanup();
    }
}
<|endoftext|>


<commit_before>use crate::prelude::*;
use std::fs;
use std::path::{Path, PathBuf};

#[cfg(unix)]
pub fn pipe() -> Result<(fs::File, fs::File), Error> {
    use fs::File;
    use std::os::unix::prelude::*;

    unsafe {
        let mut fds = [0; 2];
        if libc::pipe(&mut fds[0] as *mut _) == 0 {
            let r = File::from_raw_fd(fds[0]);
            let w = File::from_raw_fd(fds[1]);
            Ok((r, w))
        } else {
            bail!("Failed to create a pipe.");
        }
    }
}

#[cfg(windows)]
pub fn pipe() -> Result<(fs::File, fs::File), Error> {
    use fs::File;
    use std::os::windows::prelude::*;
    use std::os::windows::raw::HANDLE;
    use std::ptr;
    use winapi::um::namedpipeapi::CreatePipe;

    unsafe {
        let mut r: HANDLE = ptr::null_mut();
        let mut w: HANDLE = ptr::null_mut();
        if CreatePipe(&mut r, &mut w, ptr::null_mut(), 4096) != 0 {
            let r = File::from_raw_handle(r);
            let w = File::from_raw_handle(w);
            Ok((r, w))
        } else {
            bail!("Failed to create a pipe.");
        }
    }
}

// #[cfg(unix)]
// pub fn sink() -> Result<fs::File, Error> {
//     Ok(fs::File::create("/dev/null")?)
// }

// #[cfg(windows)]
// pub fn sink() -> Result<fs::File, Error> {
//     Ok(fs::File::create(r#"\\.\NUL"#)?)
// }

/// Returns the actual file path casing.
#[cfg(windows)]
pub fn get_fs_path_case(path: &Path) -> Result<PathBuf, std::io::Error> {
    use std::ffi::OsString;
    use std::os::windows::ffi::{OsStrExt, OsStringExt};
    use winapi::um::fileapi::GetLongPathNameW;
    let mut wpath: Vec<u16> = path.as_os_str().encode_wide().collect();
    wpath.push(0);
    let mut buffer: Vec<u16> = Vec::with_capacity(256);
    unsafe {
        let mut size = GetLongPathNameW(wpath.as_ptr(), buffer.as_mut_ptr(), buffer.capacity() as u32) as usize;
        if size == 0 {
            return Err(std::io::Error::last_os_error());
        }
        if size > buffer.capacity() {
            buffer.reserve(size - buffer.capacity());
            size = GetLongPathNameW(wpath.as_ptr(), buffer.as_mut_ptr(), buffer.capacity() as u32) as usize;
            if size == 0 {
                return Err(std::io::Error::last_os_error());
            }
            assert!(size <= buffer.capacity());
        }
        buffer.set_len(size as usize);
    }
    Ok(PathBuf::from(OsString::from_wide(&buffer)))
}

#[cfg(unix)]
pub fn get_fs_path_case(path: &Path) -> Result<PathBuf, std::io::Error> {
    Ok(path.into())
}

#[cfg(all(unix, not(test)))]
pub fn make_case_folder() -> impl FnMut(&str) -> String {
    |k| k.into()
}

#[cfg(any(windows, test))]
pub fn make_case_folder() -> impl FnMut(&str) -> String {
    use std::collections::hash_map::Entry;
    use std::collections::HashMap;

    let mut case_map: HashMap<String, String> = HashMap::new();
    move |k| {
        let uk = k.to_uppercase();
        match case_map.entry(uk) {
            Entry::Occupied(e) => e.get().into(),
            Entry::Vacant(e) => {
                e.insert(k.into());
                k.into()
            }
        }
    }
}

#[test]
fn case_folder() {
    let mut folder = make_case_folder();
    assert_eq!(folder("Path"), "Path");
    assert_eq!(folder("PATH"), "Path");

    assert_eq!(folder("Foo"), "Foo");
    assert_eq!(folder("foo"), "Foo");
}

// #[cfg(unix)]
// pub fn waitpid(pid: u32) -> Result<(), io::Error> {
//     use std::ptr;

//     unsafe {
//         if libc::waitpid(pid as libc::pid_t, ptr::null_mut(), 0) < 0 {
//             return Err(io::Error::last_os_error()).into();
//         }
//     }
//     Ok(())
// }

// #[cfg(windows)]
// pub fn waitpid(pid: u32) -> Result<(), io::Error> {
//     use winapi::um::{
//         errhandlingapi::GetLastError, handleapi::CloseHandle, processthreadsapi::OpenProcess,
//         synchapi::WaitForSingleObject, winbase::INFINITE, winnt::PROCESS_QUERY_INFORMATION,
//     };

//     unsafe {
//         let handle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
//         if handle == ptr::null_mut() {
//             return Err(io::Error::last_os_error()).into();
//         }
//         WaitForSingleObject(handle, INFINITE);
//         CloseHandle(handle);
//     }
//     Ok(())
// }

// #[cfg(windows)]
// fn put_env(key: &CStr, value: &CStr) {
//     use std::os::raw::{c_char, c_int};
//     extern "C" {
//         fn _putenv_s(key: *const c_char, value: *const c_char) -> c_int;
//     }
//     unsafe {
//         _putenv_s(key.as_ptr(), value.as_ptr());
//     }
// }
<commit_msg>Make console pipe buffer size on Windows the same as on Linux.<commit_after>use crate::prelude::*;
use std::fs;
use std::path::{Path, PathBuf};

#[cfg(unix)]
pub fn pipe() -> Result<(fs::File, fs::File), Error> {
    use fs::File;
    use std::os::unix::prelude::*;

    unsafe {
        let mut fds = [0; 2];
        if libc::pipe(&mut fds[0] as *mut _) == 0 {
            let r = File::from_raw_fd(fds[0]);
            let w = File::from_raw_fd(fds[1]);
            Ok((r, w))
        } else {
            bail!("Failed to create a pipe.");
        }
    }
}

#[cfg(windows)]
pub fn pipe() -> Result<(fs::File, fs::File), Error> {
    use fs::File;
    use std::os::windows::prelude::*;
    use std::os::windows::raw::HANDLE;
    use std::ptr;
    use winapi::um::namedpipeapi::CreatePipe;

    unsafe {
        let mut r: HANDLE = ptr::null_mut();
        let mut w: HANDLE = ptr::null_mut();
        if CreatePipe(&mut r, &mut w, ptr::null_mut(), 65536) != 0 {
            let r = File::from_raw_handle(r);
            let w = File::from_raw_handle(w);
            Ok((r, w))
        } else {
            bail!("Failed to create a pipe.");
        }
    }
}

// #[cfg(unix)]
// pub fn sink() -> Result<fs::File, Error> {
//     Ok(fs::File::create("/dev/null")?)
// }

// #[cfg(windows)]
// pub fn sink() -> Result<fs::File, Error> {
//     Ok(fs::File::create(r#"\\.\NUL"#)?)
// }

/// Returns the actual file path casing.
#[cfg(windows)]
pub fn get_fs_path_case(path: &Path) -> Result<PathBuf, std::io::Error> {
    use std::ffi::OsString;
    use std::os::windows::ffi::{OsStrExt, OsStringExt};
    use winapi::um::fileapi::GetLongPathNameW;
    let mut wpath: Vec<u16> = path.as_os_str().encode_wide().collect();
    wpath.push(0);
    let mut buffer: Vec<u16> = Vec::with_capacity(256);
    unsafe {
        let mut size = GetLongPathNameW(wpath.as_ptr(), buffer.as_mut_ptr(), buffer.capacity() as u32) as usize;
        if size == 0 {
            return Err(std::io::Error::last_os_error());
        }
        if size > buffer.capacity() {
            buffer.reserve(size - buffer.capacity());
            size = GetLongPathNameW(wpath.as_ptr(), buffer.as_mut_ptr(), buffer.capacity() as u32) as usize;
            if size == 0 {
                return Err(std::io::Error::last_os_error());
            }
            assert!(size <= buffer.capacity());
        }
        buffer.set_len(size as usize);
    }
    Ok(PathBuf::from(OsString::from_wide(&buffer)))
}

#[cfg(unix)]
pub fn get_fs_path_case(path: &Path) -> Result<PathBuf, std::io::Error> {
    Ok(path.into())
}

#[cfg(all(unix, not(test)))]
pub fn make_case_folder() -> impl FnMut(&str) -> String {
    |k| k.into()
}

#[cfg(any(windows, test))]
pub fn make_case_folder() -> impl FnMut(&str) -> String {
    use std::collections::hash_map::Entry;
    use std::collections::HashMap;

    let mut case_map: HashMap<String, String> = HashMap::new();
    move |k| {
        let uk = k.to_uppercase();
        match case_map.entry(uk) {
            Entry::Occupied(e) => e.get().into(),
            Entry::Vacant(e) => {
                e.insert(k.into());
                k.into()
            }
        }
    }
}

#[test]
fn case_folder() {
    let mut folder = make_case_folder();
    assert_eq!(folder("Path"), "Path");
    assert_eq!(folder("PATH"), "Path");

    assert_eq!(folder("Foo"), "Foo");
    assert_eq!(folder("foo"), "Foo");
}

// #[cfg(unix)]
// pub fn waitpid(pid: u32) -> Result<(), io::Error> {
//     use std::ptr;

//     unsafe {
//         if libc::waitpid(pid as libc::pid_t, ptr::null_mut(), 0) < 0 {
//             return Err(io::Error::last_os_error()).into();
//         }
//     }
//     Ok(())
// }

// #[cfg(windows)]
// pub fn waitpid(pid: u32) -> Result<(), io::Error> {
//     use winapi::um::{
//         errhandlingapi::GetLastError, handleapi::CloseHandle, processthreadsapi::OpenProcess,
//         synchapi::WaitForSingleObject, winbase::INFINITE, winnt::PROCESS_QUERY_INFORMATION,
//     };

//     unsafe {
//         let handle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
//         if handle == ptr::null_mut() {
//             return Err(io::Error::last_os_error()).into();
//         }
//         WaitForSingleObject(handle, INFINITE);
//         CloseHandle(handle);
//     }
//     Ok(())
// }

// #[cfg(windows)]
// fn put_env(key: &CStr, value: &CStr) {
//     use std::os::raw::{c_char, c_int};
//     extern "C" {
//         fn _putenv_s(key: *const c_char, value: *const c_char) -> c_int;
//     }
//     unsafe {
//         _putenv_s(key.as_ptr(), value.as_ptr());
//     }
// }
<|endoftext|>