<commit_before>use ffi;
use libc::{c_uint, c_int, c_void};
use num::complex::Complex64;

use plan::RawPlan;

/// How much effort FFTW should put into computing the best strategy
/// to use.
///
/// The `FFTW_WISDOM_ONLY` rigor level is replaced by the
pub enum Rigor {
    Estimate,
    Measure,
    Patient,
    Exhaustive,
}
impl Rigor {
    fn flags(self) -> c_uint {
        match self {
            Estimate => ffi::FFTW_ESTIMATE,
            Measure => ffi::FFTW_MEASURE,
            Patient => ffi::FFTW_PATIENT,
            Exhaustive => ffi::FFTW_EXHAUSTIVE,
        }
    }
}

/// The direction of the transform to perform..
pub enum Direction {
    Forward, Backward
}

/// Control the basic properties of a set of transforms.
pub struct Planner {
    rigor: Rigor,
    wisdom_restriction: bool,
    direction: Direction,

    #[allow(dead_code)]
    dims: Vec<Dim>,
    #[allow(dead_code)]
    howmany: Vec<Dim>,
}

impl Planner {
    /// Construct a new planner with default values.
    ///
    /// This defaults to a forward transform with estimate rigor.
    pub fn new() -> Planner {
        Planner {
            rigor: Estimate,
            wisdom_restriction: false,
            direction: Forward,
            dims: vec![],
            howmany: vec![],
        }
    }

    /// Set the rigor to use for this plan.
    pub fn rigor(mut self, r: Rigor) -> Planner {
        self.rigor = r;
        self
    }
    /// Set whether the planner should only be successfully created if
    /// there exists wisdom created with at least the rigor level set.
    pub fn wisdom_restriction(mut self, wisdom_only: bool) -> Planner {
        self.wisdom_restriction = wisdom_only;
        self
    }

    /// Set the direction of the transform to perform.
    pub fn direction(mut self, direction: Direction) -> Planner {
        self.direction = direction;
        self
    }

    #[cfg(higher_dim_is_hard)]
    pub fn dims_row_major(mut self, dims: Vec<uint>) -> Planner {
        assert!(dims.len() >= 1);

        self.dims = dims.iter().map(|n| Dim { n: *n, in_stride: 1, out_stride: 1 });
        for i in range(0, self.dims.len() - 1).rev() {
            let stride = self.dims[i + 1].n * self.dims[i + 1].in_stride;
            self.dims[i].in_stride = stride;
            self.dims[i].out_stride = stride;
        }

        self
    }
    #[cfg(higher_dim_is_hard)]
    pub fn multiples(mut self, number: uint) -> PlanMem<I, O> {
        unimplemented!()
        self.how_many = Contiguous(vec![number]);
        self
    }

    fn flags(&self) -> c_uint {
        self.rigor.flags() | if self.wisdom_restriction {
            ffi::FFTW_WISDOM_ONLY
        } else {
            0
        }
    }
    fn dir(&self) -> c_int {
        match self.direction {
            Forward => ffi::FFTW_FORWARD,
            Backward => ffi::FFTW_BACKWARD,
        }
    }

    pub fn inplace(self) -> InPlacePlanner {
        InPlacePlanner { plan: self }
    }

    pub fn c2c<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[Complex64]>, O: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: c2c,

            dims: dims,
            how_many: vec![],
        }
    }
    pub fn c2r<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[Complex64]>, O: DerefMut<[f64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len() / 2 + 1);
        let dims = vec![Dim { n: 2 * (in_.len() - 1), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: c2r,

            dims: dims,
            how_many: vec![],
        }
    }
    pub fn r2c<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[f64]>, O: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() / 2 + 1 <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: r2c,

            dims: dims,
            how_many: vec![],
        }
    }
    #[cfg(r2r_is_hard)]
    pub fn r2r<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[f64]>, O: DerefMut<[f64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: *self,
            in_: in_,
            out: Some(out),
            planner: r2r,

            dims: dims,
            how_many: vec![],
        }
    }
}

pub struct InPlacePlanner {
    plan: Planner
}

impl InPlacePlanner {
    pub fn c2c<I>(self, in_: I) -> PlanMem<I, I>
        where I: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self.plan,
            in_: in_,
            out: None,
            planner: c2c,

            dims: dims,
            how_many: vec![],
        }
    }
}

type GuruPlanner =
    unsafe fn(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan;

unsafe fn c2c(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft(rank, dims,
                            howmany_rank, howmany_dims,
                            in_ as *mut _, out as *mut _,
                            sign, flags)
}

unsafe fn r2c(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              _sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft_r2c(rank, dims,
                                howmany_rank, howmany_dims,
                                in_ as *mut _, out as *mut _,
                                flags)
}
unsafe fn c2r(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              _sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft_c2r(rank, dims,
                                howmany_rank, howmany_dims,
                                in_ as *mut _, out as *mut _,
                                flags)
}
#[cfg(r2r_is_hard)]
unsafe fn r2r(n: c_int, in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_r2r_1d(n,
                          in_ as *mut f64, out as *mut f64,
                          sign, flags)
}

#[repr(C)]
pub struct Dim {
    pub n: uint,
    pub in_stride: uint,
    pub out_stride: uint,
}

pub struct PlanMem<I, O> {
    plan: Planner,
    dims: Vec<Dim>,
    #[allow(dead_code)]
    how_many: Vec<Dim>,
    in_: I,
    out: Option<O>,
    planner: GuruPlanner
}

impl<X, Y, I: DerefMut<[X]>, O: DerefMut<[Y]>> PlanMem<I, O> {
    pub fn plan(mut self) -> Result<Planned<I, O>, PlanMem<I, O>> {
        let plan;
        {
            let in_ptr = self.in_.as_mut_ptr() as *mut c_void;
            let out_ptr = match self.out {
                None => in_ptr,
                Some(ref mut o) => o.as_mut_ptr() as *mut c_void,
            };
            assert!(self.dims.len() == 1);

            plan = RawPlan::new(|| unsafe {
                (self.planner)(
                    self.dims.len() as c_int,
                    self.dims.as_ptr() as *const ffi::fftw_iodim64,
                    0, [].as_ptr(),
                    in_ptr,
                    out_ptr,
                    self.plan.dir(),
                    self.plan.flags())
            });
        }
        match plan {
            None => Err(self),
            Some(p) => Ok(Planned { mem: self, plan: p })
        }
    }
}

pub struct Planned<I, O> {
    mem: PlanMem<I, O>,
    plan: RawPlan,
}

impl<X, Y, I: DerefMut<[X]>, O: DerefMut<[Y]>> Planned<I, O> {
    pub fn input(&mut self) -> &mut [X] {
        &mut *self.mem.in_
    }
    pub fn output(&mut self) -> Option<&mut [Y]> {
        self.mem.out.as_mut().map(|o| &mut **o)
    }

    pub fn execute(&mut self) {
        unsafe {
            self.plan.execute()
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use libc::ptrdiff_t;
    use ffi::Struct_fftw_iodim64_do_not_use_me;
    use super::Dim;

    #[test]
    fn iodims_are_compatible() {
        // handle 32-bit and 64-bit platforms properly
        let n = 0x0102_0304_0506_0708u64 as uint;
        let is = 0x090A_0B0C_0D0E_0F00u64 as uint;
        let os = 0x1122_3344_5566_7788u64 as uint;

        let d = Dim { n: n, in_stride: is, out_stride: os };
        let f = Struct_fftw_iodim64_do_not_use_me {
            n: n as ptrdiff_t, is: is as ptrdiff_t, os: os as ptrdiff_t
        };
        type T = (uint, uint, uint);
        unsafe {
            assert_eq!(mem::transmute::<_, T>(d), mem::transmute::<_, T>(f));
        }
    }
}
<commit_msg>Update for enum namespacing.<commit_after>use ffi;
use libc::{c_uint, c_int, c_void};
use num::complex::Complex64;

use plan::RawPlan;

/// How much effort FFTW should put into computing the best strategy
/// to use.
///
/// The `FFTW_WISDOM_ONLY` rigor level is replaced by the
pub enum Rigor {
    Estimate,
    Measure,
    Patient,
    Exhaustive,
}
impl Rigor {
    fn flags(self) -> c_uint {
        match self {
            Estimate => ffi::FFTW_ESTIMATE,
            Measure => ffi::FFTW_MEASURE,
            Patient => ffi::FFTW_PATIENT,
            Exhaustive => ffi::FFTW_EXHAUSTIVE,
        }
    }
}

/// The direction of the transform to perform..
pub enum Direction {
    Forward, Backward
}

/// Control the basic properties of a set of transforms.
pub struct Planner {
    rigor: Rigor,
    wisdom_restriction: bool,
    direction: Direction,

    #[allow(dead_code)]
    dims: Vec<Dim>,
    #[allow(dead_code)]
    howmany: Vec<Dim>,
}

impl Planner {
    /// Construct a new planner with default values.
    ///
    /// This defaults to a forward transform with estimate rigor.
    pub fn new() -> Planner {
        Planner {
            rigor: Rigor::Estimate,
            wisdom_restriction: false,
            direction: Direction::Forward,
            dims: vec![],
            howmany: vec![],
        }
    }

    /// Set the rigor to use for this plan.
    pub fn rigor(mut self, r: Rigor) -> Planner {
        self.rigor = r;
        self
    }
    /// Set whether the planner should only be successfully created if
    /// there exists wisdom created with at least the rigor level set.
    pub fn wisdom_restriction(mut self, wisdom_only: bool) -> Planner {
        self.wisdom_restriction = wisdom_only;
        self
    }

    /// Set the direction of the transform to perform.
    pub fn direction(mut self, direction: Direction) -> Planner {
        self.direction = direction;
        self
    }

    #[cfg(higher_dim_is_hard)]
    pub fn dims_row_major(mut self, dims: Vec<uint>) -> Planner {
        assert!(dims.len() >= 1);

        self.dims = dims.iter().map(|n| Dim { n: *n, in_stride: 1, out_stride: 1 });
        for i in range(0, self.dims.len() - 1).rev() {
            let stride = self.dims[i + 1].n * self.dims[i + 1].in_stride;
            self.dims[i].in_stride = stride;
            self.dims[i].out_stride = stride;
        }

        self
    }
    #[cfg(higher_dim_is_hard)]
    pub fn multiples(mut self, number: uint) -> PlanMem<I, O> {
        unimplemented!()
        self.how_many = Contiguous(vec![number]);
        self
    }

    fn flags(&self) -> c_uint {
        self.rigor.flags() | if self.wisdom_restriction {
            ffi::FFTW_WISDOM_ONLY
        } else {
            0
        }
    }
    fn dir(&self) -> c_int {
        match self.direction {
            Forward => ffi::FFTW_FORWARD,
            Backward => ffi::FFTW_BACKWARD,
        }
    }

    pub fn inplace(self) -> InPlacePlanner {
        InPlacePlanner { plan: self }
    }

    pub fn c2c<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[Complex64]>, O: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: c2c,

            dims: dims,
            how_many: vec![],
        }
    }
    pub fn c2r<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[Complex64]>, O: DerefMut<[f64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len() / 2 + 1);
        let dims = vec![Dim { n: 2 * (in_.len() - 1), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: c2r,

            dims: dims,
            how_many: vec![],
        }
    }
    pub fn r2c<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[f64]>, O: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() / 2 + 1 <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self,
            in_: in_,
            out: Some(out),
            planner: r2c,

            dims: dims,
            how_many: vec![],
        }
    }
    #[cfg(r2r_is_hard)]
    pub fn r2r<I, O>(self, in_: I, out: O) -> PlanMem<I, O>
        where I: DerefMut<[f64]>, O: DerefMut<[f64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        assert!(in_.len() <= out.len());
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: *self,
            in_: in_,
            out: Some(out),
            planner: r2r,

            dims: dims,
            how_many: vec![],
        }
    }
}

