<commit_before>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

use ::types::{Vector3D, Matrix3};
use ::simulation::{Compute, Forces};
use ::universe::Universe;

/// The Integrator trait define integrators interface for Molecular Dynamics.
/// An integrator is an algorithm responsible for propagating the equations of
/// motion in the system.
pub trait Integrator {
    /// Setup the integrator. This function is called once by every simulation
    /// run.
    fn setup(&mut self, _: &Universe) {}
    /// Integrate the equations of motion. This is called at every step of the
    /// simulation.
    fn integrate(&mut self, universe: &mut Universe);
}

/// Velocity-Verlet integrator. This one is reversible and symplectic.
pub struct VelocityVerlet {
    /// Timestep for the integrator
    timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>
}

impl VelocityVerlet {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> VelocityVerlet {
        VelocityVerlet{
            timestep: timestep,
            accelerations: Vec::new(),
        }
    }
}

impl Integrator for VelocityVerlet {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;
        let natoms = universe.size();

        // Update velocities at t + ∆t/2 and positions at t + ∆t
        for i in 0..natoms {
            universe[i].add_velocity(0.5 * dt * self.accelerations[i]);
            let new_vel = *universe[i].velocity() * dt;
            universe[i].add_position(new_vel);
        }

        let forces = Forces.compute(&universe);
        // Update accelerations at t + ∆t and velocities at t + ∆t
        for i in 0..natoms {
            self.accelerations[i] = forces[i] / universe[i].mass();
            universe[i].add_velocity(0.5 * dt * self.accelerations[i]);
        }
    }
}

/******************************************************************************/
/// Verlet integrator. This one is reversible and symplectic.
pub struct Verlet {
    /// Timestep for the integrator
    timestep: f64,
    /// Previous positions
    prevpos: Vec<Vector3D>,
}

impl Verlet {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> Verlet {
        Verlet{
            timestep: timestep,
            prevpos: Vec::new(),
        }
    }
}

impl Integrator for Verlet {
    fn setup(&mut self, universe: &Universe) {
        self.prevpos = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];

        let dt = self.timestep;
        // Approximate the positions at t - ∆t
        for (i, part) in universe.iter().enumerate() {
            self.prevpos[i] = *part.position() - *part.velocity() * dt;
        }
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;
        let dt2 = self.timestep * self.timestep;

        let forces = Forces.compute(&universe);
        for (i, p) in universe.iter_mut().enumerate() {
            // Save positions at t
            let tmp = p.position().clone();
            // Update positions at t + ∆t
            let position = 2.0 * tmp - self.prevpos[i] + dt2/p.mass() * forces[i];
            // Update velocities at t
            let velocity = (position - self.prevpos[i]) / (2.0 * dt);
            p.set_position(position);
            p.set_velocity(velocity);
            // Update saved position
            self.prevpos[i] = tmp;
        }
    }
}

/******************************************************************************/
/// Leap-frog integrator. This one is reversible and symplectic.
pub struct LeapFrog {
    /// Timestep for the integrator
    timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>
}

impl LeapFrog {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> LeapFrog {
        LeapFrog{
            timestep: timestep,
            accelerations: Vec::new(),
        }
    }
}

impl Integrator for LeapFrog {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;
        let dt2 = self.timestep * self.timestep;

        for (i, p) in universe.iter_mut().enumerate() {
            let velocity = p.velocity().clone();
            p.add_position(velocity * dt + 0.5 * self.accelerations[i] * dt2);
        }

        let forces = Forces.compute(&universe);
        for (i, p) in universe.iter_mut().enumerate() {
            let mass = p.mass();
            let acceleration = forces[i]/mass;
            p.add_velocity(0.5 * (self.accelerations[i] + acceleration)* dt);
            self.accelerations[i] = acceleration;
        }
    }
}

/******************************************************************************/
/// This is needed for the BerendsenBarostat implentations. The value comes
/// from the DL_POLY source code.
const WATER_COMPRESSIBILITY: f64 = 7372.0;

/// Berendsen barostat integrator based on velocity-Verlet. This one neither
/// reversible nor symplectic.
pub struct BerendsenBarostat {
    /// Timestep for the integrator
    timestep: f64,
    /// Target pressure for the barostat
    pressure: f64,
    /// Barostat timestep, expressed in units of the main timestep.
    baro_timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>,
    /// Storing the scaling factor
    eta: f64,
}

impl BerendsenBarostat {
    /// Create a new Berendsen barostat with a timestep of `timestep`, and a
    /// target pressure of `pressure`. The barostat timestep is 1000.
    pub fn new(timestep: f64, pressure: f64) -> BerendsenBarostat {
        BerendsenBarostat::with_timestep(timestep, pressure, 1000.0)
    }

    /// Create a new Berendsen barostat with a timestep of `timestep`, a
    /// target pressure of `pressure` and a barostat timestep is of
    /// `baro_timestep`. The barostat timestep is expressed in terms of the main
    /// timestep. With `baro_timestep == 1000` and `timestep == 0.8 fs`, then
    /// the effective barostat timestep will be `800 fs`.
    pub fn with_timestep(timestep: f64, pressure: f64, baro_timestep: f64) -> BerendsenBarostat {
        BerendsenBarostat{
            timestep: timestep,
            pressure: pressure,
            baro_timestep: baro_timestep,
            accelerations: Vec::new(),
            eta: 1.0,
        }
    }

}

impl Integrator for BerendsenBarostat {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;

        // Update velocities at t + ∆t/2 and positions at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            part.add_velocity(0.5 * dt * self.accelerations[i]);
            let position = *part.position();
            // Scale all positions
            let position = self.eta * position;
            let position = position + *part.velocity() * dt;
            part.set_position(position);
        }

        universe.cell_mut().scale_mut(self.eta*self.eta*self.eta * Matrix3::one());

        self.eta = f64::cbrt(1.0 - WATER_COMPRESSIBILITY / self.baro_timestep * (self.pressure - universe.pressure()));

        let forces = Forces.compute(&universe);
        // Update accelerations at t + ∆t and velocities at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            self.accelerations[i] = forces[i] / part.mass();
            part.add_velocity(0.5 * dt * self.accelerations[i]);
        }
    }
}
<commit_msg>Update the integrators to always use iterators<commit_after>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

use ::types::{Vector3D, Matrix3};
use ::simulation::{Compute, Forces};
use ::universe::Universe;

/// The Integrator trait define integrators interface for Molecular Dynamics.
/// An integrator is an algorithm responsible for propagating the equations of
/// motion in the system.
pub trait Integrator {
    /// Setup the integrator. This function is called once by every simulation
    /// run.
    fn setup(&mut self, _: &Universe) {}
    /// Integrate the equations of motion. This is called at every step of the
    /// simulation.
    fn integrate(&mut self, universe: &mut Universe);
}

/// Velocity-Verlet integrator. This one is reversible and symplectic.
pub struct VelocityVerlet {
    /// Timestep for the integrator
    timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>
}

impl VelocityVerlet {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> VelocityVerlet {
        VelocityVerlet{
            timestep: timestep,
            accelerations: Vec::new(),
        }
    }
}

impl Integrator for VelocityVerlet {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;

        // Update velocities at t + ∆t/2 and positions at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            part.add_velocity(0.5 * dt * self.accelerations[i]);
            let dr = *part.velocity() * dt;
            part.add_position(dr);
        }

        let forces = Forces.compute(&universe);
        // Update accelerations at t + ∆t and velocities at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            self.accelerations[i] = forces[i] / part.mass();
            part.add_velocity(0.5 * dt * self.accelerations[i]);
        }
    }
}

/******************************************************************************/
/// Verlet integrator. This one is reversible and symplectic.
pub struct Verlet {
    /// Timestep for the integrator
    timestep: f64,
    /// Previous positions
    prevpos: Vec<Vector3D>,
}

impl Verlet {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> Verlet {
        Verlet{
            timestep: timestep,
            prevpos: Vec::new(),
        }
    }
}

impl Integrator for Verlet {
    fn setup(&mut self, universe: &Universe) {
        self.prevpos = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];

        let dt = self.timestep;
        // Approximate the positions at t - ∆t
        for (i, part) in universe.iter().enumerate() {
            self.prevpos[i] = *part.position() - *part.velocity() * dt;
        }
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;
        let dt2 = self.timestep * self.timestep;