pub struct InPlacePlanner {
    plan: Planner
}

impl InPlacePlanner {
    pub fn c2c<I>(self, in_: I) -> PlanMem<I, I>
        where I: DerefMut<[Complex64]>
    {
        assert!(in_.len() <= 0x7F_FF_FF_FF);
        let dims = vec![Dim { n: in_.len(), in_stride: 1, out_stride: 1 }];
        PlanMem {
            plan: self.plan,
            in_: in_,
            out: None,
            planner: c2c,

            dims: dims,
            how_many: vec![],
        }
    }
}

type GuruPlanner =
    unsafe fn(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan;

unsafe fn c2c(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft(rank, dims,
                            howmany_rank, howmany_dims,
                            in_ as *mut _, out as *mut _,
                            sign, flags)
}

unsafe fn r2c(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              _sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft_r2c(rank, dims,
                                howmany_rank, howmany_dims,
                                in_ as *mut _, out as *mut _,
                                flags)
}
unsafe fn c2r(rank: c_int, dims: *const ffi::fftw_iodim64,
              howmany_rank: c_int, howmany_dims: *const ffi::fftw_iodim64,
              in_: *mut c_void, out: *mut c_void,
              _sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_guru64_dft_c2r(rank, dims,
                                howmany_rank, howmany_dims,
                                in_ as *mut _, out as *mut _,
                                flags)
}
#[cfg(r2r_is_hard)]
unsafe fn r2r(n: c_int, in_: *mut c_void, out: *mut c_void,
              sign: c_int, flags: c_uint) -> ffi::fftw_plan {
    ffi::fftw_plan_r2r_1d(n,
                          in_ as *mut f64, out as *mut f64,
                          sign, flags)
}

#[repr(C)]
pub struct Dim {
    pub n: uint,
    pub in_stride: uint,
    pub out_stride: uint,
}

pub struct PlanMem<I, O> {
    plan: Planner,
    dims: Vec<Dim>,
    #[allow(dead_code)]
    how_many: Vec<Dim>,
    in_: I,
    out: Option<O>,
    planner: GuruPlanner
}

impl<X, Y, I: DerefMut<[X]>, O: DerefMut<[Y]>> PlanMem<I, O> {
    pub fn plan(mut self) -> Result<Planned<I, O>, PlanMem<I, O>> {
        let plan;
        {
            let in_ptr = self.in_.as_mut_ptr() as *mut c_void;
            let out_ptr = match self.out {
                None => in_ptr,
                Some(ref mut o) => o.as_mut_ptr() as *mut c_void,
            };
            assert!(self.dims.len() == 1);

            plan = RawPlan::new(|| unsafe {
                (self.planner)(
                    self.dims.len() as c_int,
                    self.dims.as_ptr() as *const ffi::fftw_iodim64,
                    0, [].as_ptr(),
                    in_ptr,
                    out_ptr,
                    self.plan.dir(),
                    self.plan.flags())
            });
        }
        match plan {
            None => Err(self),
            Some(p) => Ok(Planned { mem: self, plan: p })
        }
    }
}

pub struct Planned<I, O> {
    mem: PlanMem<I, O>,
    plan: RawPlan,
}

impl<X, Y, I: DerefMut<[X]>, O: DerefMut<[Y]>> Planned<I, O> {
    pub fn input(&mut self) -> &mut [X] {
        &mut *self.mem.in_
    }
    pub fn output(&mut self) -> Option<&mut [Y]> {
        self.mem.out.as_mut().map(|o| &mut **o)
    }

    pub fn execute(&mut self) {
        unsafe {
            self.plan.execute()
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use libc::ptrdiff_t;
    use ffi::Struct_fftw_iodim64_do_not_use_me;
    use super::Dim;

    #[test]
    fn iodims_are_compatible() {
        // handle 32-bit and 64-bit platforms properly
        let n = 0x0102_0304_0506_0708u64 as uint;
        let is = 0x090A_0B0C_0D0E_0F00u64 as uint;
        let os = 0x1122_3344_5566_7788u64 as uint;

        let d = Dim { n: n, in_stride: is, out_stride: os };
        let f = Struct_fftw_iodim64_do_not_use_me {
            n: n as ptrdiff_t, is: is as ptrdiff_t, os: os as ptrdiff_t
        };
        type T = (uint, uint, uint);
        unsafe {
            assert_eq!(mem::transmute::<_, T>(d), mem::transmute::<_, T>(f));
        }
    }
}
<|endoftext|>


<commit_before>//! This module defines [`BVH`] and [`BVHNode`] and functions for building and traversing it.
//!
//! [`BVH`]: struct.BVH.html
//! [`BVHNode`]: struct.BVHNode.html
//!

use EPSILON;
use aabb::{AABB, Bounded};
use bounding_hierarchy::{BoundingHierarchy, BHShape};
use ray::Ray;
use std::f32;
use std::iter::repeat;

/// The [`BVHNode`] enum that describes a node in a [`BVH`].
/// It's either a leaf node and references a shape (by holding its index)
/// or a regular node that has two child nodes.
/// The non-leaf node stores the [`AABB`]s of its children.
///
/// [`AABB`]: ../aabb/struct.AABB.html
/// [`BVH`]: struct.BVH.html
/// [`BVH`]: struct.BVHNode.html
///
#[derive(Debug, Copy, Clone)]
pub enum BVHNode {
    /// Leaf node.
    Leaf {
        /// The node's parent.
        parent: usize,

        /// The node's depth.
        depth: u32,

        /// The shape contained in this leaf.
        shape: usize,
    },
    /// Inner node.
    Node {
        /// The node's parent.
        parent: usize,

        /// The node's depth.
        depth: u32,

        /// The convex hull of the shapes' `AABB`s in child_l.
        child_l_aabb: AABB,

        /// Index of the left subtree's root node.
        child_l: usize,

        /// The convex hull of the shapes' `AABB`s in child_r.
        child_r_aabb: AABB,

        /// Index of the right subtree's root node.
        child_r: usize,
    },
}

impl BVHNode {
    fn create_dummy() -> BVHNode {
        BVHNode::Leaf {
            parent: 0,
            depth: 0,
            shape: 0,
        }
    }

    /// Builds a [`BVHNode`] recursively using SAH partitioning.
    /// Returns the index of the node in the nodes vector.
    ///
    /// [`BVHNode`]: enum.BVHNode.html
    ///
    pub fn build<T: BHShape>(shapes: &mut [T],
                             indices: Vec<usize>,
                             nodes: &mut Vec<BVHNode>,
                             parent: usize,
                             depth: u32)
                             -> usize {
        // Helper function to accumulate the AABB joint and the centroids AABB
        fn grow_convex_hull(convex_hull: (AABB, AABB), shape_aabb: &AABB) -> (AABB, AABB) {
            let center = &shape_aabb.center();
            let convex_hull_aabbs = &convex_hull.0;
            let convex_hull_centroids = &convex_hull.1;
            (convex_hull_aabbs.join(shape_aabb), convex_hull_centroids.grow(center))
        }

        let mut convex_hull = Default::default();
        for index in &indices {
            convex_hull = grow_convex_hull(convex_hull, &shapes[*index].aabb());
        }
        let (aabb_bounds, centroid_bounds) = convex_hull;

        // If there is only one element left, don't split anymore
        if indices.len() == 1 {
            let shape_index = indices[0];
            nodes.push(BVHNode::Leaf {
                parent: parent,
                depth: depth,
                shape: shape_index,
            });
            let node_index = nodes.len() - 1;
            // Let the shape know the index of the node that represents it
            shapes[shape_index].set_bh_node_index(node_index);
            return node_index;
        }

        // Find the axis along which the shapes are spread the most
        let split_axis = centroid_bounds.largest_axis();
        let split_axis_size = centroid_bounds.max[split_axis] - centroid_bounds.min[split_axis];

        /// Defines a Bucket utility object.
        #[derive(Copy, Clone)]
        struct Bucket {
            size: usize,
            aabb: AABB,
        }

        impl Bucket {
            /// Returns an empty bucket.
            fn empty() -> Bucket {
                Bucket {
                    size: 0,
                    aabb: AABB::empty(),
                }
            }

            /// Extends this `Bucket` by the given `AABB`.
            fn add_aabb(&mut self, aabb: &AABB) {
                self.size += 1;
                self.aabb = self.aabb.join(aabb);
            }
        }

        /// Joins two `Bucket`s.
        fn join_bucket(a: Bucket, b: &Bucket) -> Bucket {
            Bucket {
                size: a.size + b.size,
                aabb: a.aabb.join(&b.aabb),
            }
        }

        // Create six buckets, and six index assignment vectors
        const NUM_BUCKETS: usize = 6;
        let mut buckets = [Bucket::empty(); NUM_BUCKETS];
        let mut bucket_assignments: [Vec<usize>; NUM_BUCKETS] = Default::default();

        if split_axis_size < EPSILON {
            // Spread the remaining shapes evenly across buckets,
            // instead of using a heuristic
            for (counter, idx) in (&indices).iter().enumerate() {
                let shape = &shapes[*idx];
                let shape_aabb = shape.aabb();

                let bucket_num = counter % NUM_BUCKETS;

                buckets[bucket_num].add_aabb(&shape_aabb);
                bucket_assignments[bucket_num].push(*idx);
            }
        } else {
            // Assign each shape to a bucket
            for idx in &indices {
                let shape = &shapes[*idx];
                let shape_aabb = shape.aabb();
                let shape_center = shape_aabb.center();

                // Get the relative position of the shape centroid [0.0..1.0]
                let bucket_num_relative =
                    (shape_center[split_axis] - centroid_bounds.min[split_axis]) / split_axis_size;

                // Convert that to the actual `Bucket` number
                let bucket_num = (bucket_num_relative * (NUM_BUCKETS as f32 - 0.01)) as usize;

                // Extend the selected `Bucket` and add the index to the actual bucket
                buckets[bucket_num].add_aabb(&shape_aabb);
                bucket_assignments[bucket_num].push(*idx);
            }
        }

        // Compute the costs for each configuration and
        // select the configuration with the minimal costs
        let mut min_bucket = 0;
        let mut min_cost = f32::INFINITY;
        let mut child_l_aabb = AABB::empty();
        let mut child_r_aabb = AABB::empty();
        for i in 0..(NUM_BUCKETS - 1) {
            let child_l = buckets.iter().take(i + 1).fold(Bucket::empty(), join_bucket);
            let child_r = buckets.iter().skip(i + 1).fold(Bucket::empty(), join_bucket);

            let cost = (child_l.size as f32 * child_l.aabb.surface_area() +
                        child_r.size as f32 * child_r.aabb.surface_area()) /
                       aabb_bounds.surface_area();

            if cost < min_cost {
                min_bucket = i;
                min_cost = cost;
                child_l_aabb = child_l.aabb;
                child_r_aabb = child_r.aabb;
            }
        }

        // Join together all index buckets, and proceed recursively
        let mut child_l_indices = Vec::new();
        for mut indices in bucket_assignments.iter_mut().take(min_bucket + 1) {
            child_l_indices.append(&mut indices);
        }
        let mut child_r_indices = Vec::new();
        for mut indices in bucket_assignments.iter_mut().skip(min_bucket + 1) {
            child_r_indices.append(&mut indices);
        }

        let node_index = nodes.len();

        nodes.push(BVHNode::create_dummy());

        let child_l = BVHNode::build(shapes, child_l_indices, nodes, node_index, depth + 1);
        let child_r = BVHNode::build(shapes, child_r_indices, nodes, node_index, depth + 1);

        // Construct the actual data structure
        nodes[node_index] = BVHNode::Node {
            parent: parent,
            depth: depth,
            child_l_aabb: child_l_aabb,
            child_l: child_l,
            child_r_aabb: child_r_aabb,
            child_r: child_r,
        };

        node_index
    }

    /// Traverses the [`BVH`] recursively and returns all shapes whose [`AABB`] is
    /// intersected by the given [`Ray`].
    ///
    /// [`AABB`]: ../aabb/struct.AABB.html
    /// [`BVH`]: struct.BVH.html
    /// [`Ray`]: ../ray/struct.Ray.html
    ///
    pub fn traverse_recursive(nodes: &Vec<BVHNode>, node_index: usize, ray: &Ray, indices: &mut Vec<usize>) {
        let node = &nodes[node_index];
        match *node {
            BVHNode::Node { ref child_l_aabb, child_l, ref child_r_aabb, child_r, .. } => {
                if ray.intersects_aabb(child_l_aabb) {
                    BVHNode::traverse_recursive(nodes, child_l, ray, indices);
                }
                if ray.intersects_aabb(child_r_aabb) {
                    BVHNode::traverse_recursive(nodes, child_r, ray, indices);
                }
            }
            BVHNode::Leaf { shape, .. } => {
                indices.push(shape);
            }
        }
    }
}

/// The [`BVH`] data structure. Contains the list of [`BVHNode`]s.
///
/// [`BVH`]: struct.BVH.html
///
pub struct BVH {
    /// The list of nodes of the [`BVH`].
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub nodes: Vec<BVHNode>,
}

impl BVH {
    /// Creates a new [`BVH`] from the `shapes` slice.
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub fn build<Shape: BHShape>(shapes: &mut [Shape]) -> BVH {
        let indices = (0..shapes.len()).collect::<Vec<usize>>();
        let mut nodes = Vec::new();
        BVHNode::build(shapes, indices, &mut nodes, 0, 0);
        BVH { nodes: nodes }
    }

    /// Traverses the [`BVH`].
    /// Returns a subset of `shapes`, in which the [`AABB`]s of the elements were hit by `ray`.
    ///
    /// [`BVH`]: struct.BVH.html
    /// [`AABB`]: ../aabb/struct.AABB.html
    ///
    pub fn traverse<'a, Shape: Bounded>(&'a self, ray: &Ray, shapes: &'a [Shape]) -> Vec<&Shape> {
        let mut indices = Vec::new();
        BVHNode::traverse_recursive(&self.nodes, 0, ray, &mut indices);
        let mut hit_shapes = Vec::new();
        for index in &indices {
            let shape = &shapes[*index];
            hit_shapes.push(shape);
        }
        hit_shapes
    }

    /// Prints the [`BVH`] in a tree-like visualization.
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub fn pretty_print(&self) {
        let nodes = &self.nodes;
        fn print_node(nodes: &Vec<BVHNode>, node_index: usize) {
            let node = &nodes[node_index];
            match *node {
                BVHNode::Node { child_l, child_r, depth, child_l_aabb, child_r_aabb, .. } => {
                    let padding: String = repeat(" ").take(depth as usize).collect();
                    println!("{}child_l {:?}", padding, child_l_aabb);
                    print_node(nodes, child_l);
                    println!("{}child_r {:?}", padding, child_r_aabb);
                    print_node(nodes, child_r);
                }
                BVHNode::Leaf { shape, depth, .. } => {
                    let padding: String = repeat(" ").take(depth as usize).collect();
                    println!("{}shape\t{:?}", padding, shape);
                }
            }
        }
        print_node(nodes, 0);
    }
}

impl BoundingHierarchy for BVH {
    fn build<Shape: BHShape>(shapes: &mut [Shape]) -> BVH {
        BVH::build(shapes)
    }

    fn traverse<'a, Shape: Bounded>(&'a self, ray: &Ray, shapes: &'a [Shape]) -> Vec<&Shape> {
        self.traverse(ray, shapes)
    }

    fn pretty_print(&self) {
        self.pretty_print();
    }
}

#[cfg(test)]
pub mod tests {
    use bvh::BVH;
    use testbase::{build_some_bh, traverse_some_bh, build_1200_triangles_bh,
                   build_12k_triangles_bh, build_120k_triangles_bh, intersect_1200_triangles_bh,
                   intersect_12k_triangles_bh, intersect_120k_triangles_bh};

    #[test]
    /// Tests whether the building procedure succeeds in not failing.
    fn test_build_bvh() {
        build_some_bh::<BVH>();
    }

    #[test]
    /// Runs some primitive tests for intersections of a ray with a fixed scene given as a BVH.
    fn test_traverse_bvh() {
        traverse_some_bh::<BVH>();
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 1,200 triangles.
    fn bench_build_1200_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_1200_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 12,000 triangles.
    fn bench_build_12k_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_12k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 120,000 triangles.
    fn bench_build_120k_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_120k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 1,200 triangles using the recursive `BVH`.
    fn bench_intersect_1200_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_1200_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 12,000 triangles using the recursive `BVH`.
    fn bench_intersect_12k_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_12k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 120,000 triangles using the recursive `BVH`.
    fn bench_intersect_120k_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_120k_triangles_bh::<BVH>(&mut b);
    }
}
<commit_msg>Add docstring<commit_after>//! This module defines [`BVH`] and [`BVHNode`] and functions for building and traversing it.
//!
//! [`BVH`]: struct.BVH.html
//! [`BVHNode`]: struct.BVHNode.html
//!

use EPSILON;
use aabb::{AABB, Bounded};
use bounding_hierarchy::{BoundingHierarchy, BHShape};
use ray::Ray;
use std::f32;
use std::iter::repeat;

/// The [`BVHNode`] enum that describes a node in a [`BVH`].
/// It's either a leaf node and references a shape (by holding its index)
/// or a regular node that has two child nodes.
/// The non-leaf node stores the [`AABB`]s of its children.
///
/// [`AABB`]: ../aabb/struct.AABB.html
/// [`BVH`]: struct.BVH.html
/// [`BVH`]: struct.BVHNode.html
///
#[derive(Debug, Copy, Clone)]
pub enum BVHNode {
    /// Leaf node.
    Leaf {
        /// The node's parent.
        parent: usize,

        /// The node's depth.
        depth: u32,

        /// The shape contained in this leaf.
        shape: usize,
    },
    /// Inner node.
    Node {
        /// The node's parent.
        parent: usize,

        /// The node's depth.
        depth: u32,

        /// The convex hull of the shapes' `AABB`s in child_l.
        child_l_aabb: AABB,

        /// Index of the left subtree's root node.
        child_l: usize,

        /// The convex hull of the shapes' `AABB`s in child_r.
        child_r_aabb: AABB,

        /// Index of the right subtree's root node.
        child_r: usize,
    },
}

impl BVHNode {
    /// The build function sometimes needs to add nodes while their data is not available yet.
    /// A dummy cerated by this function serves the purpose of being changed later on.
    fn create_dummy() -> BVHNode {
        BVHNode::Leaf {
            parent: 0,
            depth: 0,
            shape: 0,
        }
    }

    /// Builds a [`BVHNode`] recursively using SAH partitioning.
    /// Returns the index of the node in the nodes vector.
    ///
    /// [`BVHNode`]: enum.BVHNode.html
    ///
    pub fn build<T: BHShape>(shapes: &mut [T],
                             indices: Vec<usize>,
                             nodes: &mut Vec<BVHNode>,
                             parent: usize,
                             depth: u32)
                             -> usize {
        // Helper function to accumulate the AABB joint and the centroids AABB
        fn grow_convex_hull(convex_hull: (AABB, AABB), shape_aabb: &AABB) -> (AABB, AABB) {
            let center = &shape_aabb.center();
            let convex_hull_aabbs = &convex_hull.0;
            let convex_hull_centroids = &convex_hull.1;
            (convex_hull_aabbs.join(shape_aabb), convex_hull_centroids.grow(center))
        }

        let mut convex_hull = Default::default();
        for index in &indices {
            convex_hull = grow_convex_hull(convex_hull, &shapes[*index].aabb());
        }
        let (aabb_bounds, centroid_bounds) = convex_hull;

        // If there is only one element left, don't split anymore
        if indices.len() == 1 {
            let shape_index = indices[0];
            nodes.push(BVHNode::Leaf {
                parent: parent,
                depth: depth,
                shape: shape_index,
            });
            let node_index = nodes.len() - 1;
            // Let the shape know the index of the node that represents it
            shapes[shape_index].set_bh_node_index(node_index);
            return node_index;
        }

        // Find the axis along which the shapes are spread the most
        let split_axis = centroid_bounds.largest_axis();
        let split_axis_size = centroid_bounds.max[split_axis] - centroid_bounds.min[split_axis];

        /// Defines a Bucket utility object.
        #[derive(Copy, Clone)]
        struct Bucket {
            size: usize,
            aabb: AABB,
        }

        impl Bucket {
            /// Returns an empty bucket.
            fn empty() -> Bucket {
                Bucket {
                    size: 0,
                    aabb: AABB::empty(),
                }
            }

            /// Extends this `Bucket` by the given `AABB`.
            fn add_aabb(&mut self, aabb: &AABB) {
                self.size += 1;
                self.aabb = self.aabb.join(aabb);
            }
        }

        /// Joins two `Bucket`s.
        fn join_bucket(a: Bucket, b: &Bucket) -> Bucket {
            Bucket {
                size: a.size + b.size,
                aabb: a.aabb.join(&b.aabb),
            }
        }

        // Create six buckets, and six index assignment vectors
        const NUM_BUCKETS: usize = 6;
        let mut buckets = [Bucket::empty(); NUM_BUCKETS];
        let mut bucket_assignments: [Vec<usize>; NUM_BUCKETS] = Default::default();

        if split_axis_size < EPSILON {
            // Spread the remaining shapes evenly across buckets,
            // instead of using a heuristic
            for (counter, idx) in (&indices).iter().enumerate() {
                let shape = &shapes[*idx];
                let shape_aabb = shape.aabb();

                let bucket_num = counter % NUM_BUCKETS;

                buckets[bucket_num].add_aabb(&shape_aabb);
                bucket_assignments[bucket_num].push(*idx);
            }
        } else {
            // Assign each shape to a bucket
            for idx in &indices {
                let shape = &shapes[*idx];
                let shape_aabb = shape.aabb();
                let shape_center = shape_aabb.center();

                // Get the relative position of the shape centroid [0.0..1.0]
                let bucket_num_relative =
                    (shape_center[split_axis] - centroid_bounds.min[split_axis]) / split_axis_size;

                // Convert that to the actual `Bucket` number
                let bucket_num = (bucket_num_relative * (NUM_BUCKETS as f32 - 0.01)) as usize;

                // Extend the selected `Bucket` and add the index to the actual bucket
                buckets[bucket_num].add_aabb(&shape_aabb);
                bucket_assignments[bucket_num].push(*idx);
            }
        }

        // Compute the costs for each configuration and
        // select the configuration with the minimal costs
        let mut min_bucket = 0;
        let mut min_cost = f32::INFINITY;
        let mut child_l_aabb = AABB::empty();
        let mut child_r_aabb = AABB::empty();
        for i in 0..(NUM_BUCKETS - 1) {
            let child_l = buckets.iter().take(i + 1).fold(Bucket::empty(), join_bucket);
            let child_r = buckets.iter().skip(i + 1).fold(Bucket::empty(), join_bucket);

            let cost = (child_l.size as f32 * child_l.aabb.surface_area() +
                        child_r.size as f32 * child_r.aabb.surface_area()) /
                       aabb_bounds.surface_area();

            if cost < min_cost {
                min_bucket = i;
                min_cost = cost;
                child_l_aabb = child_l.aabb;
                child_r_aabb = child_r.aabb;
            }
        }

        // Join together all index buckets, and proceed recursively
        let mut child_l_indices = Vec::new();
        for mut indices in bucket_assignments.iter_mut().take(min_bucket + 1) {
            child_l_indices.append(&mut indices);
        }
        let mut child_r_indices = Vec::new();
        for mut indices in bucket_assignments.iter_mut().skip(min_bucket + 1) {
            child_r_indices.append(&mut indices);
        }

        let node_index = nodes.len();

        nodes.push(BVHNode::create_dummy());

        let child_l = BVHNode::build(shapes, child_l_indices, nodes, node_index, depth + 1);
        let child_r = BVHNode::build(shapes, child_r_indices, nodes, node_index, depth + 1);

        // Construct the actual data structure
        nodes[node_index] = BVHNode::Node {
            parent: parent,
            depth: depth,
            child_l_aabb: child_l_aabb,
            child_l: child_l,
            child_r_aabb: child_r_aabb,
            child_r: child_r,
        };

        node_index
    }

    /// Traverses the [`BVH`] recursively and returns all shapes whose [`AABB`] is
    /// intersected by the given [`Ray`].
    ///
    /// [`AABB`]: ../aabb/struct.AABB.html
    /// [`BVH`]: struct.BVH.html
    /// [`Ray`]: ../ray/struct.Ray.html
    ///
    pub fn traverse_recursive(nodes: &Vec<BVHNode>, node_index: usize, ray: &Ray, indices: &mut Vec<usize>) {
        let node = &nodes[node_index];
        match *node {
            BVHNode::Node { ref child_l_aabb, child_l, ref child_r_aabb, child_r, .. } => {
                if ray.intersects_aabb(child_l_aabb) {
                    BVHNode::traverse_recursive(nodes, child_l, ray, indices);
                }
                if ray.intersects_aabb(child_r_aabb) {
                    BVHNode::traverse_recursive(nodes, child_r, ray, indices);
                }
            }
            BVHNode::Leaf { shape, .. } => {
                indices.push(shape);
            }
        }
    }
}

/// The [`BVH`] data structure. Contains the list of [`BVHNode`]s.
///
/// [`BVH`]: struct.BVH.html
///
pub struct BVH {
    /// The list of nodes of the [`BVH`].
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub nodes: Vec<BVHNode>,
}

impl BVH {
    /// Creates a new [`BVH`] from the `shapes` slice.
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub fn build<Shape: BHShape>(shapes: &mut [Shape]) -> BVH {
        let indices = (0..shapes.len()).collect::<Vec<usize>>();
        let mut nodes = Vec::new();
        BVHNode::build(shapes, indices, &mut nodes, 0, 0);
        BVH { nodes: nodes }
    }

    /// Traverses the [`BVH`].
    /// Returns a subset of `shapes`, in which the [`AABB`]s of the elements were hit by `ray`.
    ///
    /// [`BVH`]: struct.BVH.html
    /// [`AABB`]: ../aabb/struct.AABB.html
    ///
    pub fn traverse<'a, Shape: Bounded>(&'a self, ray: &Ray, shapes: &'a [Shape]) -> Vec<&Shape> {
        let mut indices = Vec::new();
        BVHNode::traverse_recursive(&self.nodes, 0, ray, &mut indices);
        let mut hit_shapes = Vec::new();
        for index in &indices {
            let shape = &shapes[*index];
            hit_shapes.push(shape);
        }
        hit_shapes
    }

    /// Prints the [`BVH`] in a tree-like visualization.
    ///
    /// [`BVH`]: struct.BVH.html
    ///
    pub fn pretty_print(&self) {
        let nodes = &self.nodes;
        fn print_node(nodes: &Vec<BVHNode>, node_index: usize) {
            let node = &nodes[node_index];
            match *node {
                BVHNode::Node { child_l, child_r, depth, child_l_aabb, child_r_aabb, .. } => {
                    let padding: String = repeat(" ").take(depth as usize).collect();
                    println!("{}child_l {:?}", padding, child_l_aabb);
                    print_node(nodes, child_l);
                    println!("{}child_r {:?}", padding, child_r_aabb);
                    print_node(nodes, child_r);
                }
                BVHNode::Leaf { shape, depth, .. } => {
                    let padding: String = repeat(" ").take(depth as usize).collect();
                    println!("{}shape\t{:?}", padding, shape);
                }
            }
        }
        print_node(nodes, 0);
    }
}

impl BoundingHierarchy for BVH {
    fn build<Shape: BHShape>(shapes: &mut [Shape]) -> BVH {
        BVH::build(shapes)
    }

    fn traverse<'a, Shape: Bounded>(&'a self, ray: &Ray, shapes: &'a [Shape]) -> Vec<&Shape> {
        self.traverse(ray, shapes)
    }

    fn pretty_print(&self) {
        self.pretty_print();
    }
}

#[cfg(test)]
pub mod tests {
    use bvh::BVH;
    use testbase::{build_some_bh, traverse_some_bh, build_1200_triangles_bh,
                   build_12k_triangles_bh, build_120k_triangles_bh, intersect_1200_triangles_bh,
                   intersect_12k_triangles_bh, intersect_120k_triangles_bh};

    #[test]
    /// Tests whether the building procedure succeeds in not failing.
    fn test_build_bvh() {
        build_some_bh::<BVH>();
    }

    #[test]
    /// Runs some primitive tests for intersections of a ray with a fixed scene given as a BVH.
    fn test_traverse_bvh() {
        traverse_some_bh::<BVH>();
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 1,200 triangles.
    fn bench_build_1200_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_1200_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 12,000 triangles.
    fn bench_build_12k_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_12k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark the construction of a `BVH` with 120,000 triangles.
    fn bench_build_120k_triangles_bvh(mut b: &mut ::test::Bencher) {
        build_120k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 1,200 triangles using the recursive `BVH`.
    fn bench_intersect_1200_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_1200_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 12,000 triangles using the recursive `BVH`.
    fn bench_intersect_12k_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_12k_triangles_bh::<BVH>(&mut b);
    }

    #[bench]
    /// Benchmark intersecting 120,000 triangles using the recursive `BVH`.
    fn bench_intersect_120k_triangles_bvh(mut b: &mut ::test::Bencher) {
        intersect_120k_triangles_bh::<BVH>(&mut b);
    }
}
<|endoftext|>


<commit_before>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use equation::*;