        let forces = Forces.compute(&universe);
        for (i, part) in universe.iter_mut().enumerate() {
            // Save positions at t
            let tmp = part.position().clone();
            // Update positions at t + ∆t
            let position = 2.0 * tmp - self.prevpos[i] + dt2/part.mass() * forces[i];
            // Update velocities at t
            let velocity = (position - self.prevpos[i]) / (2.0 * dt);
            part.set_position(position);
            part.set_velocity(velocity);
            // Update saved position
            self.prevpos[i] = tmp;
        }
    }
}

/******************************************************************************/
/// Leap-frog integrator. This one is reversible and symplectic.
pub struct LeapFrog {
    /// Timestep for the integrator
    timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>
}

impl LeapFrog {
    /// Create a new integrator with a timestep of `timestep`.
    pub fn new(timestep: f64) -> LeapFrog {
        LeapFrog{
            timestep: timestep,
            accelerations: Vec::new(),
        }
    }
}

impl Integrator for LeapFrog {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;
        let dt2 = self.timestep * self.timestep;

        for (i, part) in universe.iter_mut().enumerate() {
            let velocity = part.velocity().clone();
            part.add_position(velocity * dt + 0.5 * self.accelerations[i] * dt2);
        }

        let forces = Forces.compute(&universe);
        for (i, part) in universe.iter_mut().enumerate() {
            let mass = part.mass();
            let acceleration = forces[i]/mass;
            part.add_velocity(0.5 * (self.accelerations[i] + acceleration)* dt);
            self.accelerations[i] = acceleration;
        }
    }
}

/******************************************************************************/
/// This is needed for the BerendsenBarostat implentations. The value comes
/// from the DL_POLY source code.
const WATER_COMPRESSIBILITY: f64 = 7372.0;

/// Berendsen barostat integrator based on velocity-Verlet. This one neither
/// reversible nor symplectic.
pub struct BerendsenBarostat {
    /// Timestep for the integrator
    timestep: f64,
    /// Target pressure for the barostat
    pressure: f64,
    /// Barostat timestep, expressed in units of the main timestep.
    baro_timestep: f64,
    /// Storing the accelerations
    accelerations: Vec<Vector3D>,
    /// Storing the scaling factor
    eta: f64,
}

impl BerendsenBarostat {
    /// Create a new Berendsen barostat with a timestep of `timestep`, and a
    /// target pressure of `pressure`. The barostat timestep is 1000.
    pub fn new(timestep: f64, pressure: f64) -> BerendsenBarostat {
        BerendsenBarostat::with_timestep(timestep, pressure, 1000.0)
    }

    /// Create a new Berendsen barostat with a timestep of `timestep`, a
    /// target pressure of `pressure` and a barostat timestep is of
    /// `baro_timestep`. The barostat timestep is expressed in terms of the main
    /// timestep. With `baro_timestep == 1000` and `timestep == 0.8 fs`, then
    /// the effective barostat timestep will be `800 fs`.
    pub fn with_timestep(timestep: f64, pressure: f64, baro_timestep: f64) -> BerendsenBarostat {
        BerendsenBarostat{
            timestep: timestep,
            pressure: pressure,
            baro_timestep: baro_timestep,
            accelerations: Vec::new(),
            eta: 1.0,
        }
    }

}

impl Integrator for BerendsenBarostat {
    fn setup(&mut self, universe: &Universe) {
        self.accelerations = vec![Vector3D::new(0.0, 0.0, 0.0); universe.size()];
    }

    fn integrate(&mut self, universe: &mut Universe) {
        let dt = self.timestep;

        // Update velocities at t + ∆t/2 and positions at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            part.add_velocity(0.5 * dt * self.accelerations[i]);
            let position = *part.position();
            // Scale all positions
            let position = self.eta * position;
            let position = position + *part.velocity() * dt;
            part.set_position(position);
        }

        universe.cell_mut().scale_mut(self.eta*self.eta*self.eta * Matrix3::one());

        self.eta = f64::cbrt(1.0 - WATER_COMPRESSIBILITY / self.baro_timestep * (self.pressure - universe.pressure()));

        let forces = Forces.compute(&universe);
        // Update accelerations at t + ∆t and velocities at t + ∆t
        for (i, part) in universe.iter_mut().enumerate() {
            self.accelerations[i] = forces[i] / part.mass();
            part.add_velocity(0.5 * dt * self.accelerations[i]);
        }
    }
}
<|endoftext|>


<commit_before>extern crate openzwave_stateful as openzwave;
extern crate foxbox_taxonomy as taxonomy;
extern crate transformable_channels;

use taxonomy::util::Id as TaxId;
use taxonomy::services::{ AdapterId, Getter, Setter };
use taxonomy::values::{ Value, Range };
use taxonomy::api::{ ResultMap, Error as TaxError };
use taxonomy::adapter::{ AdapterManagerHandle, AdapterWatchGuard, WatchEvent };
use transformable_channels::mpsc::ExtSender;

use openzwave::InitOptions;
use openzwave::{ ValueGenre, ValueID };

use std::error;
use std::fmt;
use std::collections::HashMap;

#[derive(Debug)]
pub enum OpenzwaveError {
    RegisteringError(TaxError),
    UnknownError
}

impl From<TaxError> for OpenzwaveError {
    fn from(err: TaxError) -> Self {
        OpenzwaveError::RegisteringError(err)
    }
}

impl From<()> for OpenzwaveError {
    fn from(_: ()) -> Self {
        OpenzwaveError::UnknownError
    }
}

impl fmt::Display for OpenzwaveError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => write!(f, "IO error: {}", err),
            OpenzwaveError::UnknownError => write!(f, "Unknown error"),
        }
    }
}

impl error::Error for OpenzwaveError {
    fn description(&self) -> &str {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => err.description(),
            OpenzwaveError::UnknownError => "Unknown error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => Some(err),
            OpenzwaveError::UnknownError => None,
        }
    }
}

pub struct OpenzwaveAdapter {
    id: TaxId<AdapterId>,
    name: String,
    vendor: String,
    version: [u32; 4],
    manager: Box<AdapterManagerHandle + Send>
}

impl OpenzwaveAdapter {
    pub fn init<T: AdapterManagerHandle + Clone + Send + 'static> (manager: &T) -> Result<(), OpenzwaveError> {
        let name = String::from("OpenZwave Adapter");
        let adapter = Box::new(OpenzwaveAdapter {
            id: TaxId::new(&name),
            name: name,
            vendor: String::from("Mozilla"),
            version: [1, 0, 0, 0],
            manager: Box::new(manager.clone())
        });

        try!(manager.add_adapter(adapter));

        let options = InitOptions {
            device: None // TODO we should expose this as a Value
        };

        let ozw = try!(openzwave::init(&options));

        Ok(())
    }
}

impl taxonomy::adapter::Adapter for OpenzwaveAdapter {
    fn id(&self) -> TaxId<AdapterId> {
        self.id.clone()
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn vendor(&self) -> &str {
        &self.vendor
    }

    fn version(&self) -> &[u32; 4] {
        &self.version
    }

    fn fetch_values(&self, set: Vec<TaxId<Getter>>) -> ResultMap<TaxId<Getter>, Option<Value>, TaxError> {
        unimplemented!()
    }

    fn send_values(&self, values: HashMap<TaxId<Setter>, Value>) -> ResultMap<TaxId<Setter>, (), TaxError> {
        unimplemented!()
    }

    fn register_watch(&self, values: Vec<(TaxId<Getter>, Option<Range>)>, cb: Box<ExtSender<WatchEvent>>) -> ResultMap<TaxId<Getter>, Box<AdapterWatchGuard>, TaxError> {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>[fxbox/openzwave-adapter] starting implementation of handling notifications<commit_after>extern crate openzwave_stateful as openzwave;
extern crate foxbox_taxonomy as taxonomy;
extern crate transformable_channels;

use taxonomy::util::Id as TaxId;
use taxonomy::services::{ Setter, Getter, AdapterId, ServiceId, Service, Channel, ChannelKind };
use taxonomy::values::{ Value, Range };
use taxonomy::api::{ ResultMap, Error as TaxError };
use taxonomy::adapter::{ AdapterManagerHandle, AdapterWatchGuard, WatchEvent };
use transformable_channels::mpsc::ExtSender;

use openzwave::{ InitOptions, ZWaveManager, ZWaveNotification };
use openzwave::{ ValueGenre, ValueID };
use openzwave::{ Controller };

use std::error;
use std::fmt;
use std::thread;
use std::sync::mpsc;
use std::sync::RwLock;
use std::collections::{ HashMap, HashSet };

#[derive(Debug)]
pub enum OpenzwaveError {
    RegisteringError(TaxError),
    UnknownError
}

impl From<TaxError> for OpenzwaveError {
    fn from(err: TaxError) -> Self {
        OpenzwaveError::RegisteringError(err)
    }
}

impl From<()> for OpenzwaveError {
    fn from(_: ()) -> Self {
        OpenzwaveError::UnknownError
    }
}

impl fmt::Display for OpenzwaveError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => write!(f, "IO error: {}", err),
            OpenzwaveError::UnknownError => write!(f, "Unknown error"),
        }
    }
}