    // macro_rules! symbol {
    //     ($v:expr, $s:expr) => ( Symbol { val: $v, state: $s } );
    // }

    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🐟", "!🚀"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🐟"]));
        assert!(term.contains(&symbol!["!🚀"]));
    }

    #[test]
    #[allow(unused_variables)]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🐟", "!🚀"];

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🐟"]);
        assert!(! term.contains(&symbol!["🐟"]));

        term.remove(symbol!["!🚀"]);
        assert!(! term.contains(&symbol!["!🚀"]));
    }
}
<commit_msg>Woops. Broke my unit tests :')<commit_after>//! Some unit tests for all the internal functionality of lrs

#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_macros)]
#[allow(unused_imports)]
mod tests {
    use terms::*;
    use clause::*;

    // macro_rules! symbol {
    //     ($v:expr, $s:expr) => ( Symbol { val: $v, state: $s } );
    // }

    #[test]
     fn lrs_symbol_create() {
        let s = symbol!["A"];
        assert!(s.val == 'A');
        assert!(s.state == true);
    }

    #[test]
    fn lrs_term_create() {
        let term = term!["A", "!🐎", "🐟", "!🚀"];

        assert!(term.contains(&symbol!["A"]));
        assert!(term.contains(&symbol!["!🐎"]));
        assert!(term.contains(&symbol!["🐟"]));
        assert!(term.contains(&symbol!["!🚀"]));
    }

    #[test]
    #[allow(unused_variables)]
    fn lrs_term_remove() {
        let mut term = term!["A", "!🐎", "🐟", "!🚀"];

        term.remove(symbol!["A"]);
        assert!(! term.contains(&symbol!["A"]));

        term.remove(symbol!["!🐎"]);
        assert!(! term.contains(&symbol!["!🐎"]));

        term.remove(symbol!["🐟"]);
        assert!(! term.contains(&symbol!["🐟"]));

        term.remove(symbol!["!🚀"]);
        assert!(! term.contains(&symbol!["!🚀"]));
    }
}
<|endoftext|>