impl error::Error for OpenzwaveError {
    fn description(&self) -> &str {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => err.description(),
            OpenzwaveError::UnknownError => "Unknown error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            OpenzwaveError::RegisteringError(ref err) => Some(err),
            OpenzwaveError::UnknownError => None,
        }
    }
}

pub struct OpenzwaveAdapter {
    id: TaxId<AdapterId>,
    name: String,
    vendor: String,
    version: [u32; 4],
    ozw: ZWaveManager,
}

impl OpenzwaveAdapter {
    pub fn init<T: AdapterManagerHandle + Clone + Send + 'static> (box_manager: &T) -> Result<(), OpenzwaveError> {
        let options = InitOptions {
            device: None // TODO we should expose this as a Value
        };

        let (ozw, rx) = try!(openzwave::init(&options));

        let name = String::from("OpenZwave Adapter");
        let adapter = Box::new(OpenzwaveAdapter {
            id: TaxId::new(&name),
            name: name,
            vendor: String::from("Mozilla"),
            version: [1, 0, 0, 0],
            ozw: ozw,
        });

        adapter.spawn_notification_thread(rx, box_manager);
        try!(box_manager.add_adapter(adapter));

        Ok(())
    }

    fn spawn_notification_thread<T: AdapterManagerHandle + Clone + Send + 'static>(&self, rx: mpsc::Receiver<ZWaveNotification>, box_manager: &T) {
        let adapter_id = self.id.clone();
        let box_manager = box_manager.clone();

        thread::spawn(move || {
            let mut controller_map: Vec<(TaxId<ServiceId>, Controller)> = Vec::new();

            for notification in rx {
                match notification {
                    ZWaveNotification::ControllerReady(controller) => {
                        let service = format!("OpenZWave/{}", controller.get_home_id());
                        let service_id = TaxId::new(&service);
                        controller_map.push((service_id.clone(), controller));

                        box_manager.add_service(Service::empty(service_id.clone(), adapter_id.clone()));
                    }
                    ZWaveNotification::NodeNew(node)               => {}
                    ZWaveNotification::NodeAdded(node)             => {}
                    ZWaveNotification::NodeRemoved(node)           => {}
                    ZWaveNotification::ValueAdded(value)           => {
                        let value_id = format!("OpenZWave/{}", value.get_id());
                        let controller_pair = controller_map.iter().find(|&&(_, controller)| controller == value.get_controller());
                        if controller_pair.is_none() { continue; }
                        let ref controller_id = controller_pair.unwrap().0;

                        if value.is_read_only() {
                            box_manager.add_getter(Channel {
                                id: TaxId::new(&value_id),
                                service: controller_id.clone(),
                                adapter: adapter_id.clone(),
                                last_seen: None,
                                tags: HashSet::new(),
                                mechanism: Getter {
                                    kind: ChannelKind::Ready,
                                    updated: None
                                }
                            });
                        }
                    }
                    ZWaveNotification::ValueChanged(value)         => {}
                    ZWaveNotification::ValueRemoved(value)         => {}
                    ZWaveNotification::Generic(string)             => {}
                }
            }
        });
    }
}

impl taxonomy::adapter::Adapter for OpenzwaveAdapter {
    fn id(&self) -> TaxId<AdapterId> {
        self.id.clone()
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn vendor(&self) -> &str {
        &self.vendor
    }

    fn version(&self) -> &[u32; 4] {
        &self.version
    }

    fn fetch_values(&self, set: Vec<TaxId<Getter>>) -> ResultMap<TaxId<Getter>, Option<Value>, TaxError> {
        let state = self.ozw.get_state();

        unimplemented!()
    }

    fn send_values(&self, values: HashMap<TaxId<Setter>, Value>) -> ResultMap<TaxId<Setter>, (), TaxError> {
        unimplemented!()
    }

    fn register_watch(&self, values: Vec<(TaxId<Getter>, Option<Range>)>, cb: Box<ExtSender<WatchEvent>>) -> ResultMap<TaxId<Getter>, Box<AdapterWatchGuard>, TaxError> {
        unimplemented!()
    }
}

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


<commit_before>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, Internal, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::marker::PhantomData;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    let expected = [(None, 4), (Some(false), 5), (Some(true), 6)];
    assert_eq!(map.into_iter().collect::<Vec<_>>(), expected);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Internal<V> for X {
    type Array = [V; 1];

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
}
<commit_msg>Add a test for accessing a key in manual Internal implementation for better coverage<commit_after>#[macro_use]
extern crate enum_map;

use enum_map::{EnumMap, Internal, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::marker::PhantomData;

#[derive(Copy, Clone, Debug, EnumMap, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_option_bool() {
    let mut map = enum_map! { None => 1, Some(false) => 2, Some(true) => 3};
    assert_eq!(map[None], 1);
    assert_eq!(map[Some(false)], 2);
    assert_eq!(map[Some(true)], 3);
    map[None] = 4;
    map[Some(false)] = 5;
    map[Some(true)] = 6;
    assert_eq!(map[None], 4);
    assert_eq!(map[Some(false)], 5);
    assert_eq!(map[Some(true)], 6);
    assert_eq!(map.as_slice(), [4, 5, 6]);
    let expected = [(None, 4), (Some(false), 5), (Some(true), 6)];
    assert_eq!(map.into_iter().collect::<Vec<_>>(), expected);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn discriminants() {
    #[derive(Debug, EnumMap, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example:: A => 3, Example:: B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(EnumMap)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }.into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(EnumMap)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map!{};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Internal<V> for X {
    type Array = [V; 1];

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
    assert_eq!(map[X::A(PhantomData)], true);
}
<|endoftext|>


<commit_before>// By compiling this file we check that all the intrinsics we care about continue to be provided by
// the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
// compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
// to link due to the missing intrinsic (symbol).

#![allow(unused_features)]
#![cfg_attr(thumb, no_main)]
#![deny(dead_code)]
#![feature(alloc_system)]
#![feature(asm)]
#![feature(compiler_builtins_lib)]
#![feature(core_float)]
#![feature(lang_items)]
#![feature(start)]
#![feature(global_allocator)]
#![feature(allocator_api)]
#![cfg_attr(windows, feature(panic_unwind))]
#![no_std]

#[cfg(not(thumb))]
#[link(name = "c")]
extern {}

// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even
// compiler-rt provides a C/assembly implementation.

// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
// doesn't have native support for the operation used in the function. ARM has a naming convention
// convention for its intrinsics that's different from other architectures; that's why some function
// have an additional comment: the function name is the ARM name for the intrinsic and the comment
// in the non-ARM name for the intrinsic.
mod intrinsics {
    // trunccdfsf2
    pub fn aeabi_d2f(x: f64) -> f32 {
        x as f32
    }

    // fixdfsi
    pub fn aeabi_d2i(x: f64) -> i32 {
        x as i32
    }

    // fixdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2l(x: f64) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2l(_: f64) -> i64 {
        0
    }

    // fixunsdfsi
    pub fn aeabi_d2uiz(x: f64) -> u32 {
        x as u32
    }

    // fixunsdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2ulz(x: f64) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2ulz(_: f64) -> u64 {
        0
    }

    // adddf3
    pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
        a + b
    }

    // eqdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool {
        true
    }

    // gtdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool {
        true
    }

    // ltdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmplt(_: f64, _: f64) -> bool {
        true
    }

    // divdf3
    pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
        a / b
    }

    // muldf3
    pub fn aeabi_dmul(a: f64, b: f64) -> f64 {
        a * b
    }

    // subdf3
    pub fn aeabi_dsub(a: f64, b: f64) -> f64 {
        a - b
    }

    // extendsfdf2
    pub fn aeabi_f2d(x: f32) -> f64 {
        x as f64
    }

    // fixsfsi
    pub fn aeabi_f2iz(x: f32) -> i32 {
        x as i32
    }

    // fixsfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2lz(x: f32) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2lz(_: f32) -> i64 {
        0
    }

    // fixunssfsi
    pub fn aeabi_f2uiz(x: f32) -> u32 {
        x as u32
    }

    // fixunssfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2ulz(x: f32) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2ulz(_: f32) -> u64 {
        0
    }

    // addsf3
    pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
        a + b
    }

    // eqsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool {
        true
    }

    // gtsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool {
        true
    }

    // ltsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmplt(_: f32, _: f32) -> bool {
        true
    }

    // divsf3
    pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
        a / b
    }

    // mulsf3
    pub fn aeabi_fmul(a: f32, b: f32) -> f32 {
        a * b
    }

    // subsf3
    pub fn aeabi_fsub(a: f32, b: f32) -> f32 {
        a - b
    }

    // floatsidf
    pub fn aeabi_i2d(x: i32) -> f64 {
        x as f64
    }

    // floatsisf
    pub fn aeabi_i2f(x: i32) -> f32 {
        x as f32
    }

    pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
        a.wrapping_div(b)
    }

    pub fn aeabi_idivmod(a: i32, b: i32) -> i32 {
        a % b
    }

    // floatdidf
    pub fn aeabi_l2d(x: i64) -> f64 {
        x as f64
    }

    // floatdisf
    pub fn aeabi_l2f(x: i64) -> f32 {
        x as f32
    }

    // divdi3
    pub fn aeabi_ldivmod(a: i64, b: i64) -> i64 {
        a / b
    }

    // muldi3
    pub fn aeabi_lmul(a: i64, b: i64) -> i64 {
        a.wrapping_mul(b)
    }

    // floatunsidf
    pub fn aeabi_ui2d(x: u32) -> f64 {
        x as f64
    }

    // floatunsisf
    pub fn aeabi_ui2f(x: u32) -> f32 {
        x as f32
    }

    pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
        a / b
    }

    pub fn aeabi_uidivmod(a: u32, b: u32) -> u32 {
        a % b
    }

    // floatundidf
    pub fn aeabi_ul2d(x: u64) -> f64 {
        x as f64
    }

    // floatundisf
    pub fn aeabi_ul2f(x: u64) -> f32 {
        x as f32
    }

    // udivdi3
    pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
        a * b
    }

    pub fn moddi3(a: i64, b: i64) -> i64 {
        a % b
    }

    pub fn mulodi4(a: i64, b: i64) -> i64 {
        a * b
    }

    pub fn umoddi3(a: u64, b: u64) -> u64 {
        a % b
    }

    pub fn muloti4(a: u128, b: u128) -> Option<u128> {
        a.checked_mul(b)
    }

    pub fn multi3(a: u128, b: u128) -> u128 {
        a.wrapping_mul(b)
    }

    pub fn ashlti3(a: u128, b: usize) -> u128 {
        a >> b
    }

    pub fn ashrti3(a: u128, b: usize) -> u128 {
        a << b
    }

    pub fn lshrti3(a: i128, b: usize) -> i128 {
        a >> b
    }

    pub fn udivti3(a: u128, b: u128) -> u128 {
        a / b
    }

    pub fn umodti3(a: u128, b: u128) -> u128 {
        a % b
    }

    pub fn divti3(a: i128, b: i128) -> i128 {
        a / b
    }

    pub fn modti3(a: i128, b: i128) -> i128 {
        a % b
    }
}

fn run() {
    use intrinsics::*;

    // A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO
    fn bb<T>(dummy: T) -> T {
        unsafe { asm!("" : : "r"(&dummy)) }
        dummy
    }

    bb(aeabi_d2f(bb(2.)));
    bb(aeabi_d2i(bb(2.)));
    bb(aeabi_d2l(bb(2.)));
    bb(aeabi_d2uiz(bb(2.)));
    bb(aeabi_d2ulz(bb(2.)));
    bb(aeabi_dadd(bb(2.), bb(3.)));
    bb(aeabi_dcmpeq(bb(2.), bb(3.)));
    bb(aeabi_dcmpgt(bb(2.), bb(3.)));
    bb(aeabi_dcmplt(bb(2.), bb(3.)));
    bb(aeabi_ddiv(bb(2.), bb(3.)));
    bb(aeabi_dmul(bb(2.), bb(3.)));
    bb(aeabi_dsub(bb(2.), bb(3.)));
    bb(aeabi_f2d(bb(2.)));
    bb(aeabi_f2iz(bb(2.)));
    bb(aeabi_f2lz(bb(2.)));
    bb(aeabi_f2uiz(bb(2.)));
    bb(aeabi_f2ulz(bb(2.)));
    bb(aeabi_fadd(bb(2.), bb(3.)));
    bb(aeabi_fcmpeq(bb(2.), bb(3.)));
    bb(aeabi_fcmpgt(bb(2.), bb(3.)));
    bb(aeabi_fcmplt(bb(2.), bb(3.)));
    bb(aeabi_fdiv(bb(2.), bb(3.)));
    bb(aeabi_fmul(bb(2.), bb(3.)));
    bb(aeabi_fsub(bb(2.), bb(3.)));
    bb(aeabi_i2d(bb(2)));
    bb(aeabi_i2f(bb(2)));
    bb(aeabi_idiv(bb(2), bb(3)));
    bb(aeabi_idivmod(bb(2), bb(3)));
    bb(aeabi_l2d(bb(2)));
    bb(aeabi_l2f(bb(2)));
    bb(aeabi_ldivmod(bb(2), bb(3)));
    bb(aeabi_lmul(bb(2), bb(3)));
    bb(aeabi_ui2d(bb(2)));
    bb(aeabi_ui2f(bb(2)));
    bb(aeabi_uidiv(bb(2), bb(3)));
    bb(aeabi_uidivmod(bb(2), bb(3)));
    bb(aeabi_ul2d(bb(2)));
    bb(aeabi_ul2f(bb(2)));
    bb(aeabi_uldivmod(bb(2), bb(3)));
    bb(moddi3(bb(2), bb(3)));
    bb(mulodi4(bb(2), bb(3)));
    bb(umoddi3(bb(2), bb(3)));
    bb(muloti4(bb(2), bb(2)));
    bb(multi3(bb(2), bb(2)));
    bb(ashlti3(bb(2), bb(2)));
    bb(ashrti3(bb(2), bb(2)));
    bb(lshrti3(bb(2), bb(2)));
    bb(udivti3(bb(2), bb(2)));
    bb(umodti3(bb(2), bb(2)));
    bb(divti3(bb(2), bb(2)));
    bb(modti3(bb(2), bb(2)));

    something_with_a_dtor(&|| assert_eq!(bb(1), 1));
}

fn something_with_a_dtor(f: &Fn()) {
    struct A<'a>(&'a (Fn() + 'a));

    impl<'a> Drop for A<'a> {
        fn drop(&mut self) {
            (self.0)();
        }
    }
    let _a = A(f);
    f();
}

#[cfg(not(thumb))]
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
    run();
    0
}

#[cfg(thumb)]
#[no_mangle]
pub fn _start() -> ! {
    run();
    loop {}
}

#[cfg(windows)]
#[link(name = "kernel32")]
#[link(name = "msvcrt")]
extern {}

// ARM targets need these symbols
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}

#[no_mangle]
pub fn __aeabi_unwind_cpp_pr1() {}

#[cfg(not(windows))]
#[allow(non_snake_case)]
#[no_mangle]
pub fn _Unwind_Resume() {}

#[cfg(not(windows))]
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn eh_personality() {}

#[lang = "panic_fmt"]
#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn panic_fmt() {}
<commit_msg>Try to fix example's compile on nightly<commit_after>// By compiling this file we check that all the intrinsics we care about continue to be provided by
// the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
// compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
// to link due to the missing intrinsic (symbol).

#![allow(unused_features)]
#![cfg_attr(thumb, no_main)]
#![deny(dead_code)]
#![feature(alloc_system)]
#![feature(asm)]
#![feature(compiler_builtins_lib)]
#![feature(core_float)]
#![feature(lang_items)]
#![feature(start)]
#![feature(global_allocator)]
#![feature(allocator_api)]
#![feature(panic_implementation)]
#![cfg_attr(windows, feature(panic_unwind))]
#![no_std]

#[cfg(not(thumb))]
#[link(name = "c")]
extern {}

// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even
// compiler-rt provides a C/assembly implementation.

// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
// doesn't have native support for the operation used in the function. ARM has a naming convention
// convention for its intrinsics that's different from other architectures; that's why some function
// have an additional comment: the function name is the ARM name for the intrinsic and the comment
// in the non-ARM name for the intrinsic.
mod intrinsics {
    // trunccdfsf2
    pub fn aeabi_d2f(x: f64) -> f32 {
        x as f32
    }

    // fixdfsi
    pub fn aeabi_d2i(x: f64) -> i32 {
        x as i32
    }

    // fixdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2l(x: f64) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2l(_: f64) -> i64 {
        0
    }

    // fixunsdfsi
    pub fn aeabi_d2uiz(x: f64) -> u32 {
        x as u32
    }

    // fixunsdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2ulz(x: f64) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2ulz(_: f64) -> u64 {
        0
    }

    // adddf3
    pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
        a + b
    }

    // eqdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool {
        true
    }

    // gtdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool {
        true
    }

    // ltdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmplt(_: f64, _: f64) -> bool {
        true
    }

    // divdf3
    pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
        a / b
    }

    // muldf3
    pub fn aeabi_dmul(a: f64, b: f64) -> f64 {
        a * b
    }

    // subdf3
    pub fn aeabi_dsub(a: f64, b: f64) -> f64 {
        a - b
    }

    // extendsfdf2
    pub fn aeabi_f2d(x: f32) -> f64 {
        x as f64
    }

    // fixsfsi
    pub fn aeabi_f2iz(x: f32) -> i32 {
        x as i32
    }

    // fixsfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2lz(x: f32) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2lz(_: f32) -> i64 {
        0
    }

    // fixunssfsi
    pub fn aeabi_f2uiz(x: f32) -> u32 {
        x as u32
    }

    // fixunssfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2ulz(x: f32) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2ulz(_: f32) -> u64 {
        0
    }

    // addsf3
    pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
        a + b
    }

    // eqsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool {
        true
    }

    // gtsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool {
        true
    }

    // ltsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmplt(_: f32, _: f32) -> bool {
        true
    }

    // divsf3
    pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
        a / b
    }

    // mulsf3
    pub fn aeabi_fmul(a: f32, b: f32) -> f32 {
        a * b
    }

    // subsf3
    pub fn aeabi_fsub(a: f32, b: f32) -> f32 {
        a - b
    }

    // floatsidf
    pub fn aeabi_i2d(x: i32) -> f64 {
        x as f64
    }

    // floatsisf
    pub fn aeabi_i2f(x: i32) -> f32 {
        x as f32
    }

    pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
        a.wrapping_div(b)
    }

    pub fn aeabi_idivmod(a: i32, b: i32) -> i32 {
        a % b
    }

    // floatdidf
    pub fn aeabi_l2d(x: i64) -> f64 {
        x as f64
    }

    // floatdisf
    pub fn aeabi_l2f(x: i64) -> f32 {
        x as f32
    }

    // divdi3
    pub fn aeabi_ldivmod(a: i64, b: i64) -> i64 {
        a / b
    }

    // muldi3
    pub fn aeabi_lmul(a: i64, b: i64) -> i64 {
        a.wrapping_mul(b)
    }

    // floatunsidf
    pub fn aeabi_ui2d(x: u32) -> f64 {
        x as f64
    }

    // floatunsisf
    pub fn aeabi_ui2f(x: u32) -> f32 {
        x as f32
    }

    pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
        a / b
    }

    pub fn aeabi_uidivmod(a: u32, b: u32) -> u32 {
        a % b
    }

    // floatundidf
    pub fn aeabi_ul2d(x: u64) -> f64 {
        x as f64
    }

    // floatundisf
    pub fn aeabi_ul2f(x: u64) -> f32 {
        x as f32
    }

    // udivdi3
    pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
        a * b
    }

    pub fn moddi3(a: i64, b: i64) -> i64 {
        a % b
    }

    pub fn mulodi4(a: i64, b: i64) -> i64 {
        a * b
    }

    pub fn umoddi3(a: u64, b: u64) -> u64 {
        a % b
    }

    pub fn muloti4(a: u128, b: u128) -> Option<u128> {
        a.checked_mul(b)
    }

    pub fn multi3(a: u128, b: u128) -> u128 {
        a.wrapping_mul(b)
    }

    pub fn ashlti3(a: u128, b: usize) -> u128 {
        a >> b
    }

    pub fn ashrti3(a: u128, b: usize) -> u128 {
        a << b
    }

    pub fn lshrti3(a: i128, b: usize) -> i128 {
        a >> b
    }

    pub fn udivti3(a: u128, b: u128) -> u128 {
        a / b
    }

    pub fn umodti3(a: u128, b: u128) -> u128 {
        a % b
    }

    pub fn divti3(a: i128, b: i128) -> i128 {
        a / b
    }

    pub fn modti3(a: i128, b: i128) -> i128 {
        a % b
    }
}

fn run() {
    use intrinsics::*;

    // A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO
    fn bb<T>(dummy: T) -> T {
        unsafe { asm!("" : : "r"(&dummy)) }
        dummy
    }

    bb(aeabi_d2f(bb(2.)));
    bb(aeabi_d2i(bb(2.)));
    bb(aeabi_d2l(bb(2.)));
    bb(aeabi_d2uiz(bb(2.)));
    bb(aeabi_d2ulz(bb(2.)));
    bb(aeabi_dadd(bb(2.), bb(3.)));
    bb(aeabi_dcmpeq(bb(2.), bb(3.)));
    bb(aeabi_dcmpgt(bb(2.), bb(3.)));
    bb(aeabi_dcmplt(bb(2.), bb(3.)));
    bb(aeabi_ddiv(bb(2.), bb(3.)));
    bb(aeabi_dmul(bb(2.), bb(3.)));
    bb(aeabi_dsub(bb(2.), bb(3.)));
    bb(aeabi_f2d(bb(2.)));
    bb(aeabi_f2iz(bb(2.)));
    bb(aeabi_f2lz(bb(2.)));
    bb(aeabi_f2uiz(bb(2.)));
    bb(aeabi_f2ulz(bb(2.)));
    bb(aeabi_fadd(bb(2.), bb(3.)));
    bb(aeabi_fcmpeq(bb(2.), bb(3.)));
    bb(aeabi_fcmpgt(bb(2.), bb(3.)));
    bb(aeabi_fcmplt(bb(2.), bb(3.)));
    bb(aeabi_fdiv(bb(2.), bb(3.)));
    bb(aeabi_fmul(bb(2.), bb(3.)));
    bb(aeabi_fsub(bb(2.), bb(3.)));
    bb(aeabi_i2d(bb(2)));
    bb(aeabi_i2f(bb(2)));
    bb(aeabi_idiv(bb(2), bb(3)));
    bb(aeabi_idivmod(bb(2), bb(3)));
    bb(aeabi_l2d(bb(2)));
    bb(aeabi_l2f(bb(2)));
    bb(aeabi_ldivmod(bb(2), bb(3)));
    bb(aeabi_lmul(bb(2), bb(3)));
    bb(aeabi_ui2d(bb(2)));
    bb(aeabi_ui2f(bb(2)));
    bb(aeabi_uidiv(bb(2), bb(3)));
    bb(aeabi_uidivmod(bb(2), bb(3)));
    bb(aeabi_ul2d(bb(2)));
    bb(aeabi_ul2f(bb(2)));
    bb(aeabi_uldivmod(bb(2), bb(3)));
    bb(moddi3(bb(2), bb(3)));
    bb(mulodi4(bb(2), bb(3)));
    bb(umoddi3(bb(2), bb(3)));
    bb(muloti4(bb(2), bb(2)));
    bb(multi3(bb(2), bb(2)));
    bb(ashlti3(bb(2), bb(2)));
    bb(ashrti3(bb(2), bb(2)));
    bb(lshrti3(bb(2), bb(2)));
    bb(udivti3(bb(2), bb(2)));
    bb(umodti3(bb(2), bb(2)));
    bb(divti3(bb(2), bb(2)));
    bb(modti3(bb(2), bb(2)));

    something_with_a_dtor(&|| assert_eq!(bb(1), 1));
}

fn something_with_a_dtor(f: &Fn()) {
    struct A<'a>(&'a (Fn() + 'a));

    impl<'a> Drop for A<'a> {
        fn drop(&mut self) {
            (self.0)();
        }
    }
    let _a = A(f);
    f();
}

#[cfg(not(thumb))]
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
    run();
    0
}

#[cfg(thumb)]
#[no_mangle]
pub fn _start() -> ! {
    run();
    loop {}
}

#[cfg(windows)]
#[link(name = "kernel32")]
#[link(name = "msvcrt")]
extern {}

// ARM targets need these symbols
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}

#[no_mangle]
pub fn __aeabi_unwind_cpp_pr1() {}

#[cfg(not(windows))]
#[allow(non_snake_case)]
#[no_mangle]
pub fn _Unwind_Resume() {}

#[cfg(not(windows))]
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn eh_personality() {}