<commit_before>// Copyright 2015, Igor Shaula
// Licensed under the MIT License <LICENSE or
// http://opensource.org/licenses/MIT>. This file
// may not be copied, modified, or distributed
// except according to those terms.

//! Traits for loading/saving Registry values
use std::slice;
use std::io;
use super::winapi::winerror;
use super::{RegValue};
use super::enums::*;
use super::{to_utf16,v16_to_v8};

/// A trait for types that can be loaded from registry values.
pub trait FromRegValue : Sized {
    fn from_reg_value(val: &RegValue) -> io::Result<Self>;
}

impl FromRegValue for String {
    fn from_reg_value(val: &RegValue) -> io::Result<String> {
        match val.vtype {
            REG_SZ | REG_EXPAND_SZ | REG_MULTI_SZ => {
                let words = unsafe {
                    let pwords = val.bytes.as_ptr() as *mut [u16; 2048 as usize];
                    *pwords
                };
                let mut s:String = String::from_utf16_lossy(&words[..(val.bytes.len()/2)]);
                while s.ends_with("\u{0}") {s.pop();}
                if val.vtype == REG_MULTI_SZ {
                    return Ok(s.replace("\u{0}", "\n"))
                }
                Ok(s)
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

impl FromRegValue for u32 {
    fn from_reg_value(val: &RegValue) -> io::Result<u32> {
        match val.vtype {
            REG_DWORD => {
                Ok(unsafe{ *(val.bytes.as_ptr() as *const u32) })
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

impl FromRegValue for u64 {
    fn from_reg_value(val: &RegValue) -> io::Result<u64> {
        match val.vtype {
            REG_QWORD => {
                Ok(unsafe{ *(val.bytes.as_ptr() as *const u64) })
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

/// A trait for types that can be written into registry values.
pub trait ToRegValue {
    fn to_reg_value(&self) -> RegValue;
}

impl ToRegValue for String {
    fn to_reg_value(&self) -> RegValue {
        RegValue{
            bytes: v16_to_v8(&to_utf16(self)),
            vtype: REG_SZ
        }
    }
}

impl<'a> ToRegValue for &'a str {
    fn to_reg_value(&self) -> RegValue {
        RegValue{
            bytes: v16_to_v8(&to_utf16(self)),
            vtype: REG_SZ
        }
    }
}

impl ToRegValue for u32 {
    fn to_reg_value(&self) -> RegValue {
        let bytes: Vec<u8> = unsafe {
            slice::from_raw_parts((self as *const u32) as *const u8, 4).to_vec()
        };
        RegValue{
            bytes: bytes,
            vtype: REG_DWORD
        }
    }
}

impl ToRegValue for u64 {
    fn to_reg_value(&self) -> RegValue {
        let bytes: Vec<u8> = unsafe {
            slice::from_raw_parts((self as *const u64) as *const u8, 8).to_vec()
        };
        RegValue{
            bytes: bytes,
            vtype: REG_QWORD
        }
    }
}
<commit_msg>Fix a crash in RegValue to String conversion<commit_after>// Copyright 2015, Igor Shaula
// Licensed under the MIT License <LICENSE or
// http://opensource.org/licenses/MIT>. This file
// may not be copied, modified, or distributed
// except according to those terms.

//! Traits for loading/saving Registry values
use std::slice;
use std::io;
use super::winapi::winerror;
use super::{RegValue};
use super::enums::*;
use super::{to_utf16,v16_to_v8};

/// A trait for types that can be loaded from registry values.
pub trait FromRegValue : Sized {
    fn from_reg_value(val: &RegValue) -> io::Result<Self>;
}

impl FromRegValue for String {
    fn from_reg_value(val: &RegValue) -> io::Result<String> {
        match val.vtype {
            REG_SZ | REG_EXPAND_SZ | REG_MULTI_SZ => {
                let words = unsafe {
                    slice::from_raw_parts(val.bytes.as_ptr() as *const u16, val.bytes.len() / 2)
                };
                let mut s = String::from_utf16_lossy(words);
                while s.ends_with("\u{0}") {s.pop();}
                if val.vtype == REG_MULTI_SZ {
                    return Ok(s.replace("\u{0}", "\n"))
                }
                Ok(s)
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

impl FromRegValue for u32 {
    fn from_reg_value(val: &RegValue) -> io::Result<u32> {
        match val.vtype {
            REG_DWORD => {
                Ok(unsafe{ *(val.bytes.as_ptr() as *const u32) })
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

impl FromRegValue for u64 {
    fn from_reg_value(val: &RegValue) -> io::Result<u64> {
        match val.vtype {
            REG_QWORD => {
                Ok(unsafe{ *(val.bytes.as_ptr() as *const u64) })
            },
            _ => werr!(winerror::ERROR_BAD_FILE_TYPE)
        }
    }
}

/// A trait for types that can be written into registry values.
pub trait ToRegValue {
    fn to_reg_value(&self) -> RegValue;
}

impl ToRegValue for String {
    fn to_reg_value(&self) -> RegValue {
        RegValue{
            bytes: v16_to_v8(&to_utf16(self)),
            vtype: REG_SZ
        }
    }
}

impl<'a> ToRegValue for &'a str {
    fn to_reg_value(&self) -> RegValue {
        RegValue{
            bytes: v16_to_v8(&to_utf16(self)),
            vtype: REG_SZ
        }
    }
}

impl ToRegValue for u32 {
    fn to_reg_value(&self) -> RegValue {
        let bytes: Vec<u8> = unsafe {
            slice::from_raw_parts((self as *const u32) as *const u8, 4).to_vec()
        };
        RegValue{
            bytes: bytes,
            vtype: REG_DWORD
        }
    }
}

impl ToRegValue for u64 {
    fn to_reg_value(&self) -> RegValue {
        let bytes: Vec<u8> = unsafe {
            slice::from_raw_parts((self as *const u64) as *const u8, 8).to_vec()
        };
        RegValue{
            bytes: bytes,
            vtype: REG_QWORD
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 GFX developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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 cocoa_foundation::foundation::NSUInteger;
use std::default::Default;

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLOrigin {
    pub x: NSUInteger,
    pub y: NSUInteger,
    pub z: NSUInteger,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLSize {
    pub width: NSUInteger,
    pub height: NSUInteger,
    pub depth: NSUInteger,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLRegion {
    pub origin: MTLOrigin,
    pub size: MTLSize,
}

impl MTLRegion {
    pub fn new_1d(x: NSUInteger, width: NSUInteger) -> Self {
        Self::new_2d(x, 0, width, 1)
    }

    #[inline]
    pub fn new_2d(x: NSUInteger, y: NSUInteger, width: NSUInteger, height: NSUInteger) -> Self {
        Self::new_3d(x, y, 0, width, height, 1)
    }

    #[inline]
    pub fn new_3d(
        x: NSUInteger,
        y: NSUInteger,
        z: NSUInteger,
        width: NSUInteger,
        height: NSUInteger,
        depth: NSUInteger,
    ) -> Self {
        Self {
            origin: MTLOrigin { x, y, z },
            size: MTLSize {
                width,
                height,
                depth,
            },
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MTLSamplePosition {
    pub x: f32,
    pub y: f32,
}
<commit_msg>added derives to mtlsampleposition<commit_after>// Copyright 2016 GFX developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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 cocoa_foundation::foundation::NSUInteger;
use std::default::Default;

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLOrigin {
    pub x: NSUInteger,
    pub y: NSUInteger,
    pub z: NSUInteger,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLSize {
    pub width: NSUInteger,
    pub height: NSUInteger,
    pub depth: NSUInteger,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub struct MTLRegion {
    pub origin: MTLOrigin,
    pub size: MTLSize,
}

impl MTLRegion {
    pub fn new_1d(x: NSUInteger, width: NSUInteger) -> Self {
        Self::new_2d(x, 0, width, 1)
    }

    #[inline]
    pub fn new_2d(x: NSUInteger, y: NSUInteger, width: NSUInteger, height: NSUInteger) -> Self {
        Self::new_3d(x, y, 0, width, height, 1)
    }

    #[inline]
    pub fn new_3d(
        x: NSUInteger,
        y: NSUInteger,
        z: NSUInteger,
        width: NSUInteger,
        height: NSUInteger,
        depth: NSUInteger,
    ) -> Self {
        Self {
            origin: MTLOrigin { x, y, z },
            size: MTLSize {
                width,
                height,
                depth,
            },
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub struct MTLSamplePosition {
    pub x: f32,
    pub y: f32,
}
<|endoftext|>


<commit_before>use ffi::prelude::LLVMTypeRef;
use ffi::{core, target, LLVMTypeKind};
use libc::{c_int, c_uint};
use compile::Compile;
use context::{Context, GetContext};
use target::TargetData;
use util::{self, Sub};
use std::{fmt, mem};
use std::marker::PhantomData;
use std::iter::Iterator;
use std::ops::Deref;

macro_rules! sub {
    ($ty:ty, $kind:ident) => (
unsafe impl Sub<::Type> for $ty {
    fn is(ty: &Type) -> bool {
        unsafe {
            let kind = core::LLVMGetTypeKind(ty.into());
            kind as c_uint == LLVMTypeKind::$kind as c_uint
        }
    }
}
deref!{$ty, Type}
    )
}

/// Defines how a value should be laid out in memory.
pub struct Type(PhantomData<[u8]>);
native_ref!{&Type = LLVMTypeRef}
get_context!{Type, LLVMGetTypeContext}
to_str!{Type, LLVMPrintTypeToString}
impl Type {
    #[inline(always)]
    /// Get the type given as an LLVM type descriptor in the context given.
    pub fn get<'a, T>(context:&'a Context) -> &'a Type where T:Compile<'a> {
        T::get_type(context)
    }
    /// Returns true if the size of the type is known at compile-time.
    ///
    /// This is equivalent to the type implementing `Sized` in Rust
    pub fn is_sized(&self) -> bool {
        unsafe { core::LLVMTypeIsSized(self.into()) != 0 }
    }
    /// Returns true if this type is a function.
    ///
    /// This is equivalent to `FunctionType::is`.
    pub fn is_function(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
    }
    /// Returns true if this type is a struct.
    ///
    /// This is equivalent to `StructType::is`.
    pub fn is_struct(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint
    }
    /// Returns true if this type is void.
    pub fn is_void(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMVoidTypeKind as c_uint
    }
    /// Returns true if this type is a pointer.
    ///
    /// This is equivalent to `PointerType::is`.
    pub fn is_pointer(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMPointerTypeKind as c_uint
    }
    /// Returns true if this type is an integer.
    pub fn is_integer(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMIntegerTypeKind as c_uint
    }
    /// Returns true if this type is any floating-point number.
    pub fn is_float(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) } as c_uint;
        kind == LLVMTypeKind::LLVMHalfTypeKind as c_uint ||
        kind == LLVMTypeKind::LLVMFloatTypeKind as c_uint ||
        kind == LLVMTypeKind::LLVMDoubleTypeKind as c_uint
    }
    /// Returns the size of the type in bytes.
    pub fn get_size(&self, target: &TargetData) -> usize {
        unsafe { target::LLVMABISizeOfType(target.into(), self.into()) as usize }
    }
}

/// A structure type, such as a tuple or struct.
pub struct StructType(PhantomData<[u8]>);
native_ref!{&StructType = LLVMTypeRef}
get_context!{StructType, LLVMGetTypeContext}
to_str!{StructType, LLVMPrintTypeToString}
sub!{StructType, LLVMStructTypeKind}
impl StructType {
    /// Make a new struct with the given fields and packed representation.
    pub fn new<'a>(context: &'a Context, fields: &[&'a Type], packed: bool) -> &'a StructType {
        unsafe { core::LLVMStructTypeInContext(context.into(), fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int) }.into()
    }
    /// Make a new named struct with the given fields and packed representation.
    pub fn new_named<'a>(context: &'a Context, name: &str, fields: &[&'a Type], packed: bool) -> &'a StructType {
        util::with_cstr(name, |name| unsafe {
            let ty = core::LLVMStructCreateNamed(context.into(), name);
            core::LLVMStructSetBody(ty, fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int);
            ty.into()
        })
    }
    /// Returns the elements that make up this struct.
    pub fn get_elements(&self) -> Vec<&Type> {
        unsafe {
            let size = core::LLVMCountStructElementTypes(self.into());
            let mut els:Vec<_> = (0..size).map(|_| mem::uninitialized()).collect();
            core::LLVMGetStructElementTypes(self.into(), els.as_mut_ptr() as *mut LLVMTypeRef);
            els
        }
    }
}

/// A function signature type.
pub struct FunctionType(PhantomData<[u8]>);
native_ref!{&FunctionType = LLVMTypeRef}
get_context!{FunctionType, LLVMGetTypeContext}
to_str!{FunctionType, LLVMPrintTypeToString}
deref!{FunctionType, Type}
unsafe impl Sub<Type> for FunctionType {
    fn is(mut ty: &Type) -> bool {
        unsafe {
            while let Some(ptr) = PointerType::from_super(ty) {
                ty = ptr.get_element();
            }
            let kind = core::LLVMGetTypeKind(ty.into());
            kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
        }
    }
}
impl FunctionType {
    /// Make a new function signature with the return type and arguments given.
    pub fn new<'a>(ret: &'a Type, args: &[&'a Type]) -> &'a FunctionType {
        unsafe { core::LLVMFunctionType(ret.into(), args.as_ptr() as *mut LLVMTypeRef, args.len() as c_uint, 0) }.into()
    }
    /// Returns the number of parameters this signature takes.
    pub fn num_params(&self) -> usize {
        unsafe { core::LLVMCountParamTypes(self.into()) as usize }
    }
    /// Returns a vector of this signature's parameters' types.
    pub fn get_params(&self) -> Vec<&Type> {
        unsafe {
            let count = core::LLVMCountParamTypes(self.into());
            let mut types:Vec<_> = (0..count).map(|_| mem::uninitialized()).collect();
            core::LLVMGetParamTypes(self.into(), types.as_mut_ptr() as *mut LLVMTypeRef);
            types
        }
    }
    /// Returns the type that this function returns.
    pub fn get_return(&self) -> &Type {
        unsafe { core::LLVMGetReturnType(self.into()).into() }
    }
}

/// A pointer type.
pub struct PointerType(PhantomData<[u8]>);
native_ref!{&PointerType = LLVMTypeRef}
get_context!{PointerType, LLVMGetTypeContext}
to_str!{PointerType, LLVMPrintTypeToString}
sub!{PointerType, LLVMPointerTypeKind}
impl PointerType {
    /// Make a new pointer type with the given element type.
    pub fn new(elem: &Type) -> &Type {
        unsafe { core::LLVMPointerType(elem.into(), 0 as c_uint) }.into()
    }
    /// Returns the element of this pointer type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
}

/// An integer type.
pub struct IntegerType(PhantomData<[u8]>);
native_ref!{&IntegerType = LLVMTypeRef}
get_context!{IntegerType, LLVMGetTypeContext}
to_str!{IntegerType, LLVMPrintTypeToString}
sub!{IntegerType, LLVMPointerTypeKind}
impl IntegerType {
    /// Make a new integer type that will be the size of the given number of bits.
    pub fn new(context: &Context, numbits: usize) -> &IntegerType {
        unsafe { core::LLVMIntTypeInContext(context.into(), numbits as c_uint) }.into()
    }
    /// Returns how long an integer of this type is, in bits.
    pub fn get_width(&self) -> usize {
        unsafe { core::LLVMGetIntTypeWidth (self.into()) as usize }
    }
}

/// A vector type.
pub struct VectorType(PhantomData<[u8]>);
native_ref!{&VectorType = LLVMTypeRef}
get_context!{VectorType, LLVMGetTypeContext}
to_str!{VectorType, LLVMPrintTypeToString}
sub!{VectorType, LLVMVectorTypeKind}
impl VectorType {
    /// Make a new vector type with the length given.
    pub fn new(element: &Type, length: usize) -> &VectorType {
        unsafe { core::LLVMVectorType(element.into(), length as c_uint) }.into()
    }
    /// Returns the element type of this vector type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
    /// Returns the number of elements in this vector type.
    pub fn get_size(&self) -> usize {
        unsafe { core::LLVMGetVectorSize(self.into()) as usize }
    }
}
/// An array type.
pub struct ArrayType(PhantomData<[u8]>);
native_ref!{&ArrayType = LLVMTypeRef}
get_context!{ArrayType, LLVMGetTypeContext}
to_str!{ArrayType, LLVMPrintTypeToString}
sub!{ArrayType, LLVMArrayTypeKind}
impl ArrayType {
    /// Make a new array type with the length given.
    pub fn new(element: &Type, length: usize) -> &ArrayType {
        unsafe { core::LLVMArrayType(element.into(), length as c_uint) }.into()
    }
    /// Returns the element type of this array type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
    /// Returns the number of elements in this vector type.
    pub fn get_length(&self) -> usize {
        unsafe { core::LLVMGetArrayLength(self.into()) as usize }
    }
}<commit_msg>add support for opaque structs (allowing recursive types to be defined)<commit_after>use ffi::prelude::LLVMTypeRef;
use ffi::{core, target, LLVMTypeKind};
use libc::{c_int, c_uint};
use compile::Compile;
use context::{Context, GetContext};
use target::TargetData;
use util::{self, Sub};
use std::{fmt, mem};
use std::marker::PhantomData;
use std::iter::Iterator;
use std::ops::Deref;

macro_rules! sub {
    ($ty:ty, $kind:ident) => (
unsafe impl Sub<::Type> for $ty {
    fn is(ty: &Type) -> bool {
        unsafe {
            let kind = core::LLVMGetTypeKind(ty.into());
            kind as c_uint == LLVMTypeKind::$kind as c_uint
        }
    }
}
deref!{$ty, Type}
    )
}

/// Defines how a value should be laid out in memory.
pub struct Type(PhantomData<[u8]>);
native_ref!{&Type = LLVMTypeRef}
get_context!{Type, LLVMGetTypeContext}
to_str!{Type, LLVMPrintTypeToString}
impl Type {
    #[inline(always)]
    /// Get the type given as an LLVM type descriptor in the context given.
    pub fn get<'a, T>(context:&'a Context) -> &'a Type where T:Compile<'a> {
        T::get_type(context)
    }
    /// Returns true if the size of the type is known at compile-time.
    ///
    /// This is equivalent to the type implementing `Sized` in Rust
    pub fn is_sized(&self) -> bool {
        unsafe { core::LLVMTypeIsSized(self.into()) != 0 }
    }
    /// Returns true if this type is a function.
    ///
    /// This is equivalent to `FunctionType::is`.
    pub fn is_function(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
    }
    /// Returns true if this type is a struct.
    ///
    /// This is equivalent to `StructType::is`.
    pub fn is_struct(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMStructTypeKind as c_uint
    }
    /// Returns true if this type is void.
    pub fn is_void(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMVoidTypeKind as c_uint
    }
    /// Returns true if this type is a pointer.
    ///
    /// This is equivalent to `PointerType::is`.
    pub fn is_pointer(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMPointerTypeKind as c_uint
    }
    /// Returns true if this type is an integer.
    pub fn is_integer(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) };
        kind as c_uint == LLVMTypeKind::LLVMIntegerTypeKind as c_uint
    }
    /// Returns true if this type is any floating-point number.
    pub fn is_float(&self) -> bool {
        let kind = unsafe { core::LLVMGetTypeKind(self.into()) } as c_uint;
        kind == LLVMTypeKind::LLVMHalfTypeKind as c_uint ||
        kind == LLVMTypeKind::LLVMFloatTypeKind as c_uint ||
        kind == LLVMTypeKind::LLVMDoubleTypeKind as c_uint
    }
    /// Returns the size of the type in bytes.
    pub fn get_size(&self, target: &TargetData) -> usize {
        unsafe { target::LLVMABISizeOfType(target.into(), self.into()) as usize }
    }
}

/// A structure type, such as a tuple or struct.
pub struct StructType(PhantomData<[u8]>);
native_ref!{&StructType = LLVMTypeRef}
get_context!{StructType, LLVMGetTypeContext}
to_str!{StructType, LLVMPrintTypeToString}
sub!{StructType, LLVMStructTypeKind}
impl StructType {
    /// Make a new struct with the given fields and packed representation.
    pub fn new<'a>(context: &'a Context, fields: &[&'a Type], packed: bool) -> &'a StructType {
        unsafe { core::LLVMStructTypeInContext(context.into(), fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int) }.into()
    }
    /// Make a new named struct with the given fields and packed representation.
    pub fn new_named<'a>(context: &'a Context, name: &str, fields: &[&'a Type], packed: bool) -> &'a StructType {
        util::with_cstr(name, |name| unsafe {
            let ty = core::LLVMStructCreateNamed(context.into(), name);
            core::LLVMStructSetBody(ty, fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int);
            ty.into()
        })
    }
    /// Make a new named struct without defining its fields yet.
    ///
    /// You can use this opaque struct without defining its fields (for creating recursive types, etc.). When you want to define its fields (which may include itself), use set_elements().
    pub fn new_opaque<'a>(context: &'a Context, name: &str) -> &'a StructType {
        util::with_cstr(name, |name| unsafe {
            core::LLVMStructCreateNamed(context.into(), name).into()
        })
    }
    /// Set the elements that make up this struct.
    ///
    /// Can only be called once, and only on a StructType created through the new_opaque() function.
    /// Returns Err(()) if the struct is not opaque.
    pub fn set_elements<'a>(&self, fields: &[&'a Type], packed: bool) -> Result<(), ()> {
        unsafe {
            if core::LLVMIsOpaqueStruct(self.into()) != 0 {
                core::LLVMStructSetBody(self.into(), fields.as_ptr() as *mut LLVMTypeRef, fields.len() as c_uint, packed as c_int);
                Ok(())
            } else {
                Err(())
            }
        }
    }
    /// Returns the elements that make up this struct.
    pub fn get_elements(&self) -> Vec<&Type> {
        unsafe {
            let size = core::LLVMCountStructElementTypes(self.into());
            let mut els:Vec<_> = (0..size).map(|_| mem::uninitialized()).collect();
            core::LLVMGetStructElementTypes(self.into(), els.as_mut_ptr() as *mut LLVMTypeRef);
            els
        }
    }
}

/// A function signature type.
pub struct FunctionType(PhantomData<[u8]>);
native_ref!{&FunctionType = LLVMTypeRef}
get_context!{FunctionType, LLVMGetTypeContext}
to_str!{FunctionType, LLVMPrintTypeToString}
deref!{FunctionType, Type}
unsafe impl Sub<Type> for FunctionType {
    fn is(mut ty: &Type) -> bool {
        unsafe {
            while let Some(ptr) = PointerType::from_super(ty) {
                ty = ptr.get_element();
            }
            let kind = core::LLVMGetTypeKind(ty.into());
            kind as c_uint == LLVMTypeKind::LLVMFunctionTypeKind as c_uint
        }
    }
}
impl FunctionType {
    /// Make a new function signature with the return type and arguments given.
    pub fn new<'a>(ret: &'a Type, args: &[&'a Type]) -> &'a FunctionType {
        unsafe { core::LLVMFunctionType(ret.into(), args.as_ptr() as *mut LLVMTypeRef, args.len() as c_uint, 0) }.into()
    }
    /// Returns the number of parameters this signature takes.
    pub fn num_params(&self) -> usize {
        unsafe { core::LLVMCountParamTypes(self.into()) as usize }
    }
    /// Returns a vector of this signature's parameters' types.
    pub fn get_params(&self) -> Vec<&Type> {
        unsafe {
            let count = core::LLVMCountParamTypes(self.into());
            let mut types:Vec<_> = (0..count).map(|_| mem::uninitialized()).collect();
            core::LLVMGetParamTypes(self.into(), types.as_mut_ptr() as *mut LLVMTypeRef);
            types
        }
    }
    /// Returns the type that this function returns.
    pub fn get_return(&self) -> &Type {
        unsafe { core::LLVMGetReturnType(self.into()).into() }
    }
}

/// A pointer type.
pub struct PointerType(PhantomData<[u8]>);
native_ref!{&PointerType = LLVMTypeRef}
get_context!{PointerType, LLVMGetTypeContext}
to_str!{PointerType, LLVMPrintTypeToString}
sub!{PointerType, LLVMPointerTypeKind}
impl PointerType {
    /// Make a new pointer type with the given element type.
    pub fn new(elem: &Type) -> &Type {
        unsafe { core::LLVMPointerType(elem.into(), 0 as c_uint) }.into()
    }
    /// Returns the element of this pointer type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
}

/// An integer type.
pub struct IntegerType(PhantomData<[u8]>);
native_ref!{&IntegerType = LLVMTypeRef}
get_context!{IntegerType, LLVMGetTypeContext}
to_str!{IntegerType, LLVMPrintTypeToString}
sub!{IntegerType, LLVMPointerTypeKind}
impl IntegerType {
    /// Make a new integer type that will be the size of the given number of bits.
    pub fn new(context: &Context, numbits: usize) -> &IntegerType {
        unsafe { core::LLVMIntTypeInContext(context.into(), numbits as c_uint) }.into()
    }
    /// Returns how long an integer of this type is, in bits.
    pub fn get_width(&self) -> usize {
        unsafe { core::LLVMGetIntTypeWidth (self.into()) as usize }
    }
}

/// A vector type.
pub struct VectorType(PhantomData<[u8]>);
native_ref!{&VectorType = LLVMTypeRef}
get_context!{VectorType, LLVMGetTypeContext}
to_str!{VectorType, LLVMPrintTypeToString}
sub!{VectorType, LLVMVectorTypeKind}
impl VectorType {
    /// Make a new vector type with the length given.
    pub fn new(element: &Type, length: usize) -> &VectorType {
        unsafe { core::LLVMVectorType(element.into(), length as c_uint) }.into()
    }
    /// Returns the element type of this vector type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
    /// Returns the number of elements in this vector type.
    pub fn get_size(&self) -> usize {
        unsafe { core::LLVMGetVectorSize(self.into()) as usize }
    }
}
/// An array type.
pub struct ArrayType(PhantomData<[u8]>);
native_ref!{&ArrayType = LLVMTypeRef}
get_context!{ArrayType, LLVMGetTypeContext}
to_str!{ArrayType, LLVMPrintTypeToString}
sub!{ArrayType, LLVMArrayTypeKind}
impl ArrayType {
    /// Make a new array type with the length given.
    pub fn new(element: &Type, length: usize) -> &ArrayType {
        unsafe { core::LLVMArrayType(element.into(), length as c_uint) }.into()
    }
    /// Returns the element type of this array type.
    pub fn get_element(&self) -> &Type {
        unsafe { mem::transmute(core::LLVMGetElementType(self.into())) }
    }
    /// Returns the number of elements in this vector type.
    pub fn get_length(&self) -> usize {
        unsafe { core::LLVMGetArrayLength(self.into()) as usize }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::net::SocketAddr;
use std::rc::{Rc, Weak};
use std::cell::RefCell;

use mioco::udp::UdpSocket;
use mioco::sync::mpsc::{channel, Receiver, Sender};
use bincode::rustc_serialize as bcode_rcs;
use sodiumoxide::crypto::secretbox as crypto_secretbox;

use ::Result;
use identity::{Identity, RemoteServer, Extension};
use packet::*;
use keys::*;
use boxes::*;
use nonces::*;

pub struct Stream {

}

impl Stream {
    pub fn new() -> Stream {
        Stream {}
    }
}

pub struct Demultiplexor {
    sock: UdpSocket,
    listeners: HashMap<Extension, Weak<RefCell<Listener>>>,
}

impl Demultiplexor {
    pub fn new(sock: UdpSocket) -> Demultiplexor {
        Demultiplexor {
            sock: sock,
            listeners: HashMap::new(),
        }
    }

    pub fn create_listener(&mut self, listener_id: Identity) -> Rc<RefCell<Listener>> {
        let listener_extension = listener_id.extension.clone();
        let listener = Rc::new(RefCell::new(Listener::new(listener_id)));

        self.listeners.insert(listener_extension, Rc::downgrade(&listener));

        listener
    }

    pub fn listen(&mut self) -> Result<()> {
        let mut buf = [0u8; PACKET_MAX_SIZE];
        loop {
            let (recv_len, rem_addr) = try!(self.sock.recv(&mut buf));
            let packet: Packet = try!(bcode_rcs::decode(&buf[..recv_len]));

            if let Some(ref mut listener) = {
                let dst_extension = packet.get_destination_extension();
                self.listeners.get_mut(dst_extension).and_then(|listener_weak|
                    listener_weak.upgrade()
                )
            } {
                try!(listener.borrow_mut().process(packet, &mut self.sock, rem_addr));
            }
        }
    }
}

pub struct ServerSocket {
    recv_rx: Receiver<Vec<u8>>,
    sock: UdpSocket,
    rem_addr: SocketAddr,
    client_extension: Extension,
    my_extension: Extension,
    precomputed_key: PrecomputedKey,
    next_send_nonce: Nonce8,
}

struct ServerConnection {
    precomputed_key: PrecomputedKey,
    recv_tx: Sender<Vec<u8>>,
    last_recv_nonce: Nonce8,
}

pub struct Listener {
    my_extension: Extension,
    my_long_term_pk: server_long_term::PublicKey,
    my_long_term_sk: server_long_term::SecretKey,
    minute_key: crypto_secretbox::Key,
    last_minute_key: crypto_secretbox::Key,
    conns: HashMap<(Extension, client_short_term::PublicKey), ServerConnection>,
    accept_chan_tx: Sender<ServerSocket>,
    accept_chan_rx: Receiver<ServerSocket>,
}

impl Listener {
    fn new(my_id: Identity) -> Listener {
        let (my_long_term_pk, my_long_term_sk, my_extension) = my_id.as_server();
        let (accept_chan_tx, accept_chan_rx) = channel();

        Listener {
            my_extension: my_extension,
            my_long_term_pk: my_long_term_pk,
            my_long_term_sk: my_long_term_sk,
            minute_key: crypto_secretbox::gen_key(),
            last_minute_key: crypto_secretbox::gen_key(),
            conns: HashMap::new(),
            accept_chan_tx: accept_chan_tx,
            accept_chan_rx: accept_chan_rx,
        }
    }

    pub fn accept(&mut self) -> Result<ServerSocket> {
        self.accept_chan_rx.recv().or(Err("Couldnt read accept channel".into()))
    }

    pub fn process(&mut self, packet: Packet, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        match packet {
            Packet::ClientMessage(client_msg_packet) => {
                let mut preserve = true;
                let conn_key = (client_msg_packet.client_extension.clone(),
                                client_msg_packet.client_short_term_pk.clone());

                if let Some(server_conn) = self.conns.get_mut(&conn_key) {
                    let send_res = server_conn.recv_tx.send(vec![]);
                    preserve = send_res.is_ok();
                }

                if !preserve {
                    self.conns.remove(&conn_key);
                }
            },
            Packet::Initiate(initiate_packet) => {
                try!(self.process_initiate(initiate_packet, sock, rem_addr));
            },
            Packet::Hello(hello_packet) => {
                try!(self.process_hello(hello_packet, sock, rem_addr));
            },
            _ => {
                debug!("Unvalid packet type");
            }
        }

        Ok(())
    }

    fn process_hello(&self, hello_packet: HelloPacket, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        let client_short_term_pk = hello_packet.client_short_term_pk;
        let conn_key = (hello_packet.client_extension.clone(), client_short_term_pk.clone());

        if self.conns.contains_key(&conn_key) {
            debug!("Hello packet received on open connection");
            return Ok(());
        }

        hello_packet.hello_box.open(&client_short_term_pk, &self.my_long_term_sk).unwrap();

        let (server_short_term_pk, server_short_term_sk) = server_short_term::gen_keypair();

        let cookie_packet: Packet = CookiePacket {
            client_extension: hello_packet.client_extension.clone(),
            server_extension: self.my_extension.clone(),
            cookie_box: PlainCookieBox {
                server_short_term_pk: server_short_term_pk,
                server_cookie: PlainCookie {
                    client_short_term_pk: client_short_term_pk.clone(),
                    server_short_term_sk: server_short_term_sk.clone(),
                }.seal(&CookieNonce::new_random(), &self.minute_key),
            }.seal(&Nonce16::new_random(), &client_short_term_pk, &self.my_long_term_sk),
        }.into();

        try!(cookie_packet.send(sock, &rem_addr));

        Ok(())
    }

    fn process_initiate(&mut self, initiate_packet: InitiatePacket, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        let conn_key = (initiate_packet.client_extension.clone(), initiate_packet.client_short_term_pk.clone());

        if self.conns.contains_key(&conn_key) {
            debug!("Recv'd INITIATE on already initiated connection");
            return Ok(());
        }

        let cookie = initiate_packet.server_cookie.open(&self.minute_key, &self.last_minute_key).unwrap();
        let precomputed_key = PrecomputedKey::precompute_at_server(&initiate_packet.client_short_term_pk, &cookie.server_short_term_sk);
        let (initiate_box, payload) = initiate_packet.initiate_box.open_precomputed_with_payload(&precomputed_key).unwrap();

        let client_long_term_pk = initiate_box.client_long_term_pk;
        let vouch = initiate_box.vouch.open(&client_long_term_pk, &self.my_long_term_sk).unwrap();

        if vouch.client_short_term_pk != initiate_packet.client_short_term_pk {
            return try!(Err("Invalid vouch"));
        }

        //TODO: Check if client_long_term_pk is accepted

        let (recv_tx, recv_rx) = channel();

        if let Some(msg) = payload {
            recv_tx.send(msg).unwrap();
        }

        let new_conn = ServerConnection {
            precomputed_key: precomputed_key.clone(),
            recv_tx: recv_tx,
            last_recv_nonce: initiate_packet.initiate_box.nonce.clone(),
        };

        self.conns.insert(conn_key, new_conn);
        info!("\"{}\" accepting connection \"{}\"@{}", &self.my_extension, &initiate_packet.client_extension, &rem_addr);

        let new_sock = ServerSocket {
            recv_rx: recv_rx,
            sock: sock.try_clone().unwrap(),
            rem_addr: rem_addr,
            client_extension: initiate_packet.client_extension.clone(),
            my_extension: self.my_extension.clone(),
            precomputed_key: precomputed_key,
            next_send_nonce: Nonce8::new_low(),
        };

        self.accept_chan_tx.send(new_sock).or(Err("Couldnt read accept channel".into()))
    }
}
<commit_msg>Correctly processing ClientMsg<commit_after>use std::collections::HashMap;
use std::net::SocketAddr;
use std::rc::{Rc, Weak};
use std::cell::RefCell;

use mioco::udp::UdpSocket;
use mioco::sync::mpsc::{channel, Receiver, Sender};
use bincode::rustc_serialize as bcode_rcs;
use sodiumoxide::crypto::secretbox as crypto_secretbox;

use ::Result;
use identity::{Identity, RemoteServer, Extension};
use packet::*;
use keys::*;
use boxes::*;
use nonces::*;

pub struct Stream {

}

impl Stream {
    pub fn new() -> Stream {
        Stream {}
    }
}

pub struct Demultiplexor {
    sock: UdpSocket,
    listeners: HashMap<Extension, Weak<RefCell<Listener>>>,
}

impl Demultiplexor {
    pub fn new(sock: UdpSocket) -> Demultiplexor {
        Demultiplexor {
            sock: sock,
            listeners: HashMap::new(),
        }
    }

    pub fn create_listener(&mut self, listener_id: Identity) -> Rc<RefCell<Listener>> {
        let listener_extension = listener_id.extension.clone();
        let listener = Rc::new(RefCell::new(Listener::new(listener_id)));

        self.listeners.insert(listener_extension, Rc::downgrade(&listener));

        listener
    }

    pub fn listen(&mut self) -> Result<()> {
        let mut buf = [0u8; PACKET_MAX_SIZE];
        loop {
            let (recv_len, rem_addr) = try!(self.sock.recv(&mut buf));
            let packet: Packet = try!(bcode_rcs::decode(&buf[..recv_len]));

            if let Some(ref mut listener) = {
                let dst_extension = packet.get_destination_extension();
                self.listeners.get_mut(dst_extension).and_then(|listener_weak|
                    listener_weak.upgrade()
                )
            } {
                try!(listener.borrow_mut().process(packet, &mut self.sock, rem_addr));
            }
        }
    }
}

pub struct ServerSocket {
    recv_rx: Receiver<Vec<u8>>,
    sock: UdpSocket,
    rem_addr: SocketAddr,
    client_extension: Extension,
    my_extension: Extension,
    precomputed_key: PrecomputedKey,
    next_send_nonce: Nonce8,
}

pub struct Listener {
    my_extension: Extension,
    my_long_term_pk: server_long_term::PublicKey,
    my_long_term_sk: server_long_term::SecretKey,
    minute_key: crypto_secretbox::Key,
    last_minute_key: crypto_secretbox::Key,
    conns: HashMap<(Extension, client_short_term::PublicKey), ServerConnection>,
    accept_chan_tx: Sender<ServerSocket>,
    accept_chan_rx: Receiver<ServerSocket>,
}

impl Listener {
    fn new(my_id: Identity) -> Listener {
        let (my_long_term_pk, my_long_term_sk, my_extension) = my_id.as_server();
        let (accept_chan_tx, accept_chan_rx) = channel();

        Listener {
            my_extension: my_extension,
            my_long_term_pk: my_long_term_pk,
            my_long_term_sk: my_long_term_sk,
            minute_key: crypto_secretbox::gen_key(),
            last_minute_key: crypto_secretbox::gen_key(),
            conns: HashMap::new(),
            accept_chan_tx: accept_chan_tx,
            accept_chan_rx: accept_chan_rx,
        }
    }

    pub fn accept(&mut self) -> Result<ServerSocket> {
        self.accept_chan_rx.recv().or(Err("Couldnt read accept channel".into()))
    }

    pub fn process(&mut self, packet: Packet, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        match packet {
            Packet::ClientMessage(client_msg_packet) => {
                try!(self.process_client_msg(client_msg_packet, sock, rem_addr));
            },
            Packet::Initiate(initiate_packet) => {
                try!(self.process_initiate(initiate_packet, sock, rem_addr));
            },
            Packet::Hello(hello_packet) => {
                try!(self.process_hello(hello_packet, sock, rem_addr));
            },
            _ => {
                debug!("Unvalid packet type");
            }
        }

        Ok(())
    }

    fn process_hello(&self, hello_packet: HelloPacket, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        let client_short_term_pk = hello_packet.client_short_term_pk;
        let conn_key = (hello_packet.client_extension.clone(), client_short_term_pk.clone());

        if self.conns.contains_key(&conn_key) {
            debug!("Hello packet received on open connection");
            return Ok(());
        }

        hello_packet.hello_box.open(&client_short_term_pk, &self.my_long_term_sk).unwrap();

        let (server_short_term_pk, server_short_term_sk) = server_short_term::gen_keypair();

        let cookie_packet: Packet = CookiePacket {
            client_extension: hello_packet.client_extension.clone(),
            server_extension: self.my_extension.clone(),
            cookie_box: PlainCookieBox {
                server_short_term_pk: server_short_term_pk,
                server_cookie: PlainCookie {
                    client_short_term_pk: client_short_term_pk.clone(),
                    server_short_term_sk: server_short_term_sk.clone(),
                }.seal(&CookieNonce::new_random(), &self.minute_key),
            }.seal(&Nonce16::new_random(), &client_short_term_pk, &self.my_long_term_sk),
        }.into();

        try!(cookie_packet.send(sock, &rem_addr));

        Ok(())
    }

    fn process_initiate(&mut self, initiate_packet: InitiatePacket, sock: &mut UdpSocket, rem_addr: SocketAddr) -> Result<()> {
        let conn_key = (initiate_packet.client_extension.clone(), initiate_packet.client_short_term_pk.clone());

        if self.conns.contains_key(&conn_key) {
            debug!("Recv'd INITIATE on already initiated connection");
            return Ok(());
        }

        let cookie = initiate_packet.server_cookie.open(&self.minute_key, &self.last_minute_key).unwrap();
        let precomputed_key = PrecomputedKey::precompute_at_server(&initiate_packet.client_short_term_pk, &cookie.server_short_term_sk);
        let (initiate_box, payload) = initiate_packet.initiate_box.open_precomputed_with_payload(&precomputed_key).unwrap();

        let client_long_term_pk = initiate_box.client_long_term_pk;
        let vouch = initiate_box.vouch.open(&client_long_term_pk, &self.my_long_term_sk).unwrap();

        if vouch.client_short_term_pk != initiate_packet.client_short_term_pk {
            return try!(Err("Invalid vouch"));
        }

        //TODO: Check if client_long_term_pk is accepted

        let (recv_tx, recv_rx) = channel();

        if let Some(msg) = payload {
            recv_tx.send(msg).unwrap();
        }

        let new_conn = ServerConnection {
            precomputed_key: precomputed_key.clone(),
            recv_tx: recv_tx,
            last_recv_nonce: initiate_packet.initiate_box.nonce.clone(),
        };

        self.conns.insert(conn_key, new_conn);
        info!("\"{}\" accepting connection \"{}\"@{}", &self.my_extension, &initiate_packet.client_extension, &rem_addr);

        let new_sock = ServerSocket {
            recv_rx: recv_rx,
            sock: sock.try_clone().unwrap(),
            rem_addr: rem_addr,
            client_extension: initiate_packet.client_extension.clone(),
            my_extension: self.my_extension.clone(),
            precomputed_key: precomputed_key,
            next_send_nonce: Nonce8::new_low(),
        };

        self.accept_chan_tx.send(new_sock).or(Err("Couldnt read accept channel".into()))
    }

    fn process_client_msg(&mut self, client_msg_packet: ClientMessagePacket, _sock: &mut UdpSocket, _rem_addr: SocketAddr) -> Result<()> {
        let conn_key = (client_msg_packet.client_extension.clone(),
                        client_msg_packet.client_short_term_pk.clone());

        if let Some(server_conn) = self.conns.get_mut(&conn_key) {
            try!(server_conn.process_packet(client_msg_packet));
        }

        Ok(())
    }
}

struct ServerConnection {
    precomputed_key: PrecomputedKey,
    recv_tx: Sender<Vec<u8>>,
    last_recv_nonce: Nonce8,
}

impl ServerConnection {
    pub fn process_packet(&mut self, client_msg_packet: ClientMessagePacket) -> Result<()> {
        if client_msg_packet.payload_box.nonce <= self.last_recv_nonce {
            return Err("Bad nonce".into()); // TODO: Rework to allow some packet reordering
        }

        let msg = try!(client_msg_packet.payload_box.open_precomputed(&self.precomputed_key)
            .or(Err("Bad encrypted message")));

        self.last_recv_nonce = client_msg_packet.payload_box.nonce;

        try!(self.recv_tx.send(msg).or(Err("Couldnt write to recv channel")));

        Ok(())
    }
}
<|endoftext|>