#[panic_implementation]
fn panic(x: &core::panic::PanicInfo) -> ! {
    loop {}
}
<|endoftext|>


<commit_before>// src/controllers/money_maps_controller.rs

/// Money Maps Controller

// Import
// External
use ::chrono::{DateTime, Duration, Local};
use ::nickel::{JsonBody, Request};
use ::bson::{Bson, Document};
use ::bson::oid::ObjectId;
use ::std::default::Default;
use ::crypto::sha2::Sha256;
use ::jwt::{Header, Registered, Token};
use ::rustc_serialize::hex::ToHex;
// Utilities
use ::common::api_result::ApiResult;
use ::common::config::Config;
use ::common::data_access::ServerData;
use ::common::session as Session;
// DAO
use ::dao::dao_manager::DAOManager;
// Models
use ::models::user_model::{OutUserModel};
use ::models::money_map_model::{MoneyMapModel, MoneyMapUserModel};

#[derive(Clone)]
pub struct MoneyMapsController{
    dao_manager: DAOManager,
    config: Config
}

impl MoneyMapsController{

    pub fn new(dao_manager: DAOManager, config: Config) -> MoneyMapsController{
        MoneyMapsController{
            dao_manager: dao_manager,
            config: config
        }
    }

    /// Find All Money Maps belonging to the requesting user
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<Vec<MoneyMapModel>>` - ApiResult including a vector of money maps
    pub fn find(&self, req: &mut Request<ServerData>) -> ApiResult<Vec<MoneyMapModel>>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                //Get list of money maps for this user
                let mut money_maps = dao.find(Some(doc!{
                    "users.user_id" => user_id,
                    "deleted" => {
                        "$ne" => true
                    }
                }));

                // Get list of user details for each money map
                for i in 0..money_maps.len(){
                    if let Some(mm_users) = money_maps[i].get_users(){
                        // Initialze a list of user details for this money map
                        let mut users_list = Vec::new();

                        // For each user associated with this money map
                        for mm_user in mm_users{
                            match self.dao_manager.get_user_dao(){
                                Ok(user_dao) => {

                                    // Fetch the user's details
                                    let user_id = Bson::ObjectId(mm_user.user.unwrap().id.unwrap());
                                    let found_user = user_dao.find_one(Some(doc!{
                                        "_id" => user_id
                                    }), None);
                                    if let Some(user) = found_user{
                                        // Add the user details to the list
                                        users_list.push(
                                            MoneyMapUserModel::new(OutUserModel::new(user), mm_user.owner)
                                        );
                                    }
                                },
                                Err(e) => {
                                    error!("{}",e.get_message().to_string());
                                    return ApiResult::Failure{msg:"Unable to interact with database"};
                                }
                            }
                        }

                        // Add the new list of user details to the money map
                        money_maps[i].set_users(Some(users_list));
                    }
                }

                // Return the list of money maps
                ApiResult::Success{result:money_maps}
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end find_all

    /// Create Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the create money map
    pub fn create(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        match req.json_as::<MoneyMapModel>(){
                            Ok(mut money_map) => {
                                // Validate
                                let validation_result = money_map.validate();
                                if validation_result.is_valid(){
                                    // Save User
                                    match dao.create(&money_map, user_id.clone()){
                                        Ok(result) => {
                                            // Set user ID
                                            match result.inserted_id{
                                                Some(id_wrapper) => {
                                                    match id_wrapper{
                                                        Bson::ObjectId(id) => money_map.set_id(id),
                                                        _ => {}
                                                    }
                                                },
                                                None => {}
                                            }
                                            // Add user details
                                            if let Ok(id) = ObjectId::with_string(user_id.as_str()){
                                                if let Some(user) = user_dao.find_one(Some(doc!{"_id" => id}), None){
                                                    money_map.set_users(Some(
                                                        vec![
                                                            MoneyMapUserModel::new(OutUserModel::new(user), true)
                                                        ]
                                                    ));
                                                }
                                            }

                                            ApiResult::Success{result:money_map}
                                        },
                                        Err(e) => {
                                            error!("{}",e);
                                            ApiResult::Failure{msg:"Unable to create money map"}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:money_map}
                                }
                            },
                            Err(e) => {
                                error!("{}",e);
                                ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                            }
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        ApiResult::Failure{msg:"Unable to interact with database"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end create

    /// Modify Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the modified user
    pub fn modify(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {

                match req.json_as::<MoneyMapModel>(){
                    Ok(edit_money_map) => {
                        // Get Money Map
                        if let Some(mm_id) = edit_money_map.get_id(){
                            let filter = doc!{
                                "_id" => mm_id,
                                "users.user_id" => user_id
                            };

                            if let Some(money_map) = dao.find_one(Some(filter), None){

                            // Verify User has access

                            // Validate
                                let validation_result = edit_money_map.validate();
                                if validation_result.is_valid(){
                                    // Save
                                    match dao.update(&edit_money_map){
                                        Ok(result) => {
                                            ApiResult::Success{result:result}
                                        },
                                        Err(e) => {
                                            ApiResult::Failure{msg:e.get_message()}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:edit_money_map}
                                }

                            }else{
                                ApiResult::Failure{msg:"Unable to find Money Map"}
                            }
                        }else{
                            ApiResult::Failure{msg:"Invalid Money Map ID"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end modify

    /// Delete a Money Map
    ///
    /// # Arguments
    /// &self
    /// id - String
    ///
    /// # Returns
    /// `ApiResult<String>` - ApiResult
    pub fn delete(&self, id: &str) -> ApiResult<String>{
        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match dao.delete(id){
                    Ok(result) => {
                        if result.acknowledged && result.modified_count > 0 {
                            ApiResult::Success{result:"Successfully deleted money map".to_string()}
                        }else{
                            ApiResult::Failure{msg:"Unable to delete money map"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Malformed ID"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end delete

}
<commit_msg>Add user details to modified money map result<commit_after>// src/controllers/money_maps_controller.rs

/// Money Maps Controller

// Import
// External
use ::chrono::{DateTime, Duration, Local};
use ::nickel::{JsonBody, Request};
use ::bson::{Bson, Document};
use ::bson::oid::ObjectId;
use ::std::default::Default;
use ::crypto::sha2::Sha256;
use ::jwt::{Header, Registered, Token};
use ::rustc_serialize::hex::ToHex;
// Utilities
use ::common::api_result::ApiResult;
use ::common::config::Config;
use ::common::data_access::ServerData;
use ::common::mm_result::{MMResult, MMError, MMErrorKind};
use ::common::session as Session;
// DAO
use ::dao::dao_manager::DAOManager;
// Models
use ::models::user_model::{OutUserModel};
use ::models::money_map_model::{MoneyMapModel, MoneyMapUserModel};

#[derive(Clone)]
pub struct MoneyMapsController{
    dao_manager: DAOManager,
    config: Config
}

impl MoneyMapsController{

    pub fn new(dao_manager: DAOManager, config: Config) -> MoneyMapsController{
        MoneyMapsController{
            dao_manager: dao_manager,
            config: config
        }
    }

    /// Find All Money Maps belonging to the requesting user
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<Vec<MoneyMapModel>>` - ApiResult including a vector of money maps
    pub fn find(&self, req: &mut Request<ServerData>) -> ApiResult<Vec<MoneyMapModel>>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                //Get list of money maps for this user
                let mut money_maps = dao.find(Some(doc!{
                    "users.user_id" => user_id,
                    "deleted" => {
                        "$ne" => true
                    }
                }));

                // Get list of user details for each money map
                for i in 0..money_maps.len(){
                    match self.get_users_for_mm(&money_maps[i]){
                        Ok(users_list) => {
                            // Add the new list of user details to the money map
                            money_maps[i].set_users(Some(users_list));
                        },
                        Err(e) => {
                            return ApiResult::Failure{msg:e.get_message()};
                        }
                    }
                }

                // Return the list of money maps
                ApiResult::Success{result:money_maps}
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end find_all

    /// Create Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the create money map
    pub fn create(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        match req.json_as::<MoneyMapModel>(){
                            Ok(mut money_map) => {
                                // Validate
                                let validation_result = money_map.validate();
                                if validation_result.is_valid(){
                                    // Save User
                                    match dao.create(&money_map, user_id.clone()){
                                        Ok(result) => {
                                            // Set user ID
                                            match result.inserted_id{
                                                Some(id_wrapper) => {
                                                    match id_wrapper{
                                                        Bson::ObjectId(id) => money_map.set_id(id),
                                                        _ => {}
                                                    }
                                                },
                                                None => {}
                                            }
                                            // Add user details
                                            if let Ok(id) = ObjectId::with_string(user_id.as_str()){
                                                if let Some(user) = user_dao.find_one(Some(doc!{"_id" => id}), None){
                                                    money_map.set_users(Some(
                                                        vec![
                                                            MoneyMapUserModel::new(OutUserModel::new(user), true)
                                                        ]
                                                    ));
                                                }
                                            }

                                            ApiResult::Success{result:money_map}
                                        },
                                        Err(e) => {
                                            error!("{}",e);
                                            ApiResult::Failure{msg:"Unable to create money map"}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:money_map}
                                }
                            },
                            Err(e) => {
                                error!("{}",e);
                                ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                            }
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        ApiResult::Failure{msg:"Unable to interact with database"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end create

    /// Modify Money Map
    ///
    /// # Arguments
    /// &self
    /// req - nickel::Request
    ///
    /// # Returns
    /// `ApiResult<MoneyMapModel>` - ApiResult including the modified user
    pub fn modify(&self, req: &mut Request<ServerData>) -> ApiResult<MoneyMapModel>{

        let user_id = match Session::get_session_id(req){
            Ok(id) => id,
            Err(e) => {
                error!("{}",e.get_message().to_string());
                return ApiResult::Failure{msg:"Unable to retrieve session data."};
            }
        };

        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {

                match req.json_as::<MoneyMapModel>(){
                    Ok(edit_money_map) => {
                        // Get Money Map
                        if let Some(mm_id) = edit_money_map.get_id(){
                            let filter = doc!{
                                "_id" => mm_id,
                                "users.user_id" => user_id
                            };

                            if let Some(money_map) = dao.find_one(Some(filter), None){

                            // Verify User has access

                            // Validate
                                let validation_result = edit_money_map.validate();
                                if validation_result.is_valid(){
                                    // Save
                                    match dao.update(&edit_money_map){
                                        Ok(mut updated_mm) => {
                                            match self.get_users_for_mm(&updated_mm){
                                                Ok(users_list) => {
                                                    // Add the new list of user details to the money map
                                                    updated_mm.set_users(Some(users_list));
                                                    ApiResult::Success{result:updated_mm}
                                                },
                                                Err(e) => {
                                                    ApiResult::Success{result:updated_mm}
                                                }
                                            }
                                        },
                                        Err(e) => {
                                            ApiResult::Failure{msg:e.get_message()}
                                        }
                                    }
                                }else{
                                    ApiResult::Invalid{validation:validation_result, request:edit_money_map}
                                }

                            }else{
                                ApiResult::Failure{msg:"Unable to find Money Map"}
                            }
                        }else{
                            ApiResult::Failure{msg:"Invalid Money Map ID"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Invalid format. Unable to parse data."}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end modify

    /// Delete a Money Map
    ///
    /// # Arguments
    /// &self
    /// id - String
    ///
    /// # Returns
    /// `ApiResult<String>` - ApiResult
    pub fn delete(&self, id: &str) -> ApiResult<String>{
        match self.dao_manager.get_money_map_dao(){
            Ok(dao) => {
                match dao.delete(id){
                    Ok(result) => {
                        if result.acknowledged && result.modified_count > 0 {
                            ApiResult::Success{result:"Successfully deleted money map".to_string()}
                        }else{
                            ApiResult::Failure{msg:"Unable to delete money map"}
                        }
                    },
                    Err(e) => {
                        error!("{}",e);
                        ApiResult::Failure{msg:"Malformed ID"}
                    }
                }
            },
            Err(e) => {
                error!("{}",e.get_message().to_string());
                ApiResult::Failure{msg:"Unable to interact with database"}
            }
        }
    }// end delete

    fn get_users_for_mm(&self, money_map: &MoneyMapModel) -> MMResult<Vec<MoneyMapUserModel>>{
        // Initialze a list of user details for this money map
        let mut users_list = Vec::new();
        if let Some(mm_users) = money_map.get_users(){

            // For each user associated with this money map
            for mm_user in mm_users{
                match self.dao_manager.get_user_dao(){
                    Ok(user_dao) => {

                        // Fetch the user's details
                        let user_id = Bson::ObjectId(mm_user.user.unwrap().id.unwrap());
                        let found_user = user_dao.find_one(Some(doc!{
                            "_id" => user_id
                        }), None);
                        if let Some(user) = found_user{
                            // Add the user details to the list
                            users_list.push(
                                MoneyMapUserModel::new(OutUserModel::new(user), mm_user.owner)
                            );
                        }
                    },
                    Err(e) => {
                        error!("{}",e.get_message().to_string());
                        return Err(MMError::new("Unable to interact with database", MMErrorKind::Controller));
                    }
                }
            }
        }
        Ok(users_list)
    }
}
<|endoftext|>


<commit_before>use docopt::Docopt;
use radeco_lib;
use errors::ArgError;
use rustc_serialize::json;
use structs;
use std::fs::{File};
use std::io::{Write, Read};

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [options] [<file>]
  radeco run [options] [<file>]

Options:
  --config <json_file>     Run decompilation using json rules file.
  --make-config <file>     Wizard to make the JSON config.
  -a --address=<addr>      Address of function to decompile.
  -e --esil=<esil_expr>    Evaluate given esil expression.
  -o --output=<output>     Specify output directory.
  -p --pipeline=<pipe>     Stages in the pipeline. Comma separated values.
                           Prefix the string with '=' (such as =ssa)
                           to obtain the output the stage.
                           Valid values: c,C,r2,ssa,cfg,const,dce,verify
  -q --quiet               Display silent output.
  -s --shell               Run interactive prompt.
  -v --version             Show version.
  -h --help                Show this screen.
";

#[derive(Debug, RustcDecodable)]
struct Args {
	arg_esil_expr: Option<Vec<String>>,
	arg_file: Option<String>,
	cmd_run: bool,
	flag_address: Option<String>,
	flag_config: Option<String>,
	flag_help: bool,
	flag_make_config: bool,
	flag_shell: bool,
	flag_quiet: bool,
	flag_version: bool,
	flag_output: Option<String>,
	flag_esil: Option<Vec<String>>,
	flag_pipeline: Option<String>,
}

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub type ArgResult<T> = Option<Result<T, ArgError>>;

fn json_slurp(fname: String) -> Result<structs::Input, ArgError> {
	let mut fh = try!(File::open(fname));
	let mut raw_json = String::new();
	try!(fh.read_to_string(&mut raw_json));
	json::decode(&*raw_json).map_err(|x| ArgError::DecodeError(x))
}

fn make_config() -> structs::Input {
	structs::input_builder()
}

fn write_file(fname: String, res: String) {
	let mut file = File::create(fname).unwrap();
	file.write_all(res.as_bytes()).unwrap();
}

#[allow(dead_code)]
pub struct Radeco {
	bin_name: Option<String>,
	esil: Option<Vec<String>>,
	addr: String,
	name: Option<String>,
	outpath: String,
	stages: Vec<usize>,
	quiet: bool,
	runner: Option<radeco_lib::utils::Runner>,
	outmodes: Option<Vec<u16>>,
}

impl Radeco {
	pub fn new(input: structs::Input) -> ArgResult<Radeco> {
		let runner = input.validate();
		if runner.is_err() {
			return Some(Err(runner.err().unwrap()));
		}

		let radeco = Radeco {
			bin_name: input.bin_name.clone(),
			esil: input.esil.clone(),
			addr: input.addr.clone().unwrap(),
			name: input.name.clone(),
			outpath: input.outpath.clone().unwrap(),
			stages: input.stages.clone(),
			quiet: input.quiet.clone().unwrap(),
			runner: runner.ok(),
			outmodes: input.outmodes.clone(),
		};

		Some(Ok(radeco))
	}

	pub fn init() -> ArgResult<Radeco> {
		let args: Args = Docopt::new(USAGE)
			.and_then(|d| d.decode())
			.unwrap_or_else(|e| e.exit());

		if args.flag_version {
			println!("Version: {:?}", VERSION);
			return None;
		} else if args.flag_help {
			println!("{}", USAGE);
			return None;
		}

		// Make config file and run radeco with it
		if args.flag_make_config {
			let input = make_config();
			{
				let mut name = input.name.clone().unwrap();
				let json = json::as_pretty_json(&input);
				let raw_json = format!("{}", json);
				name.push_str(".json");
				write_file(name, raw_json);
			}
			return Radeco::new(input);
		}

		// Run from a predefined configuration file
		if args.flag_config.is_some() {
			let filename = args.flag_config.clone().unwrap();
			let input = json_slurp(filename);
			if input.is_err() {
				return Some(Err(input.err().unwrap()))
			}
			return Radeco::new(input.unwrap());
		}

		let mut input = structs::Input::defaults();

		if args.arg_file.is_some() {
			input.bin_name = args.arg_file;
		}
		if args.flag_address.is_some() {
			input.addr = args.flag_address;
		}
		if args.flag_esil.is_some() {
			input.esil = args.flag_esil;
		}
		input.quiet = Some(!args.flag_quiet);
		if args.flag_output.is_some() {
			input.outpath = args.flag_output;
		}

		if args.flag_pipeline.is_some() {
			let mut i = 0;
			let pipe = args.flag_pipeline.unwrap();
			{
				let mut _tmp_stages = Vec::<usize>::new();
				let mut _tmp_out = Vec::<u16>::new();
				for stage in pipe.split(',') {
					let mut j = 0;
					if stage.chars().nth(0).unwrap() == '=' {
						_tmp_out.push(i);
						j = 1;
					}
					let n = match &stage[j..] {
						"c" | "C" => 7,
						"r2" => 0,
						"esil" => 1,
						"cfg" => 2,
						"ssa" => 3,
						"const" => 4,
						"dce" => 5,
						"verify" => 6,
						_ => {
							let e = format!("Invalid expression {} in stages", stage[1..].to_owned());
							panic!(e)
						},
					};
					_tmp_stages.push(n);
					i += 1;
				}
				input.stages = _tmp_stages;
				input.outmodes = Some(_tmp_out);
			}
		}

		Radeco::new(input)
	}

	pub fn run(&mut self) -> Result<(), String> {
		match self.runner.as_mut(){
			Some(ref mut runner) => {
				if runner.is_verbose() {
					println!("[*] Starting radeco with config: ");
					println!("{}", runner);
				}
				runner.run()
			},
			None => panic!("Uninitialized instance of radeco!"),
		}
		Ok(())
	}

	pub fn output(&mut self) {
		match self.runner.as_mut() {
			Some(ref mut runner) => {
				runner.output(self.outmodes.clone());
			},
			None => panic!("Uninitialized instance of radeco!"),
		}
	}
}
<commit_msg>Fixes #9. Use +/- for inclusion/exclusion rather than '='<commit_after>use docopt::Docopt;
use radeco_lib;
use errors::ArgError;
use rustc_serialize::json;
use structs;
use std::fs::{File};
use std::io::{Write, Read};

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [options] [<file>]
  radeco run [options] [<file>]

Options:
  --config <json_file>     Run decompilation using json rules file.
  --make-config <file>     Wizard to make the JSON config.
  -a --address=<addr>      Address of function to decompile.
  -e --esil=<esil_expr>    Evaluate given esil expression.
  -o --output=<output>     Specify output directory.
  -p --pipeline=<pipe>     Stages in the pipeline. Comma separated values.
                           Prefix the string with '=' (such as =ssa)
                           to obtain the output the stage.
                           Valid values: c,C,r2,ssa,cfg,const,dce,verify
  -q --quiet               Display silent output.
  -s --shell               Run interactive prompt.
  -v --version             Show version.
  -h --help                Show this screen.
";

#[derive(Debug, RustcDecodable)]
struct Args {
	arg_esil_expr:    Option<Vec<String>>,
	arg_file:         Option<String>,
	cmd_run:          bool,
	flag_address:     Option<String>,
	flag_config:      Option<String>,
	flag_help:        bool,
	flag_make_config: bool,
	flag_shell:       bool,
	flag_quiet:       bool,
	flag_version:     bool,
	flag_output:      Option<String>,
	flag_esil:        Option<Vec<String>>,
	flag_pipeline:    Option<String>,
}

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

pub type ArgResult<T> = Option<Result<T, ArgError>>;

fn json_slurp(fname: String) -> Result<structs::Input, ArgError> {
	let mut fh = try!(File::open(fname));
	let mut raw_json = String::new();
	try!(fh.read_to_string(&mut raw_json));
	json::decode(&*raw_json).map_err(|x| ArgError::DecodeError(x))
}

fn make_config() -> structs::Input {
	structs::input_builder()
}

fn write_file(fname: String, res: String) {
	let mut file = File::create(fname).unwrap();
	file.write_all(res.as_bytes()).unwrap();
}

#[allow(dead_code)]
pub struct Radeco {
	bin_name: Option<String>,
	esil:     Option<Vec<String>>,
	addr:     String,
	name:     Option<String>,
	outpath:  String,
	stages:   Vec<usize>,
	quiet:    bool,
	runner:   Option<radeco_lib::utils::Runner>,
	outmodes: Option<Vec<u16>>,
}

impl Radeco {
	pub fn new(input: structs::Input) -> ArgResult<Radeco> {
		let runner = input.validate();
		if runner.is_err() {
			return Some(Err(runner.err().unwrap()));
		}

		let radeco = Radeco {
			bin_name: input.bin_name.clone(),
			esil: input.esil.clone(),
			addr: input.addr.clone().unwrap(),
			name: input.name.clone(),
			outpath: input.outpath.clone().unwrap(),
			stages: input.stages.clone(),
			quiet: input.quiet.clone().unwrap(),
			runner: runner.ok(),
			outmodes: input.outmodes.clone(),
		};

		Some(Ok(radeco))
	}

	pub fn init() -> ArgResult<Radeco> {
		let args: Args = Docopt::new(USAGE)
			.and_then(|d| d.decode())
			.unwrap_or_else(|e| e.exit());

		if args.flag_version {
			println!("Version: {:?}", VERSION);
			return None;
		} else if args.flag_help {
			println!("{}", USAGE);
			return None;
		}

		// Make config file and run radeco with it
		if args.flag_make_config {
			let input = make_config();
			{
				let mut name = input.name.clone().unwrap();
				let json = json::as_pretty_json(&input);
				let raw_json = format!("{}", json);
				name.push_str(".json");
				write_file(name, raw_json);
			}
			return Radeco::new(input);
		}

		// Run from a predefined configuration file
		if args.flag_config.is_some() {
			let filename = args.flag_config.clone().unwrap();
			let input = json_slurp(filename);
			if input.is_err() {
				return Some(Err(input.err().unwrap()))
			}
			return Radeco::new(input.unwrap());
		}

		let mut input = structs::Input::defaults();

		if args.arg_file.is_some() {
			input.bin_name = args.arg_file;
		}
		if args.flag_address.is_some() {
			input.addr = args.flag_address;
		}
		if args.flag_esil.is_some() {
			input.esil = args.flag_esil;
		}
		input.quiet = Some(!args.flag_quiet);
		if args.flag_output.is_some() {
			input.outpath = args.flag_output;
		}

		if args.flag_pipeline.is_some() {
			let pipe = args.flag_pipeline.unwrap();
			{
				let mut _tmp_stages = Vec::<usize>::new();
				let mut exclude = Vec::<u16>::new();
				for (i, stage) in pipe.split(',').enumerate() {
					let j = match stage.chars().nth(0).unwrap() {
						'-' => {
							exclude.push(i as u16);
							1
						},
						'+' => 1,
						_   => 0,
					};

					let n = match &stage[j..] {
						"r2"      => 0,
						"esil"    => 1,
						"cfg"     => 2,
						"ssa"     => 3,
						"const"   => 4,
						"dce"     => 5,
						"verify"  => 6,
						"c"       => 7,
						_ => {
							let e = format!("Invalid expression {} in stages",
							                            stage[1..].to_owned());
							panic!(e)
						},
					};
					_tmp_stages.push(n);
				}

				let mut _tmp_out = Vec::<u16>::new();
				for i in (0..(pipe.len()-1) as u16) {
					if exclude.contains(&i) {
						continue;
					}
					_tmp_out.push(i);
				}

				input.stages = _tmp_stages;
				input.outmodes = Some(_tmp_out);
			}
		}

		Radeco::new(input)
	}

	pub fn run(&mut self) -> Result<(), String> {
		match self.runner.as_mut(){
			Some(ref mut runner) => {
				if runner.is_verbose() {
					println!("[*] Starting radeco with config: ");
					println!("{}", runner);
				}
				runner.run()
			},
			None => panic!("Uninitialized instance of radeco!"),
		}
		Ok(())
	}

	pub fn output(&mut self) {
		match self.runner.as_mut() {
			Some(ref mut runner) => {
				runner.output(self.outmodes.clone());
			},
			None => panic!("Uninitialized instance of radeco!"),
		}
	}
}
<|endoftext|>