<commit_before>//! The main entry point for the Space API server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate iron;
extern crate spaceapi;

pub mod datastore;
pub mod redis_store;

use std::net::Ipv4Addr;
use std::sync::Mutex;
use std::sync::Arc;

use rustc_serialize::json::{Json, ToJson};
use iron::{Request, Response, IronResult, Iron, Set};
use iron::{status, headers, middleware};
use iron::modifiers::Header;

pub use datastore::DataStore;
use spaceapi::Optional::{Value, Absent};

fn build_response_json(status: &spaceapi::Status, people_present: Option<u32>, raspi_temperature: Option<f32>) -> Json {
    let people_present_sensor = match people_present {
        Some(count) => Value(vec![
            spaceapi::PeopleNowPresentSensor {
                value: count,
                location: Value("Hackerspace".to_string()),
                name: Absent,
                description: Absent,
                names: Absent,
            }
        ]),
        None => Absent,
    };

    let temperature_sensor = match raspi_temperature {
        Some(degrees) => Value(vec![
            spaceapi::TemperatureSensor {
                value: degrees,
                unit: "°C".to_string(),
                location: "Basement".to_string(),
                name: Value("Raspberry CPU".to_string()),
                description: Absent,
            }
        ]),
        None => Absent,
    };

    // Create a mutable copy of the status struct and add sensor data.
    let mut status_copy = (*status).clone();
    status_copy.sensors = Value(spaceapi::Sensors {
        people_now_present: people_present_sensor,
        temperature: temperature_sensor,
    });

    // Serialize to JSON
    status_copy.to_json()
}

/// A specification of a sensor.
///
/// The ``sensor`` field contains the static data of a sensor and the
/// ``data_key`` says how to find the sensor value in the datastore.
pub struct SensorSpec {
    sensor: spaceapi::SensorTemplate,
    data_key: String,
}

/// A Space API server instance.
///
/// You can create a new instance using the ``new`` constructor method by
/// passing it the host, the port, the ``Status`` object and a datastore.
///
/// The ``SpaceapiServer`` includes a web server through
/// [Hyper](http://hyper.rs/hyper/hyper/server/index.html). Simply call the ``serve`` method.
pub struct SpaceapiServer {
    host: Ipv4Addr,
    port: u16,
    status: spaceapi::Status,
    datastore: Arc<Mutex<Box<DataStore>>>,
    sensors: Vec<SensorSpec>
}

impl SpaceapiServer {

    pub fn new(host: Ipv4Addr, port: u16, status: spaceapi::Status, datastore: Arc<Mutex<Box<DataStore>>>) -> SpaceapiServer {
        SpaceapiServer {
            host: host,
            port: port,
            status: status,
            datastore: datastore,
            sensors: vec![],
        }
    }

    /// Start a HTTP server listening on ``self.host:self.port``.
    ///
    /// This call is blocking. It can be interrupted with SIGINT (Ctrl+C).
    pub fn serve(self) {
        let host = self.host;
        let port = self.port;
        println!("Starting HTTP server on http://{}:{}...", host, port);
        Iron::new(self).http((host, port)).unwrap();
    }

    /// Register a new sensor.
    ///
    /// The first argument is a ``spaceapi::Sensor`` instance containing all static data. The
    /// second argument specifies how to get the actual sensor value from the datastore.
    pub fn register_sensor(&mut self, sensor: spaceapi::SensorTemplate, data_key: String) {
        self.sensors.push(
            SensorSpec { sensor: sensor, data_key: data_key }
        );
    }

}

impl middleware::Handler for SpaceapiServer {

    fn handle(&self, _: &mut Request) -> IronResult<Response> {

        // Fetch data from datastore
        let datastore_clone = self.datastore.clone();
        let datastore_lock = datastore_clone.lock().unwrap();
        let people_present: Option<u32> = match datastore_lock.retrieve("people_present") {
            Ok(v) => match v.parse::<u32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };
        let raspi_temperature: Option<f32> = match datastore_lock.retrieve("raspi_temperature") {
            Ok(v) => match v.parse::<f32>() {
                Ok(i) => Some(i),
                Err(_) => None,
            },
            Err(_) => None,
        };

        // Get response body
        let body = build_response_json(&self.status, people_present, raspi_temperature).to_string();

        // Create response
        let mut response = Response::with((status::Ok, body));

        // Set headers
        response.set_mut(Header(headers::ContentType("application/json; charset=utf-8".parse().unwrap())));
        response.set_mut(Header(headers::CacheControl(vec![headers::CacheDirective::NoCache])));
        response.set_mut(Header(headers::AccessControlAllowOrigin::Any));

        Ok(response)
    }
}

#[cfg(test)]
mod test {
    extern crate spaceapi;
    extern crate rustc_serialize;

    use super::build_response_json;
    use spaceapi::Optional;
    use rustc_serialize::json::Json;

    fn get_test_data() -> Json {
        // Create minimal status object
        let ref status = spaceapi::Status::new(
            "ourspace".to_string(),
            "https://example.com/logo.png".to_string(),
            "https://example.com/".to_string(),
            spaceapi::Location {
                address: Optional::Value("Street 1, Zürich, Switzerland".to_string()),
                lat: 47.123,
                lon: 8.88,
            },
            spaceapi::Contact {
                irc: Optional::Absent,
                twitter: Optional::Absent,
                foursquare: Optional::Absent,
                email: Optional::Value("hi@example.com".to_string()),
            },
            vec![
                "email".to_string(),
                "twitter".to_string(),
            ],
        );

        // Add sensor data, build JSON
        let people_present = Some(23);
        let temperature = Some(42.5);
        build_response_json(status, people_present, temperature)
    }

    #[test]
    /// Verify that the result is a JSON object.
    fn verify_json_obj() {
        let json = get_test_data();
        assert!(json.is_object());
    }

    #[test]
    /// Verify that the result has the correct keys.
    fn verify_json_keys() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>
        let keys: Vec<String> = status.keys().cloned().collect();  // Collect the keys
        assert_eq!(keys, ["api", "contact", "issue_report_channels", "location",
                          "logo", "sensors", "space", "state", "url"]);
    }

    #[test]
    /// Verify static data
    fn verify_json_static_data() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>

        // Strings
        assert_eq!(status.get("api").unwrap().as_string().unwrap(), "0.13");
        assert_eq!(status.get("space").unwrap().as_string().unwrap(), "ourspace");
        assert_eq!(status.get("url").unwrap().as_string().unwrap(), "https://example.com/");
        assert_eq!(status.get("logo").unwrap().as_string().unwrap(), "https://example.com/logo.png");

        // Channels
        let channels: &Vec<Json> = status.get("issue_report_channels").unwrap().as_array().unwrap();
        let channel_values: Vec<String> = channels.iter()
                                                  .cloned()
                                                  .map(|c| c.as_string().unwrap().to_string())
                                                  .collect();
        assert_eq!(vec!["email", "twitter"], channel_values);
    }

    #[test]
    /// Verify location
    fn verify_json_location() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let location = status.get("location").unwrap().as_object().unwrap();

        // Verify data
        let address = location.get("address").unwrap().as_string().unwrap();
        assert_eq!("Street 1, Zürich, Switzerland".to_string(), address);
        assert_eq!(47.123, location.get("lat").unwrap().as_f64().unwrap());
        assert_eq!(8.88, location.get("lon").unwrap().as_f64().unwrap());
    }

    #[test]
    /// Verify contact
    fn verify_json_contact() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let contact = status.get("contact").unwrap().as_object().unwrap();

        // Verify data
        let email = contact.get("email").unwrap().as_string().unwrap();
        assert_eq!("hi@example.com".to_string(), email);
    }

    #[test]
    /// Verify sensor data
    fn verify_json_sensors() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let sensors = status.get("sensors").unwrap().as_object().unwrap();
        let temperature_sensor = sensors.get("temperature").unwrap()
                                        .as_array().unwrap()[0]  // List of sensors
                                        .as_object().unwrap();  // Sensor object
        let people_sensor = sensors.get("people_now_present").unwrap()  // List of sensors
                                        .as_array().unwrap()[0]  // Sensor object
                                        .as_object().unwrap();

        // Verify temperature sensor
        let temp_location = temperature_sensor.get("location").unwrap().as_string().unwrap();
        let temp_name = temperature_sensor.get("name").unwrap().as_string().unwrap();
        let temp_unit = temperature_sensor.get("unit").unwrap().as_string().unwrap();
        let temp_value = temperature_sensor.get("value").unwrap().as_f64().unwrap();
        assert_eq!("Basement".to_string(), temp_location);
        assert_eq!("Raspberry CPU".to_string(), temp_name);
        assert_eq!("°C".to_string(), temp_unit);
        assert_eq!(42.5, temp_value);

        // Verify peoplesensor
        let people_location = people_sensor.get("location").unwrap().as_string().unwrap();
        let people_value = people_sensor.get("value").unwrap().as_u64().unwrap();
        assert_eq!("Hackerspace".to_string(), people_location);
        assert_eq!(23, people_value);
    }

}
<commit_msg>Implement sensor processing<commit_after>//! The main entry point for the Space API server.
//!
//! Running this code starts a HTTP server instance. The default port is 3000, but you can set your
//! own favorite port by exporting the `PORT` environment variable.

extern crate rustc_serialize;
extern crate iron;
extern crate spaceapi;

pub mod datastore;
pub mod redis_store;

use std::net::Ipv4Addr;
use std::sync::Mutex;
use std::sync::Arc;

use rustc_serialize::json::{Json, ToJson};
use iron::{Request, Response, IronResult, Iron, Set};
use iron::{status, headers, middleware};
use iron::modifiers::Header;

pub use datastore::DataStore;
use spaceapi::Optional::{Value, Absent};
use spaceapi::SensorTemplate::{PeopleNowPresentSensorTemplate, TemperatureSensorTemplate};

/// A specification of a sensor.
///
/// The ``sensor`` field contains the static data of a sensor and the
/// ``data_key`` says how to find the sensor value in the datastore.
#[derive(Debug)]
pub struct SensorSpec {
    sensor: spaceapi::SensorTemplate,
    data_key: String,
    data_type: SensorValueType,
}

/// All possible value types a sensor can have.
#[derive(Debug)]
pub enum SensorValueType {
    Int,
    Float,
    Bool,
}

/// The actual sensor values.
#[derive(Debug)]
pub enum SensorValue {
    Int(i64),
    Float(f64),
    Bool(bool),
}

/// A Space API server instance.
///
/// You can create a new instance using the ``new`` constructor method by
/// passing it the host, the port, the ``Status`` object and a datastore.
///
/// The ``SpaceapiServer`` includes a web server through
/// [Hyper](http://hyper.rs/hyper/hyper/server/index.html). Simply call the ``serve`` method.
pub struct SpaceapiServer {
    host: Ipv4Addr,
    port: u16,
    status: spaceapi::Status,
    datastore: Arc<Mutex<Box<DataStore>>>,
    sensors: Vec<SensorSpec>
}

impl SpaceapiServer {

    pub fn new(host: Ipv4Addr, port: u16, status: spaceapi::Status, datastore: Arc<Mutex<Box<DataStore>>>) -> SpaceapiServer {
        SpaceapiServer {
            host: host,
            port: port,
            status: status,
            datastore: datastore,
            sensors: vec![],
        }
    }

    /// Start a HTTP server listening on ``self.host:self.port``.
    ///
    /// This call is blocking. It can be interrupted with SIGINT (Ctrl+C).
    pub fn serve(self) {
        let host = self.host;
        let port = self.port;
        println!("Starting HTTP server on http://{}:{}...", host, port);
        Iron::new(self).http((host, port)).unwrap();
    }

    /// Register a new sensor.
    ///
    /// The first argument is a ``spaceapi::Sensor`` instance containing all static data. The
    /// second argument specifies how to get the actual sensor value from the datastore. And the
    /// third argument specifies the data type of the value.
    pub fn register_sensor(&mut self, sensor: spaceapi::SensorTemplate, data_key: String, data_type: SensorValueType) {
        self.sensors.push(
            SensorSpec { sensor: sensor, data_key: data_key, data_type: data_type }
        );
    }

    fn build_response_json(&self) -> Json {

        // Create a mutable copy of the status struct
        let mut status_copy = self.status.clone();

        // Prepare sensor vector
        let mut temperature_sensors: Vec<spaceapi::TemperatureSensor> = Vec::new();
        let mut people_now_present_sensors: Vec<spaceapi::PeopleNowPresentSensor> = Vec::new();

        // Process registered sensors
        if !self.sensors.is_empty() {

            // Get access to datastore
            let datastore_clone = self.datastore.clone();
            let datastore_lock = datastore_clone.lock().unwrap();

            // Add sensor data
            for sensor_spec in &self.sensors {

                // Retrieve sensor value
                let value: Option<SensorValue> = match datastore_lock.retrieve(&sensor_spec.data_key) {
                    Ok(v) => {
                        match sensor_spec.data_type {
                            SensorValueType::Float => match v.parse::<f64>() {
                                Ok(i) => Some(SensorValue::Float(i)),
                                Err(_) => None,
                            },
                            SensorValueType::Int => match v.parse::<i64>() {
                                Ok(i) => Some(SensorValue::Int(i)),
                                Err(_) => None,
                            },
                            SensorValueType::Bool => None,  // TODO
                        }
                    },
                    Err(_) => None,
                };

                // If value is available, save sensor data
                if value.is_some() {
                    match sensor_spec.sensor {

                        // Create temperature sensor instance
                        TemperatureSensorTemplate { ref unit, ref location, ref name, ref description } => {
                            let sensor = spaceapi::TemperatureSensor {
                                unit: (*unit).clone(),
                                location: (*location).clone(),
                                name: (*name).clone(),
                                description: (*description).clone(),
                                value: match value.unwrap() {
                                    SensorValue::Float(v) => v,
                                    _ => unreachable!(),
                                },
                            };
                            temperature_sensors.push(sensor);
                        },

                        // Create people now present sensor instance
                        PeopleNowPresentSensorTemplate { ref location, ref name, ref names, ref description } => {
                            let sensor = spaceapi::PeopleNowPresentSensor {
                                location: (*location).clone(),
                                name: (*name).clone(),
                                names: (*names).clone(),
                                description: (*description).clone(),
                                value: match value.unwrap() {
                                    SensorValue::Int(v) => v,
                                    _ => unreachable!(),
                                },
                            };
                            people_now_present_sensors.push(sensor);
                        },

                    }
                }

            }

        }

        // Add sensors to status object
        status_copy.sensors = Value(spaceapi::Sensors {
            people_now_present: match people_now_present_sensors.is_empty() {
                true => Absent,
                false => Value(people_now_present_sensors),
            },
            temperature: match temperature_sensors.is_empty() {
                true => Absent,
                false => Value(temperature_sensors),
            },
        });

        // Serialize to JSON
        status_copy.to_json()
    }

}

impl middleware::Handler for SpaceapiServer {

    fn handle(&self, _: &mut Request) -> IronResult<Response> {
        // Get response body
        let body = self.build_response_json().to_string();

        // Create response
        let mut response = Response::with((status::Ok, body));

        // Set headers
        response.set_mut(Header(headers::ContentType("application/json; charset=utf-8".parse().unwrap())));
        response.set_mut(Header(headers::CacheControl(vec![headers::CacheDirective::NoCache])));
        response.set_mut(Header(headers::AccessControlAllowOrigin::Any));

        Ok(response)
    }
}

#[cfg(test)]
mod test {
    extern crate spaceapi;
    extern crate rustc_serialize;

    use std::net::Ipv4Addr;
    use std::sync::{Mutex,Arc};
    use rustc_serialize::json::Json;
    use spaceapi::Optional;
    use super::SpaceapiServer;
    use super::datastore::DataStore;
    use super::redis_store::RedisStore;

    fn get_test_data() -> Json {
        // Create minimal status object
        let status = spaceapi::Status::new(
            "ourspace".to_string(),
            "https://example.com/logo.png".to_string(),
            "https://example.com/".to_string(),
            spaceapi::Location {
                address: Optional::Value("Street 1, Zürich, Switzerland".to_string()),
                lat: 47.123,
                lon: 8.88,
            },
            spaceapi::Contact {
                irc: Optional::Absent,
                twitter: Optional::Absent,
                foursquare: Optional::Absent,
                email: Optional::Value("hi@example.com".to_string()),
            },
            vec![
                "email".to_string(),
                "twitter".to_string(),
            ],
        );

        // Create datastore (TODO: Create dummy store for testing?)
        let datastore = Arc::new(Mutex::new(Box::new(RedisStore::new().unwrap()) as Box<DataStore>));

        // Initialize server
        let server = SpaceapiServer::new(Ipv4Addr::new(127, 0, 0, 1), 3001, status, datastore);

        // Build JSON
        server.build_response_json()
    }

    #[test]
    /// Verify that the result is a JSON object.
    fn verify_json_obj() {
        let json = get_test_data();
        assert!(json.is_object());
    }

    #[test]
    /// Verify that the result has the correct keys.
    fn verify_json_keys() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>
        let keys: Vec<String> = status.keys().cloned().collect();  // Collect the keys
        assert_eq!(keys, ["api", "contact", "issue_report_channels", "location",
                          "logo", "sensors", "space", "state", "url"]);
    }

    #[test]
    /// Verify static data
    fn verify_json_static_data() {
        let json = get_test_data();
        let status = json.as_object().unwrap();  // We get back a BTreeMap<String, Json>

        // Strings
        assert_eq!(status.get("api").unwrap().as_string().unwrap(), "0.13");
        assert_eq!(status.get("space").unwrap().as_string().unwrap(), "ourspace");
        assert_eq!(status.get("url").unwrap().as_string().unwrap(), "https://example.com/");
        assert_eq!(status.get("logo").unwrap().as_string().unwrap(), "https://example.com/logo.png");

        // Channels
        let channels: &Vec<Json> = status.get("issue_report_channels").unwrap().as_array().unwrap();
        let channel_values: Vec<String> = channels.iter()
                                                  .cloned()
                                                  .map(|c| c.as_string().unwrap().to_string())
                                                  .collect();
        assert_eq!(vec!["email", "twitter"], channel_values);
    }

    #[test]
    /// Verify location
    fn verify_json_location() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let location = status.get("location").unwrap().as_object().unwrap();

        // Verify data
        let address = location.get("address").unwrap().as_string().unwrap();
        assert_eq!("Street 1, Zürich, Switzerland".to_string(), address);
        assert_eq!(47.123, location.get("lat").unwrap().as_f64().unwrap());
        assert_eq!(8.88, location.get("lon").unwrap().as_f64().unwrap());
    }

    #[test]
    /// Verify contact
    fn verify_json_contact() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let contact = status.get("contact").unwrap().as_object().unwrap();

        // Verify data
        let email = contact.get("email").unwrap().as_string().unwrap();
        assert_eq!("hi@example.com".to_string(), email);
    }

    /* TODO: Update
    #[test]
    /// Verify sensor data
    fn verify_json_sensors() {
        let json = get_test_data();
        let status = json.as_object().unwrap();
        let sensors = status.get("sensors").unwrap().as_object().unwrap();
        let temperature_sensor = sensors.get("temperature").unwrap()
                                        .as_array().unwrap()[0]  // List of sensors
                                        .as_object().unwrap();  // Sensor object
        let people_sensor = sensors.get("people_now_present").unwrap()  // List of sensors
                                        .as_array().unwrap()[0]  // Sensor object
                                        .as_object().unwrap();

        // Verify temperature sensor
        let temp_location = temperature_sensor.get("location").unwrap().as_string().unwrap();
        let temp_name = temperature_sensor.get("name").unwrap().as_string().unwrap();
        let temp_unit = temperature_sensor.get("unit").unwrap().as_string().unwrap();
        let temp_value = temperature_sensor.get("value").unwrap().as_f64().unwrap();
        assert_eq!("Basement".to_string(), temp_location);
        assert_eq!("Raspberry CPU".to_string(), temp_name);
        assert_eq!("°C".to_string(), temp_unit);
        assert_eq!(42.5, temp_value);

        // Verify peoplesensor
        let people_location = people_sensor.get("location").unwrap().as_string().unwrap();
        let people_value = people_sensor.get("value").unwrap().as_u64().unwrap();
        assert_eq!("Hackerspace".to_string(), people_location);
        assert_eq!(23, people_value);
    }
    */

}
<|endoftext|>


<commit_before>//! Leaf is a open, fast and a well-designed, modular Framework for distributed
//! Deep Learning on {C, G}PUs.
//!
//! ## Overview
//!
//! To build a Deep Neural Network you create a [Network][network] which is a
//! container for all different types of [Layers][layers].
//! These layers are grouped in different types such as
//! [Activation Layers][activation] and [Loss Layers][loss] which states the
//! characteristics of the layer.
//!
//! Now to train your network you will use one of the [Solvers][solvers].
//! The Solver defines the [Optimization Method][optimization]
//! and keeps track on the learning progress.
//!
//! The operations can run on different Backends {CPU, GPU} and must not be
//! defined at compile time, which allows for easy backend swapping.
//!
//! ## Philosophy
//!
//! We are strong believers in the technology of Machine Learning.
//! We put our experience in
//! software engineering into Leaf, to solve our own need for a modern,
//! performant and easy-to-use Deep Learning Framework.
//! These principles direct our decisions on Leaf and related projects.
//!
//! * __Cutting Edge Performance__:

//! For research and industry speed and efficency are curcial for
//! state-of-the-art machine learning over massive data and networks.
//! * __Open and Expressive Architecture__:

//! Designing an open architecture that follows best practices and concepts in
//! Engineering such as modularity, flexibility and expressiveness is critical
//! to stimulate future innovation.
//! * __Clear and Transparent Documentation__:

//! A well-written documentation that addresses both concepts and
//! implementations, empowers developers and researchers to contribute their
//! unique experience to the project for the benefit of everyone.
//!
//! ## Examples
//!
//! ```
//! # extern crate leaf;
//! # use leaf::network::{NetworkConfig};
//! # fn main() {
//! # }
//! ```
//!
//! ## Development
//!
//! The implementation of various Layers is pretty scarce at the moment.

//! There are around a dozen layers, which are really important and would
//! increase the value and functionality of Leaf tremendously.

//! Progress is tracked at

//!
//! - [Issue #18 for Loss Layers][issue-loss]
//! - [Issue #19 for Activation Layers][issue-activation]
//! - [Issue #20 for Common Layers][issue-common]
//!
//! [network]: ./network/index.html
//! [layers]: ./layers/index.html
//! [activation]: ./layers/activation/index.html
//! [loss]: ./layers/loss/index.html
//! [solvers]: ./solvers/index.html
//! [optimization]: https://en.wikipedia.org/wiki/Stochastic_optimization
//!
//! [issue-loss]: https://github.com/autumnai/leaf/issues/18
//! [issue-activation]: https://github.com/autumnai/leaf/issues/19
//! [issue-common]: https://github.com/autumnai/leaf/issues/20
#![feature(plugin)]
#![feature(augmented_assignments)]
#![plugin(clippy)]
#![allow(dead_code)]
#![allow(unused_variables)]
#![deny(missing_docs,
        missing_debug_implementations, missing_copy_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code,
        unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate log;
extern crate rblas;
extern crate phloem;
pub mod shared_memory;
mod math;
pub mod layer;
pub mod layers;
pub mod solver;
pub mod solvers;
pub mod network;
<commit_msg>Auto merge of #27 - killercup:patch-1, r=hobofan<commit_after>//! Leaf is a open, fast and a well-designed, modular Framework for distributed
//! Deep Learning on {C, G}PUs.
//!
//! ## Overview
//!
//! To build a Deep Neural Network you first need to create a
//! [Network][network] which is a container for all different types of
//! [Layers][layers]. These layers are grouped in different types such as
//! [Activation Layers][activation] and [Loss Layers][loss] (these state the
//! characteristics of the layer).
//!
//! Now to train your network you can use one of the [Solvers][solvers]. The
//! Solver defines the [Optimization Method][optimization] and keeps track on
//! the learning progress.
//!
//! The operations can run on different Backends {CPU, GPU} and doesn't have
//! to be defined at compile time, which allows for easy backend swapping.
//!
//! ## Philosophy
//!
//! We are strong believers in the technology of Machine Learning.
//!
//! We put our experience in software engineering into Leaf, to solve our own
//! need for a modern, performant and easy-to-use Deep Learning Framework.
//! These principles direct our decisions on Leaf and related projects.
//!
//! * __Cutting Edge Performance__:

//! For research and industry speed and efficency are curcial for
//! state-of-the-art machine learning over massive data and networks.
//! * __Open and Expressive Architecture__:

//! Designing an open architecture that follows best practices and concepts in
//! Engineering such as modularity, flexibility and expressiveness is critical
//! to stimulate future innovation.
//! * __Clear and Transparent Documentation__:

//! A well-written documentation that addresses both concepts and
//! implementations, empowers developers and researchers to contribute their
//! unique experience to the project for the benefit of everyone.
//!
//! ## Examples
//!
//! ```
//! # extern crate leaf;
//! # use leaf::network::{NetworkConfig};
//! # fn main() {
//! # }
//! ```
//!
//! ## Development
//!
//! The implementation of various Layers is pretty scarce at the moment.

//! There are around a dozen layers, which are really important and would
//! increase the value and functionality of Leaf tremendously.

//! Progress is tracked at

//!
//! - [Issue #18 for Loss Layers][issue-loss]
//! - [Issue #19 for Activation Layers][issue-activation]
//! - [Issue #20 for Common Layers][issue-common]
//!
//! [network]: ./network/index.html
//! [layers]: ./layers/index.html
//! [activation]: ./layers/activation/index.html
//! [loss]: ./layers/loss/index.html
//! [solvers]: ./solvers/index.html
//! [optimization]: https://en.wikipedia.org/wiki/Stochastic_optimization
//!
//! [issue-loss]: https://github.com/autumnai/leaf/issues/18
//! [issue-activation]: https://github.com/autumnai/leaf/issues/19
//! [issue-common]: https://github.com/autumnai/leaf/issues/20
#![feature(plugin)]
#![feature(augmented_assignments)]
#![plugin(clippy)]
#![allow(dead_code)]
#![allow(unused_variables)]
#![deny(missing_docs,
        missing_debug_implementations, missing_copy_implementations,
        trivial_casts, trivial_numeric_casts,
        unsafe_code,
        unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate log;
extern crate rblas;
extern crate phloem;
pub mod shared_memory;
mod math;
pub mod layer;
pub mod layers;
pub mod solver;
pub mod solvers;
pub mod network;
<|endoftext|>


<commit_before>//! Provides the abstraction of a bit field, which allows for bit-level update and retrieval
//! operations.

#![no_std]

#[cfg(test)]
mod tests;

use core::ops::Range;

/// A generic trait which provides methods for extracting and setting specific bits or ranges of
/// bits.
pub trait BitField {

    /// Returns the length, eg number of bits, in this bit field.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// assert_eq!(u32::bit_length(), 32);
    /// assert_eq!(u64::bit_length(), 64);
    /// ```
    fn bit_length() -> u8;

    /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while
    /// index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let value: u32 = 0b110101;
    ///
    /// assert_eq!(value.get_bit(1), false);
    /// assert_eq!(value.get_bit(2), true);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of bounds of the bit field.
    fn get_bit(&self, bit: u8) -> bool;

    /// Obtains the range of bits specified by `range`; note that index 0 is the least significant
    /// bit, while index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let value: u32 = 0b110101;
    ///
    /// assert_eq!(value.get_bits(0..3), 0b101);
    /// assert_eq!(value.get_bits(2..6), 0b1101);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the start or end indexes of the range are out of bounds of the
    /// bit field.
    fn get_bits(&self, range: Range<u8>) -> Self;

    /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and
    /// false means a value of '0'); note that index 0 is the least significant bit, while index
    /// `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let mut value = 0u32;
    ///
    /// value.set_bit(1, true);
    /// assert_eq!(value, 2u32);
    ///
    /// value.set_bit(3, true);
    /// assert_eq!(value, 10u32);
    ///
    /// value.set_bit(1, false);
    /// assert_eq!(value, 8u32);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of the bounds of the bit field.
    fn set_bit(&mut self, bit: u8, value: bool) -> &mut Self;

    /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be
    /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of
    /// the other bits in `value` are set to 1, this function will panic.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let mut value = 0u32;
    ///
    /// value.set_bits(0..2, 0b11);
    /// assert_eq!(value, 0b11);
    ///
    /// value.set_bits(0..4, 0b1010);
    /// assert_eq!(value, 0b1010);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the range is out of bounds of the bit field, or if there are `1`s
    /// not in the lower N bits of `value`.
    fn set_bits(&mut self, range: Range<u8>, value: Self) -> &mut Self;
}

pub trait BitArray<T: BitField> {
    /// Returns the length, eg number of bits, in this bit array.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// assert_eq!([0u8, 4u8, 8u8].bit_length(), 24);
    /// assert_eq!([0u32, 5u32].bit_length(), 64);
    /// ```
    fn bit_length(&self) -> usize;

    /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while
    /// index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let value: [u32; 1] = [0b110101];
    ///
    /// assert_eq!(value.get_bit(1), false);
    /// assert_eq!(value.get_bit(2), true);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of bounds of the bit array.
    fn get_bit(&self, bit: usize) -> bool;

    /// Obtains the range of bits specified by `range`; note that index 0 is the least significant
    /// bit, while index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let value: [u32; 2] = [0b110101, 0b11];
    ///
    /// assert_eq!(value.get_bits(0..3), 0b101);
    /// assert_eq!(value.get_bits(31..33), 0b10);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the start or end indexes of the range are out of bounds of the
    /// bit array, or if the range can't be contained by the bit field T.
    fn get_bits(&self, range: Range<usize>) -> T;

    /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and
    /// false means a value of '0'); note that index 0 is the least significant bit, while index
    /// `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let mut value = [0u32];
    ///
    /// value.set_bit(1, true);
    /// assert_eq!(value, [2u32]);
    ///
    /// value.set_bit(3, true);
    /// assert_eq!(value, [10u32]);
    ///
    /// value.set_bit(1, false);
    /// assert_eq!(value, [8u32]);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of the bounds of the bit array.
    fn set_bit(&mut self, bit: usize, value: bool);

    /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be
    /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of
    /// the other bits in `value` are set to 1, this function will panic.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let mut value = [0u32, 0u32];
    ///
    /// value.set_bits(0..2, 0b11);
    /// assert_eq!(value, [0b11, 0u32]);
    ///
    /// value.set_bits(31..35, 0b1010);
    /// assert_eq!(value, [0x0003, 0b101]);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the range is out of bounds of the bit array,
    /// if the range can't be contained by the bit field T, or if there are `1`s
    /// not in the lower N bits of `value`.
    fn set_bits(&mut self, range: Range<usize>, value: T);
}

/// An internal macro used for implementing BitField on the standard integral types.
macro_rules! bitfield_numeric_impl {
    ($($t:ty)*) => ($(
        impl BitField for $t {
            fn bit_length() -> u8 {
                ::core::mem::size_of::<Self>() as u8 * 8
            }

            fn get_bit(&self, bit: u8) -> bool {
                assert!(bit < Self::bit_length());

                (*self & (1 << bit)) != 0
            }

            fn get_bits(&self, range: Range<u8>) -> Self {
                assert!(range.start < Self::bit_length());
                assert!(range.end <= Self::bit_length());
                assert!(range.start < range.end);

                // shift away high bits
                let bits = *self << (Self::bit_length() - range.end) >> (Self::bit_length() - range.end);

                // shift away low bits
                bits >> range.start
            }

            fn set_bit(&mut self, bit: u8, value: bool) -> &mut Self {
                assert!(bit < Self::bit_length());

                if value {
                    *self |= 1 << bit;
                } else {
                    *self &= !(1 << bit);
                }

                self
            }

            fn set_bits(&mut self, range: Range<u8>, value: Self) -> &mut Self {
                assert!(range.start < Self::bit_length());
                assert!(range.end <= Self::bit_length());
                assert!(range.start < range.end);
                assert!(value << (Self::bit_length() - (range.end - range.start)) >>
                        (Self::bit_length() - (range.end - range.start)) == value,
                        "value does not fit into bit range");

                let bitmask: Self = !(!0 << (Self::bit_length() - range.end) >>
                                    (Self::bit_length() - range.end) >>
                                    range.start << range.start);

                // set bits
                *self = (*self & bitmask) | (value << range.start);

                self
            }
        }
    )*)
}

bitfield_numeric_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

impl<T: BitField> BitArray<T> for [T] {
    fn bit_length(&self) -> usize {
        self.len() * (T::bit_length() as usize)
    }

    fn get_bit(&self, bit: usize) -> bool {
        let slice_index = bit / T::bit_length() as usize;
        let bit_index = (bit % T::bit_length() as usize) as u8;
        self[slice_index].get_bit(bit_index)
    }

    fn get_bits(&self, range: Range<usize>) -> T {
        assert!(range.len() <= T::bit_length() as usize);

        let slice_start = range.start/T::bit_length() as usize;
        let slice_end = range.end / T::bit_length() as usize;
        let bit_start = (range.start % T::bit_length() as usize) as u8;
        let bit_end = (range.end % T::bit_length() as usize) as u8;
        let len = range.len() as u8;

        assert!(slice_end - slice_start<= 1);

        if slice_start == slice_end {
            self[slice_start].get_bits(bit_start..bit_end)
        } else if bit_end == 0 {
            self[slice_start].get_bits(bit_start..T::bit_length())
        } else {
            let mut ret = self[slice_start].get_bits(bit_start..T::bit_length());
            ret.set_bits((T::bit_length() - bit_start)..len, self[slice_end].get_bits(0..bit_end));
            ret
        }
    }

    fn set_bit(&mut self, bit: usize, value: bool) {
        let slice_index = bit / T::bit_length() as usize;
        let bit_index = (bit % T::bit_length() as usize) as u8;
        self[slice_index].set_bit(bit_index, value);
    }

    fn set_bits(&mut self, range: Range<usize>, value: T) {
        assert!(range.len() <= T::bit_length() as usize);

        let slice_start = range.start/T::bit_length() as usize;
        let slice_end = range.end / T::bit_length() as usize;
        let bit_start = (range.start % T::bit_length() as usize) as u8;
        let bit_end = (range.end % T::bit_length() as usize) as u8;

        assert!(slice_end - slice_start<= 1);

        if slice_start == slice_end {
            self[slice_start].set_bits(bit_start..bit_end, value);
        } else if bit_end == 0 {
            self[slice_start].set_bits(bit_start..T::bit_length(), value);
        } else {
            self[slice_start].set_bits(bit_start..T::bit_length(), value.get_bits(0..T::bit_length()-bit_start));
            self[slice_end].set_bits(0..bit_end, value.get_bits(T::bit_length()-bit_start..T::bit_length()));
        }
    }

}

<commit_msg>Made BitField indexable with usize instead of u8 (#12)<commit_after>//! Provides the abstraction of a bit field, which allows for bit-level update and retrieval
//! operations.

#![no_std]

#[cfg(test)]
mod tests;

use core::ops::Range;

/// A generic trait which provides methods for extracting and setting specific bits or ranges of
/// bits.
pub trait BitField {

    /// Returns the length, eg number of bits, in this bit field.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// assert_eq!(u32::bit_length(), 32);
    /// assert_eq!(u64::bit_length(), 64);
    /// ```
    fn bit_length() -> usize;

    /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while
    /// index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let value: u32 = 0b110101;
    ///
    /// assert_eq!(value.get_bit(1), false);
    /// assert_eq!(value.get_bit(2), true);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of bounds of the bit field.
    fn get_bit(&self, bit: usize) -> bool;

    /// Obtains the range of bits specified by `range`; note that index 0 is the least significant
    /// bit, while index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let value: u32 = 0b110101;
    ///
    /// assert_eq!(value.get_bits(0..3), 0b101);
    /// assert_eq!(value.get_bits(2..6), 0b1101);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the start or end indexes of the range are out of bounds of the
    /// bit field.
    fn get_bits(&self, range: Range<usize>) -> Self;

    /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and
    /// false means a value of '0'); note that index 0 is the least significant bit, while index
    /// `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let mut value = 0u32;
    ///
    /// value.set_bit(1, true);
    /// assert_eq!(value, 2u32);
    ///
    /// value.set_bit(3, true);
    /// assert_eq!(value, 10u32);
    ///
    /// value.set_bit(1, false);
    /// assert_eq!(value, 8u32);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of the bounds of the bit field.
    fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self;

    /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be
    /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of
    /// the other bits in `value` are set to 1, this function will panic.
    ///
    /// ```rust
    /// use bit_field::BitField;
    ///
    /// let mut value = 0u32;
    ///
    /// value.set_bits(0..2, 0b11);
    /// assert_eq!(value, 0b11);
    ///
    /// value.set_bits(0..4, 0b1010);
    /// assert_eq!(value, 0b1010);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the range is out of bounds of the bit field, or if there are `1`s
    /// not in the lower N bits of `value`.
    fn set_bits(&mut self, range: Range<usize>, value: Self) -> &mut Self;
}

pub trait BitArray<T: BitField> {
    /// Returns the length, eg number of bits, in this bit array.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// assert_eq!([0u8, 4u8, 8u8].bit_length(), 24);
    /// assert_eq!([0u32, 5u32].bit_length(), 64);
    /// ```
    fn bit_length(&self) -> usize;

    /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while
    /// index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let value: [u32; 1] = [0b110101];
    ///
    /// assert_eq!(value.get_bit(1), false);
    /// assert_eq!(value.get_bit(2), true);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of bounds of the bit array.
    fn get_bit(&self, bit: usize) -> bool;

    /// Obtains the range of bits specified by `range`; note that index 0 is the least significant
    /// bit, while index `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let value: [u32; 2] = [0b110101, 0b11];
    ///
    /// assert_eq!(value.get_bits(0..3), 0b101);
    /// assert_eq!(value.get_bits(31..33), 0b10);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the start or end indexes of the range are out of bounds of the
    /// bit array, or if the range can't be contained by the bit field T.
    fn get_bits(&self, range: Range<usize>) -> T;

    /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and
    /// false means a value of '0'); note that index 0 is the least significant bit, while index
    /// `length() - 1` is the most significant bit.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let mut value = [0u32];
    ///
    /// value.set_bit(1, true);
    /// assert_eq!(value, [2u32]);
    ///
    /// value.set_bit(3, true);
    /// assert_eq!(value, [10u32]);
    ///
    /// value.set_bit(1, false);
    /// assert_eq!(value, [8u32]);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the bit index is out of the bounds of the bit array.
    fn set_bit(&mut self, bit: usize, value: bool);

    /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be
    /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of
    /// the other bits in `value` are set to 1, this function will panic.
    ///
    /// ```rust
    /// use bit_field::BitArray;
    ///
    /// let mut value = [0u32, 0u32];
    ///
    /// value.set_bits(0..2, 0b11);
    /// assert_eq!(value, [0b11, 0u32]);
    ///
    /// value.set_bits(31..35, 0b1010);
    /// assert_eq!(value, [0x0003, 0b101]);
    /// ```
    ///
    /// ## Panics
    ///
    /// This method will panic if the range is out of bounds of the bit array,
    /// if the range can't be contained by the bit field T, or if there are `1`s
    /// not in the lower N bits of `value`.
    fn set_bits(&mut self, range: Range<usize>, value: T);
}

/// An internal macro used for implementing BitField on the standard integral types.
macro_rules! bitfield_numeric_impl {
    ($($t:ty)*) => ($(
        impl BitField for $t {
            fn bit_length() -> usize {
                ::core::mem::size_of::<Self>() as usize * 8
            }

            fn get_bit(&self, bit: usize) -> bool {
                assert!(bit < Self::bit_length());

                (*self & (1 << bit)) != 0
            }

            fn get_bits(&self, range: Range<usize>) -> Self {
                assert!(range.start < Self::bit_length());
                assert!(range.end <= Self::bit_length());
                assert!(range.start < range.end);

                // shift away high bits
                let bits = *self << (Self::bit_length() - range.end) >> (Self::bit_length() - range.end);

                // shift away low bits
                bits >> range.start
            }

            fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self {
                assert!(bit < Self::bit_length());

                if value {
                    *self |= 1 << bit;
                } else {
                    *self &= !(1 << bit);
                }

                self
            }

            fn set_bits(&mut self, range: Range<usize>, value: Self) -> &mut Self {
                assert!(range.start < Self::bit_length());
                assert!(range.end <= Self::bit_length());
                assert!(range.start < range.end);
                assert!(value << (Self::bit_length() - (range.end - range.start)) >>
                        (Self::bit_length() - (range.end - range.start)) == value,
                        "value does not fit into bit range");

                let bitmask: Self = !(!0 << (Self::bit_length() - range.end) >>
                                    (Self::bit_length() - range.end) >>
                                    range.start << range.start);

                // set bits
                *self = (*self & bitmask) | (value << range.start);

                self
            }
        }
    )*)
}

bitfield_numeric_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

impl<T: BitField> BitArray<T> for [T] {
    fn bit_length(&self) -> usize {
        self.len() * T::bit_length()
    }

    fn get_bit(&self, bit: usize) -> bool {
        let slice_index = bit / T::bit_length();
        let bit_index = bit % T::bit_length();
        self[slice_index].get_bit(bit_index)
    }

    fn get_bits(&self, range: Range<usize>) -> T {
        assert!(range.len() <= T::bit_length());

        let slice_start = range.start/T::bit_length();
        let slice_end = range.end / T::bit_length();
        let bit_start = range.start % T::bit_length();
        let bit_end = range.end % T::bit_length();
        let len = range.len();

        assert!(slice_end - slice_start<= 1);

        if slice_start == slice_end {
            self[slice_start].get_bits(bit_start..bit_end)
        } else if bit_end == 0 {
            self[slice_start].get_bits(bit_start..T::bit_length())
        } else {
            let mut ret = self[slice_start].get_bits(bit_start..T::bit_length());
            ret.set_bits((T::bit_length() - bit_start)..len, self[slice_end].get_bits(0..bit_end));
            ret
        }
    }

    fn set_bit(&mut self, bit: usize, value: bool) {
        let slice_index = bit / T::bit_length();
        let bit_index = bit % T::bit_length();
        self[slice_index].set_bit(bit_index, value);
    }

    fn set_bits(&mut self, range: Range<usize>, value: T) {
        assert!(range.len() <= T::bit_length());

        let slice_start = range.start/T::bit_length();
        let slice_end = range.end / T::bit_length();
        let bit_start = range.start % T::bit_length();
        let bit_end = range.end % T::bit_length();

        assert!(slice_end - slice_start<= 1);

        if slice_start == slice_end {
            self[slice_start].set_bits(bit_start..bit_end, value);
        } else if bit_end == 0 {
            self[slice_start].set_bits(bit_start..T::bit_length(), value);
        } else {
            self[slice_start].set_bits(bit_start..T::bit_length(), value.get_bits(0..T::bit_length()-bit_start));
            self[slice_end].set_bits(0..bit_end, value.get_bits(T::bit_length()-bit_start..T::bit_length()));
        }
    }

}

<|endoftext|>


<commit_before>//! This is a library for controlling a cursor and a screen,
//! on ANSI terminals.
//!
//!
//! ## Example
//!
//!     use ansi_control::*;
//!

use std::cmp::Ordering;

/// A Pos is position of clearing (display|line) from cursor.
pub enum Pos {
    Back,
    Front,
    Both,
}

/// Moves the cursor _i_ (row), _j_ (column) cells. If the cursor
/// is already at the edge of the screen, this has no effect.
pub fn move_cursor(i: i32, j: i32) -> String {
    let code0 = match i.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}B", -i),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}A", i),
    };
    let code1 = match j.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}D", -j),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}C", j),
    };
    format!("{}{}", code0, code1)
}

/// Moves the cursor to beginning of the line _n_ lines down.
/// If _n_ is a negative number, this function moves the cursor
/// _|n|_ lines up.
pub fn move_line(n: i32) -> String {
    format!("")
}

/// Sets the column of the cursor. (n: column)
pub fn set_column(n: u32) -> String {
    format!("")
}

/// Sets the position of the cursor. (i: row, j: column)
pub fn set_position(i: u32, j: u32) -> String {
    format!("")
}

/// Clears part of screen. If pos is Pos::Back, clear from cursor
/// to the end of the screen. If pos is Pos::Front, clear from
/// cursor to beginning of the screen. If pos is Pos::Both, clear
/// entire screen.
pub fn clear_display(pos: Pos) -> String {
    format!("")
}

/// Clears part of line. If pos is Pos::Back, clear from cursor
/// to the end of the line. If pos is Pos::Front, clear from
/// cursor to beginning of the line. If pos is Pos::Both, clear
/// entire line.
pub fn clear_line(pos: Pos) -> String {
    format!("")
}

/// Scroll whole page up by _n_ lines. If _n_ is a negative
/// number, this function scroll whole page down by _|n|_ lines.
pub fn scroll(n: i32) -> String {
    format!("")
}

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

    macro_rules! test {
        ($name: ident; $ctrl: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, $ctrl)
            }
        };
    }

    test!(move_cursor0; move_cursor(2, -4) => "\x1B[2A\x1B[4D");
    test!(move_cursor1; move_cursor(-2, 0) => "\x1B[2B");
    test!(move_cursor2; move_cursor(0, 6) => "\x1B[6C");
    test!(move_cursor3; move_cursor(0, 0) => "");

    test!(move_line0; move_line(4) => "\x1B[4E");
    test!(move_line1; move_line(-4) => "\x1B[4F");

    test!(set_column0; set_column(3) => "\x1B[3G");
    test!(set_column1; set_column(0) => "\x1B[1G");

    test!(set_position0; set_position(3, 5) => "\x1B[3;5H");
    test!(set_position1; set_position(0, 0) => "\x1B[1;1H");

    test!(clear_display0; clear_display(Pos::Back) => "\x1B[0J");
    test!(clear_display1; clear_display(Pos::Front) => "\x1B[1J");
    test!(clear_display2; clear_display(Pos::Both) => "\x1B[2J");

    test!(clear_line0; clear_line(Pos::Back) => "\x1B[0K");
    test!(clear_line1; clear_line(Pos::Front) => "\x1B[1K");
    test!(clear_line2; clear_line(Pos::Both) => "\x1B[2K");

    test!(scroll0; scroll(7) => "\x1B[7S");
    test!(scroll1; scroll(-5) => "\x1B[5T");
}
<commit_msg>Improve move_line<commit_after>//! This is a library for controlling a cursor and a screen,
//! on ANSI terminals.
//!
//!
//! ## Example
//!
//!     use ansi_control::*;
//!

use std::cmp::Ordering;

/// A Pos is position of clearing (display|line) from cursor.
pub enum Pos {
    Back,
    Front,
    Both,
}

/// Moves the cursor _i_ (row), _j_ (column) cells. If the cursor
/// is already at the edge of the screen, this has no effect.
pub fn move_cursor(i: i32, j: i32) -> String {
    let code0 = match i.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}B", -i),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}A", i),
    };
    let code1 = match j.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}D", -j),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}C", j),
    };
    format!("{}{}", code0, code1)
}

/// Moves the cursor to beginning of the line _n_ lines down.
/// If _n_ is a negative number, this function moves the cursor
/// _|n|_ lines up.
pub fn move_line(n: i32) -> String {
    match n.cmp(&0) {
        Ordering::Less      => format!("\x1B[{}F", -n),
        Ordering::Equal     => format!(""),
        Ordering::Greater   => format!("\x1B[{}E", n),
    }
}

/// Sets the column of the cursor. (n: column)
pub fn set_column(n: u32) -> String {
    format!("")
}

/// Sets the position of the cursor. (i: row, j: column)
pub fn set_position(i: u32, j: u32) -> String {
    format!("")
}

/// Clears part of screen. If pos is Pos::Back, clear from cursor
/// to the end of the screen. If pos is Pos::Front, clear from
/// cursor to beginning of the screen. If pos is Pos::Both, clear
/// entire screen.
pub fn clear_display(pos: Pos) -> String {
    format!("")
}

/// Clears part of line. If pos is Pos::Back, clear from cursor
/// to the end of the line. If pos is Pos::Front, clear from
/// cursor to beginning of the line. If pos is Pos::Both, clear
/// entire line.
pub fn clear_line(pos: Pos) -> String {
    format!("")
}

/// Scroll whole page up by _n_ lines. If _n_ is a negative
/// number, this function scroll whole page down by _|n|_ lines.
pub fn scroll(n: i32) -> String {
    format!("")
}

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

    macro_rules! test {
        ($name: ident; $ctrl: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, $ctrl)
            }
        };
    }

    test!(move_cursor0; move_cursor(2, -4) => "\x1B[2A\x1B[4D");
    test!(move_cursor1; move_cursor(-2, 0) => "\x1B[2B");
    test!(move_cursor2; move_cursor(0, 6) => "\x1B[6C");
    test!(move_cursor3; move_cursor(0, 0) => "");

    test!(move_line0; move_line(4) => "\x1B[4E");
    test!(move_line1; move_line(-4) => "\x1B[4F");

    test!(set_column0; set_column(3) => "\x1B[3G");
    test!(set_column1; set_column(0) => "\x1B[1G");

    test!(set_position0; set_position(3, 5) => "\x1B[3;5H");
    test!(set_position1; set_position(0, 0) => "\x1B[1;1H");

    test!(clear_display0; clear_display(Pos::Back) => "\x1B[0J");
    test!(clear_display1; clear_display(Pos::Front) => "\x1B[1J");
    test!(clear_display2; clear_display(Pos::Both) => "\x1B[2J");

    test!(clear_line0; clear_line(Pos::Back) => "\x1B[0K");
    test!(clear_line1; clear_line(Pos::Front) => "\x1B[1K");
    test!(clear_line2; clear_line(Pos::Both) => "\x1B[2K");

    test!(scroll0; scroll(7) => "\x1B[7S");
    test!(scroll1; scroll(-5) => "\x1B[5T");
}
<|endoftext|>


<commit_before>pub mod error;
use error::Result;
use std::str::FromStr;

enum ExprType {
    Variable,
    Function0,
    Function1,
    Function2,
    Function3,
    Function4,
    Function5,
    Function6,
    Function7,
    Closure0,
    Closure1,
    Closure2,
    Closure3,
    Closure4,
    Closure5,
    Closure6,
    Closure7,
    FlagPure
}

#[derive(PartialEq)]
enum TokenType {
    Null,
    Error,
    End,
    Sep,
    Open,
    Close,
    Number,
    Variable,
    Infix
}

struct State {
    pub start: String,
    pub next: String,
    pub s_type: TokenType,
    pub value: f64,
}

fn find_lookup(s: &State, txt: &String) -> u8 {
    0
}

fn find_builtin(txt: &String) -> u8 {
    0
}

fn next_token(s: &mut State) -> Result<String> {
    s.s_type = TokenType::Null;

    let mut idx: usize = 0;

    while s.s_type == TokenType::Null {
        if idx == s.next.len() {
            s.s_type = TokenType::End;
            break;
        }

        let next_char = s.next.as_bytes()[idx] as char;
        // try reading a number
        if (next_char >= '0' && next_char <= '9') || next_char == '.' {
            let mut num_str = String::new();
            let mut c = next_char;

            // extract the number part to separate string which we then convert to f64
            while idx < s.next.len() && (next_char >= '0' && next_char <= '9') || c == '.' {
                c = s.next.as_bytes()[idx] as char;
                num_str.push(c);
                idx += 1;
            }
            s.value  = try!(f64::from_str(&num_str));
            s.s_type = TokenType::Number;
        } else {
            // look for a variable or builting function call
            if next_char >= 'a' && next_char <= 'z' {
                let mut txt_str = String::new();
                let mut c = next_char;

                while idx < s.next.len() && (next_char >= 'a' && next_char <= 'z') || (next_char >= '0' && next_char <= '9') {
                    c = s.next.as_bytes()[idx] as char;
                    txt_str.push(c);
                    idx += 1;
                }

                let mut var = find_lookup(&s, &txt_str);
                if var == 0 {
                   var = find_builtin(&txt_str);
                }

                if var == 0 {
                    s.s_type = TokenType::Error;
                } else {
                    // todo
                }
            } else {
                // look for an operator or special character
                match s.next.as_bytes()[idx] as char {
                    '+' => s.s_type = TokenType::Infix,
                    '-' => s.s_type = TokenType::Infix,
                    '*' => s.s_type = TokenType::Infix,
                    '/' => s.s_type = TokenType::Infix,
                    '^' => s.s_type = TokenType::Infix,
                    '%' => s.s_type = TokenType::Infix,
                    '(' => s.s_type = TokenType::Open,
                    ')' => s.s_type = TokenType::Close,
                    ',' => s.s_type = TokenType::Sep,
                    ' ' | '\t' | '\n' |'\r' => {},
                      _ => s.s_type = TokenType::Error
                }
                idx += 1;
            }
        }
    }

    Ok(String::new())
}

pub fn interp(expression: &str) -> Result<String> {
    Ok(String::new())
}

pub fn compile() {
}

pub fn eval() {
}
<commit_msg>further next_token impl<commit_after>#[macro_use]
extern crate bitflags;
pub mod error;
use error::Result;
use std::str::FromStr;

bitflags! {
    flags ExprType: u64 {
        const TE_VARIABLE = 0,
        const TE_FUNCTION0 = 8,
        const TE_FUNCTION1 = 9,
        const TE_FUNCTION2 = 10,
        const TE_FUNCTION3 = 11,
        const TE_FUNCTION4 = 12,
        const TE_FUNCTION5 = 13,
        const TE_FUNCTION6 = 14,
        const TE_FUNCTION7 = 15,
        const TE_CLOSURE0 = 16,
        const TE_CLOSURE1 = 17,
        const TE_CLOSURE2 = 18,
        const TE_CLOSURE3 = 19,
        const TE_CLOSURE4 = 20,
        const TE_CLOSURE5 = 21,
        const TE_CLOSURE6 = 22,
        const TE_CLOSURE7 = 23,
        const TE_FLAG_PURE = 32,
        const TOK_NULL = 24,
        const TOK_ERROR = 25,
        const TOK_END = 26,
        const TOK_SEP = 27,
        const TOK_OPEN = 28,
        const TOK_CLOSE = 29,
        const TOK_NUMBER = 30,
        const TOK_VARIABLE = 31,
        const TOK_INFIX = 32,
        const T_MASK = 0x0000001F
    }
}

struct Variable {
    pub name: String,
    pub address: i8,
    pub v_type: ExprType,
    pub context: i8,
}

impl Variable {
    fn new() -> Variable {
        Variable {
            name: String::new(),
            address: 0,
            v_type: TE_VARIABLE,
            context: 0
        }
    }
}

struct State {
    pub next: String,
    pub s_type: ExprType,
    pub n_idx: usize,
    pub value: f64,
    pub bound: i8,
    pub function: i8,
    pub context: i8
}

impl State {
    fn new() -> State {
        State {
            next: String::new(),
            s_type: TOK_NULL,
            n_idx: 0,
            value: 0.0,
            bound: 0,
            function: 0,
            context: 0
        }
    }
}

fn find_lookup(s: &State, txt: &String) -> Option<Variable> {
    Some(Variable::new())
}

fn find_builtin(s: &State, txt: &String) -> Option<Variable> {
    Some(Variable::new())
}

fn next_token(s: &mut State) -> Result<String> {
    s.s_type = TOK_NULL;

    while s.s_type == TOK_NULL {
        if s.n_idx == s.next.len() {
            s.s_type = TOK_END;
            break;
        }

        let next_char = s.next.as_bytes()[s.n_idx] as char;
        // try reading a number
        if (next_char >= '0' && next_char <= '9') || next_char == '.' {
            let mut num_str = String::new();
            let mut c = next_char;

            // extract the number part to separate string which we then convert to f64
            while s.n_idx < s.next.len() && (c >= '0' && c <= '9') || c == '.' {
                num_str.push(c);
                s.n_idx += 1;
                if s.n_idx < s.next.len() {
                    c = s.next.as_bytes()[s.n_idx] as char;
                }
            }
            s.value  = try!(f64::from_str(&num_str));
            s.s_type = TOK_NUMBER;
        } else {
            // look for a variable or builting function call
            if next_char >= 'a' && next_char <= 'z' {
                let mut txt_str = String::new();
                let mut c = next_char;

                while s.n_idx < s.next.len() && (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') {
                    txt_str.push(c);
                    s.n_idx += 1;
                    if s.n_idx < s.next.len() {
                        c = s.next.as_bytes()[s.n_idx] as char;
                    }
                }

                let mut var = find_lookup(&s, &txt_str);
                if let None = var {
                   var = find_builtin(&s, &txt_str);
                }

                if let Some(v) = var {
                    match s.s_type & T_MASK {
                        TE_VARIABLE => { s.s_type = TOK_VARIABLE; s.bound = v.address; },
                        TE_CLOSURE0 => s.context = v.context,
                        TE_CLOSURE1 => s.context = v.context,
                        TE_CLOSURE2 => s.context = v.context,
                        TE_CLOSURE3 => s.context = v.context,
                        TE_CLOSURE4 => s.context = v.context,
                        TE_CLOSURE5 => s.context = v.context,
                        TE_CLOSURE6 => s.context = v.context,
                        TE_CLOSURE7 => s.context = v.context,
                        TE_FUNCTION0 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION1 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION2 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION3 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION4 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION5 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION6 => { s.s_type = v.v_type; s.function = v.address; },
                        TE_FUNCTION7 => { s.s_type = v.v_type; s.function = v.address; },
                        _ => {}
                    }
                }
                else {
                    s.s_type = TOK_ERROR;
                }
            } else {
                // todo: set function
                // look for an operator or special character
                match s.next.as_bytes()[s.n_idx] as char {
                    '+' => s.s_type = TOK_INFIX,
                    '-' => s.s_type = TOK_INFIX,
                    '*' => s.s_type = TOK_INFIX,
                    '/' => s.s_type = TOK_INFIX,
                    '^' => s.s_type = TOK_INFIX,
                    '%' => s.s_type = TOK_INFIX,
                    '(' => s.s_type = TOK_OPEN,
                    ')' => s.s_type = TOK_CLOSE,
                    ',' => s.s_type = TOK_SEP,
                    ' ' | '\t' | '\n' |'\r' => {},
                      _ => s.s_type = TOK_ERROR
                }
                s.n_idx += 1;
            }
        }
    }

    Ok(String::new())
}

pub fn interp(expression: &str) -> Result<String> {
    Ok(String::new())
}

pub fn compile() {
}

pub fn eval() {
}
<|endoftext|>


<commit_before>// Copyright 2016 oauth-client-rs Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Performs topological sorting.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::hash::Hash;
use std::iter::FromIterator;

struct Dependency<T> {
    num_prec: usize,
    succ: HashSet<T>,
}

impl<T: Hash + Eq> Dependency<T> {
    fn new() -> Dependency<T> {
        Dependency {
            num_prec: 0,
            succ: HashSet::new(),
        }
    }
}

/// Performs topological sorting.
pub struct TopologicalSort<T> {
    top: HashMap<T, Dependency<T>>,
}

impl<T: Hash + Eq + Clone> TopologicalSort<T> {
    /// Creates new empty `TopologicalSort`.
    ///
    /// ```rust
    /// # extern crate topological_sort;
    /// # fn main() {
    /// use topological_sort::TopologicalSort;
    /// let mut ts = TopologicalSort::new();
    /// ts.add_dependency("hello_world.o", "hello_world");
    /// ts.add_dependency("hello_world.c", "hello_world");
    /// ts.add_dependency("stdio.h", "hello_world.o");
    /// ts.add_dependency("glibc.so", "hello_world");
    /// assert_eq!(vec!["glibc.so", "hello_world.c", "stdio.h"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert_eq!(vec!["hello_world.o"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert_eq!(vec!["hello_world"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert!(ts.pop_all().is_empty());
    /// # }
    /// ```
    #[inline]
    pub fn new() -> TopologicalSort<T> {
        TopologicalSort { top: HashMap::new() }
    }

    /// Returns the number of elements in the `TopologicalSort`.
    #[inline]
    pub fn len(&self) -> usize {
        self.top.len()
    }

    /// Returns true if the `TopologicalSort` contains no elements.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.top.is_empty()
    }

    /// Registers the two elements' dependency.
    ///
    /// # Arguments
    ///
    /// * `prec` - The element appears before `succ`. `prec` is depended on by `succ`.
    /// * `succ` - The element appears after `prec`. `succ` depends on `prec`.
    pub fn add_dependency(&mut self, prec: T, succ: T) {
        match self.top.entry(prec) {
            Entry::Vacant(e) => {
                let mut dep = Dependency::new();
                dep.succ.insert(succ.clone());
                let _ = e.insert(dep);
            }
            Entry::Occupied(e) => {
                if !e.into_mut().succ.insert(succ.clone()) {
                    // Already registered
                    return;
                }
            }
        }

        match self.top.entry(succ) {
            Entry::Vacant(e) => {
                let mut dep = Dependency::new();
                dep.num_prec += 1;
                let _ = e.insert(dep);
            }
            Entry::Occupied(e) => {
                e.into_mut().num_prec += 1;
            }
        }
    }

    /// Inserts an element, without adding any dependencies from or to it.
    ///
    /// If the `TopologicalSort` did not have this element present, `true` is returned.
    ///
    /// If the `TopologicalSort` already had this element present, `false` is returned.
    pub fn insert(&mut self, elt: T) -> bool {
        match self.top.entry(elt) {
            Entry::Vacant(e) => {
                let dep = Dependency::new();
                let _ = e.insert(dep);
                true
            }
            Entry::Occupied(_) => {
                false
            }
        }
    }

    /// Removes the item that is not depended on by any other items and returns it, or `None` if there is no such item.
    ///
    /// If `pop` returns `None` and `len` is not 0, there is cyclic dependencies.
    pub fn pop(&mut self) -> Option<T> {
        self.top
            .iter()
            .filter(|&(_, v)| v.num_prec == 0)
            .next()
            .map(|(k, _)| k.clone())
            .map(|key| {
                let _ = self.remove(&key);
                key
            })
    }

    /// Removes all items that are not depended on by any other items and returns it, or empty vector if there are no such items.
    ///
    /// If `pop_all` returns an empty vector and `len` is not 0, there is cyclic dependencies.
    pub fn pop_all(&mut self) -> Vec<T> {
        let keys = self.top
                       .iter()
                       .filter(|&(_, v)| v.num_prec == 0)
                       .map(|(k, _)| k.clone())
                       .collect::<Vec<_>>();
        for k in keys.iter() {
            let _ = self.remove(k);
        }
        keys
    }

    fn remove(&mut self, prec: &T) -> Option<Dependency<T>> {
        let result = self.top.remove(prec);
        if let Some(ref p) = result {
            for s in p.succ.iter() {
                if let Some(y) = self.top.get_mut(s) {
                    y.num_prec -= 1;
                }
            }
        }
        result
    }
}

impl<T: PartialOrd + Eq + Hash + Clone> FromIterator<T> for TopologicalSort<T> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> TopologicalSort<T> {
        let mut top = TopologicalSort::new();
        let mut seen = Vec::<T>::default();
        for item in iter {
            top.insert(item.clone());
            for seen_item in seen.iter().cloned() {
                match seen_item.partial_cmp(&item) {
                    Some(Ordering::Less) => { top.add_dependency(seen_item, item.clone()); }
                    Some(Ordering::Greater) => { top.add_dependency(item.clone(), seen_item); }
                    _ => ()
                }
            }
            seen.push(item);
        }
        top
    }
}

impl<T: Hash + Eq + Clone> Iterator for TopologicalSort<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.pop()
    }
}

#[cfg(test)]
mod test {
    use std::iter::FromIterator;

    use super::TopologicalSort;

    #[test]
    fn from_iter() {
        let t = vec![4, 3, 3, 5, 7, 6, 8];
        let mut ts = TopologicalSort::<i32>::from_iter(t);
        assert_eq!(Some(3), ts.next());
        assert_eq!(Some(4), ts.next());
        assert_eq!(Some(5), ts.next());
        assert_eq!(Some(6), ts.next());
        assert_eq!(Some(7), ts.next());
        assert_eq!(Some(8), ts.next());
        assert_eq!(None, ts.next());
    }

    #[test]
    fn iter() {
        let mut ts = TopologicalSort::<i32>::new();
        ts.add_dependency(1, 2);
        ts.add_dependency(2, 3);
        ts.add_dependency(3, 4);
        assert_eq!(Some(1), ts.next());
        assert_eq!(Some(2), ts.next());
        assert_eq!(Some(3), ts.next());
        assert_eq!(Some(4), ts.next());
        assert_eq!(None, ts.next());
    }

    #[test]
    fn pop_all() {
        fn check(result: &[i32], ts: &mut TopologicalSort<i32>) {
            let l = ts.len();
            let mut v = ts.pop_all();
            v.sort();
            assert_eq!(result, &v[..]);
            assert_eq!(l - result.len(), ts.len());
        }

        let mut ts = TopologicalSort::new();
        ts.add_dependency(7, 11);
        assert_eq!(2, ts.len());
        ts.add_dependency(7, 8);
        assert_eq!(3, ts.len());
        ts.add_dependency(5, 11);
        assert_eq!(4, ts.len());
        ts.add_dependency(3, 8);
        assert_eq!(5, ts.len());
        ts.add_dependency(3, 10);
        assert_eq!(6, ts.len());
        ts.add_dependency(11, 2);
        assert_eq!(7, ts.len());
        ts.add_dependency(11, 9);
        assert_eq!(8, ts.len());
        ts.add_dependency(11, 10);
        assert_eq!(8, ts.len());
        ts.add_dependency(8, 9);
        assert_eq!(8, ts.len());

        check(&[3, 5, 7], &mut ts);
        check(&[8, 11], &mut ts);
        check(&[2, 9, 10], &mut ts);
        check(&[], &mut ts);
    }
}
<commit_msg>Implement Debug<commit_after>// Copyright 2016 oauth-client-rs Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Performs topological sorting.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::hash::Hash;
use std::iter::FromIterator;

struct Dependency<T> {
    num_prec: usize,
    succ: HashSet<T>,
}

impl<T: Hash + Eq> Dependency<T> {
    fn new() -> Dependency<T> {
        Dependency {
            num_prec: 0,
            succ: HashSet::new(),
        }
    }
}

/// Performs topological sorting.
pub struct TopologicalSort<T> {
    top: HashMap<T, Dependency<T>>,
}

impl<T: Hash + Eq + Clone> TopologicalSort<T> {
    /// Creates new empty `TopologicalSort`.
    ///
    /// ```rust
    /// # extern crate topological_sort;
    /// # fn main() {
    /// use topological_sort::TopologicalSort;
    /// let mut ts = TopologicalSort::new();
    /// ts.add_dependency("hello_world.o", "hello_world");
    /// ts.add_dependency("hello_world.c", "hello_world");
    /// ts.add_dependency("stdio.h", "hello_world.o");
    /// ts.add_dependency("glibc.so", "hello_world");
    /// assert_eq!(vec!["glibc.so", "hello_world.c", "stdio.h"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert_eq!(vec!["hello_world.o"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert_eq!(vec!["hello_world"],
    ///            { let mut v = ts.pop_all(); v.sort(); v });
    /// assert!(ts.pop_all().is_empty());
    /// # }
    /// ```
    #[inline]
    pub fn new() -> TopologicalSort<T> {
        TopologicalSort { top: HashMap::new() }
    }

    /// Returns the number of elements in the `TopologicalSort`.
    #[inline]
    pub fn len(&self) -> usize {
        self.top.len()
    }

    /// Returns true if the `TopologicalSort` contains no elements.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.top.is_empty()
    }

    /// Registers the two elements' dependency.
    ///
    /// # Arguments
    ///
    /// * `prec` - The element appears before `succ`. `prec` is depended on by `succ`.
    /// * `succ` - The element appears after `prec`. `succ` depends on `prec`.
    pub fn add_dependency(&mut self, prec: T, succ: T) {
        match self.top.entry(prec) {
            Entry::Vacant(e) => {
                let mut dep = Dependency::new();
                dep.succ.insert(succ.clone());
                let _ = e.insert(dep);
            }
            Entry::Occupied(e) => {
                if !e.into_mut().succ.insert(succ.clone()) {
                    // Already registered
                    return;
                }
            }
        }

        match self.top.entry(succ) {
            Entry::Vacant(e) => {
                let mut dep = Dependency::new();
                dep.num_prec += 1;
                let _ = e.insert(dep);
            }
            Entry::Occupied(e) => {
                e.into_mut().num_prec += 1;
            }
        }
    }

    /// Inserts an element, without adding any dependencies from or to it.
    ///
    /// If the `TopologicalSort` did not have this element present, `true` is returned.
    ///
    /// If the `TopologicalSort` already had this element present, `false` is returned.
    pub fn insert(&mut self, elt: T) -> bool {
        match self.top.entry(elt) {
            Entry::Vacant(e) => {
                let dep = Dependency::new();
                let _ = e.insert(dep);
                true
            }
            Entry::Occupied(_) => {
                false
            }
        }
    }

    /// Removes the item that is not depended on by any other items and returns it, or `None` if there is no such item.
    ///
    /// If `pop` returns `None` and `len` is not 0, there is cyclic dependencies.
    pub fn pop(&mut self) -> Option<T> {
        self.top
            .iter()
            .filter(|&(_, v)| v.num_prec == 0)
            .next()
            .map(|(k, _)| k.clone())
            .map(|key| {
                let _ = self.remove(&key);
                key
            })
    }

    /// Removes all items that are not depended on by any other items and returns it, or empty vector if there are no such items.
    ///
    /// If `pop_all` returns an empty vector and `len` is not 0, there is cyclic dependencies.
    pub fn pop_all(&mut self) -> Vec<T> {
        let keys = self.top
                       .iter()
                       .filter(|&(_, v)| v.num_prec == 0)
                       .map(|(k, _)| k.clone())
                       .collect::<Vec<_>>();
        for k in keys.iter() {
            let _ = self.remove(k);
        }
        keys
    }

    fn remove(&mut self, prec: &T) -> Option<Dependency<T>> {
        let result = self.top.remove(prec);
        if let Some(ref p) = result {
            for s in p.succ.iter() {
                if let Some(y) = self.top.get_mut(s) {
                    y.num_prec -= 1;
                }
            }
        }
        result
    }
}

impl<T: PartialOrd + Eq + Hash + Clone> FromIterator<T> for TopologicalSort<T> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> TopologicalSort<T> {
        let mut top = TopologicalSort::new();
        let mut seen = Vec::<T>::default();
        for item in iter {
            top.insert(item.clone());
            for seen_item in seen.iter().cloned() {
                match seen_item.partial_cmp(&item) {
                    Some(Ordering::Less) => { top.add_dependency(seen_item, item.clone()); }
                    Some(Ordering::Greater) => { top.add_dependency(item.clone(), seen_item); }
                    _ => ()
                }
            }
            seen.push(item);
        }
        top
    }
}

impl<T: Hash + Eq + Clone> Iterator for TopologicalSort<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.pop()
    }
}

use std::fmt;

impl<T: fmt::Debug + Hash + Eq> fmt::Debug for Dependency<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "prec={}, succ={:?}", self.num_prec, self.succ)
    }
}

impl<T: fmt::Debug + Hash + Eq + Clone> fmt::Debug for TopologicalSort<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self.top)
    }
}

#[cfg(test)]
mod test {
    use std::iter::FromIterator;

    use super::TopologicalSort;

    #[test]
    fn from_iter() {
        let t = vec![4, 3, 3, 5, 7, 6, 8];
        let mut ts = TopologicalSort::<i32>::from_iter(t);
        assert_eq!(Some(3), ts.next());
        assert_eq!(Some(4), ts.next());
        assert_eq!(Some(5), ts.next());
        assert_eq!(Some(6), ts.next());
        assert_eq!(Some(7), ts.next());
        assert_eq!(Some(8), ts.next());
        assert_eq!(None, ts.next());
    }

    #[test]
    fn iter() {
        let mut ts = TopologicalSort::<i32>::new();
        ts.add_dependency(1, 2);
        ts.add_dependency(2, 3);
        ts.add_dependency(3, 4);
        assert_eq!(Some(1), ts.next());
        assert_eq!(Some(2), ts.next());
        assert_eq!(Some(3), ts.next());
        assert_eq!(Some(4), ts.next());
        assert_eq!(None, ts.next());
    }

    #[test]
    fn pop_all() {
        fn check(result: &[i32], ts: &mut TopologicalSort<i32>) {
            let l = ts.len();
            let mut v = ts.pop_all();
            v.sort();
            assert_eq!(result, &v[..]);
            assert_eq!(l - result.len(), ts.len());
        }

        let mut ts = TopologicalSort::new();
        ts.add_dependency(7, 11);
        assert_eq!(2, ts.len());
        ts.add_dependency(7, 8);
        assert_eq!(3, ts.len());
        ts.add_dependency(5, 11);
        assert_eq!(4, ts.len());
        ts.add_dependency(3, 8);
        assert_eq!(5, ts.len());
        ts.add_dependency(3, 10);
        assert_eq!(6, ts.len());
        ts.add_dependency(11, 2);
        assert_eq!(7, ts.len());
        ts.add_dependency(11, 9);
        assert_eq!(8, ts.len());
        ts.add_dependency(11, 10);
        assert_eq!(8, ts.len());
        ts.add_dependency(8, 9);
        assert_eq!(8, ts.len());

        check(&[3, 5, 7], &mut ts);
        check(&[8, 11], &mut ts);
        check(&[2, 9, 10], &mut ts);
        check(&[], &mut ts);
    }

    #[test]
    fn cyclic_deadlock() {
        let mut ts = TopologicalSort::new();
        ts.add_dependency("stone", "sharp");

        ts.add_dependency("bucket", "hole");
        ts.add_dependency("hole", "straw");
        ts.add_dependency("straw", "axe");
        ts.add_dependency("axe", "sharp");
        ts.add_dependency("sharp", "water");
        ts.add_dependency("water", "bucket");
        assert_eq!(ts.pop(), Some("stone"));
        assert!(ts.pop().is_none());
        println!("{:?}", ts);
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! tomson provides conversions from [Toml](http://alexcrichton.com/toml-rs) to [Json](https://doc.rust-lang.org/serialize/json/) and [Json](https://doc.rust-lang.org/serialize/json/) to [Toml](http://alexcrichton.com/toml-rs)

extern crate toml;
extern crate rustc_serialize;

use rustc_serialize::json::{ self, ToJson };
use std::collections::BTreeMap;
use std::io::Read;

/// Provides converstions from Json to Toml
pub struct Json;

impl Json {
  /// Convert Json to Toml
  pub fn as_toml(read: &mut Read) -> Result<toml::Value, json::ParserError> {
    let mut src = String::new();
    let _ = read.read_to_string(&mut src);
    let json = json::Json::from_str(&src);
    fn adapt(value: &json::Json) -> toml::Value {
      match *value {
        json::Json::I64(ref v)     => toml::Value::Integer(v.clone()),
        json::Json::U64(ref v)     => toml::Value::Integer(v.clone() as i64),
        json::Json::F64(ref v)     => toml::Value::Float(v.clone()),
        json::Json::String(ref v)  => toml::Value::String(v.clone()),
        json::Json::Boolean(ref v) => toml::Value::Boolean(v.clone()),
        json::Json::Array(ref v)   => {
          let mut tl = Vec::<toml::Value>::new();
          for jv in v.iter() {
            tl.push(adapt(jv));
          }
          toml::Value::Array(tl)
        },
        json::Json::Object(ref v)  => {
          let mut tm = BTreeMap::new();
          for (k,v) in v.iter() {
            tm.insert(k.clone(), adapt(v));
          }
          toml::Value::Table(tm)
        },
        json::Json::Null           => toml::Value::String("".to_string())
      }
    }
    json.map(|value| adapt(&value))
  }
}

/// Provides convertions from Toml to Json
pub struct Toml;

impl Toml {
  /// Convert Toml to Json
  pub fn as_json(read: &mut Read) -> Result<json::Json, Vec<toml::ParserError>> {
    let mut src = String::new();
    let _ = read.read_to_string(&mut src);
    let mut parser = toml::Parser::new(&src);

    fn adapt(toml: &toml::Value) -> json::Json {
      match *toml {
        toml::Value::Table(ref value)    => {
          let mut map = BTreeMap::new();
          for (k,v) in value.iter() {
            map.insert(k.to_string(), adapt(v));
          };
          map.to_json()
        },
        toml::Value::Array(ref array)    => {
          let mut vec = Vec::new();
          for value in array.iter() {
            vec.push(adapt(value));
          };
          vec.to_json()
        },
        toml::Value::String(ref value)   => value.to_json(),
        toml::Value::Integer(ref value)  => value.to_json(),
        toml::Value::Float(ref value)    => value.to_json(),
        toml::Value::Boolean(ref value)  => value.to_json(),
        toml::Value::Datetime(ref value) => value.to_json()
      }
    }

    match parser.parse() {
      Some(value) => Ok(adapt(&toml::Value::Table(value))),
      _ => Err(parser.errors)
    }
  }
}

#[cfg(test)]
mod tests {
  use super::{ Json, Toml };
  use std::io::BufReader;
  #[test]
  fn test_to_json() {
    let mut reader = BufReader::new("[foo.bar]\n\nbaz=1".as_bytes());
    let res = Toml::as_json(&mut reader);
    assert_eq!(res.is_some(), true)
  }
  #[test]
  fn test_to_toml() {
    let mut reader = BufReader::new(r#"{"foo":1}"#.as_bytes());
    let res = Json::as_toml(&mut reader);
    assert_eq!(res.is_some(), true)
  }
}
<commit_msg>fix tests<commit_after>#![deny(missing_docs)]

//! tomson provides conversions from [Toml](http://alexcrichton.com/toml-rs) to [Json](https://doc.rust-lang.org/serialize/json/) and [Json](https://doc.rust-lang.org/serialize/json/) to [Toml](http://alexcrichton.com/toml-rs)

extern crate toml;
extern crate rustc_serialize;

use rustc_serialize::json::{ self, ToJson };
use std::collections::BTreeMap;
use std::io::Read;

/// Provides converstions from Json to Toml
pub struct Json;

impl Json {
  /// Convert Json to Toml
  pub fn as_toml(read: &mut Read) -> Result<toml::Value, json::ParserError> {
    let mut src = String::new();
    let _ = read.read_to_string(&mut src);
    let json = json::Json::from_str(&src);
    fn adapt(value: &json::Json) -> toml::Value {
      match *value {
        json::Json::I64(ref v)     => toml::Value::Integer(v.clone()),
        json::Json::U64(ref v)     => toml::Value::Integer(v.clone() as i64),
        json::Json::F64(ref v)     => toml::Value::Float(v.clone()),
        json::Json::String(ref v)  => toml::Value::String(v.clone()),
        json::Json::Boolean(ref v) => toml::Value::Boolean(v.clone()),
        json::Json::Array(ref v)   => {
          let mut tl = Vec::<toml::Value>::new();
          for jv in v.iter() {
            tl.push(adapt(jv));
          }
          toml::Value::Array(tl)
        },
        json::Json::Object(ref v)  => {
          let mut tm = BTreeMap::new();
          for (k,v) in v.iter() {
            tm.insert(k.clone(), adapt(v));
          }
          toml::Value::Table(tm)
        },
        json::Json::Null           => toml::Value::String("".to_string())
      }
    }
    json.map(|value| adapt(&value))
  }
}

/// Provides convertions from Toml to Json
pub struct Toml;

impl Toml {
  /// Convert Toml to Json
  pub fn as_json(read: &mut Read) -> Result<json::Json, Vec<toml::ParserError>> {
    let mut src = String::new();
    let _ = read.read_to_string(&mut src);
    let mut parser = toml::Parser::new(&src);

    fn adapt(toml: &toml::Value) -> json::Json {
      match *toml {
        toml::Value::Table(ref value)    => {
          let mut map = BTreeMap::new();
          for (k,v) in value.iter() {
            map.insert(k.to_string(), adapt(v));
          };
          map.to_json()
        },
        toml::Value::Array(ref array)    => {
          let mut vec = Vec::new();
          for value in array.iter() {
            vec.push(adapt(value));
          };
          vec.to_json()
        },
        toml::Value::String(ref value)   => value.to_json(),
        toml::Value::Integer(ref value)  => value.to_json(),
        toml::Value::Float(ref value)    => value.to_json(),
        toml::Value::Boolean(ref value)  => value.to_json(),
        toml::Value::Datetime(ref value) => value.to_json()
      }
    }

    match parser.parse() {
      Some(value) => Ok(adapt(&toml::Value::Table(value))),
      _ => Err(parser.errors)
    }
  }
}

#[cfg(test)]
mod tests {
  use super::{ Json, Toml };
  use std::io::BufReader;
  #[test]
  fn test_to_json() {
    let mut reader = BufReader::new("[foo.bar]\n\nbaz=1".as_bytes());
    let res = Toml::as_json(&mut reader);
    assert_eq!(res.is_ok(), true)
  }
  #[test]
  fn test_to_toml() {
    let mut reader = BufReader::new(r#"{"foo":1}"#.as_bytes());
    let res = Json::as_toml(&mut reader);
    assert_eq!(res.is_ok(), true)
  }
}
<|endoftext|>


<commit_before><commit_msg>Fix typo<commit_after><|endoftext|>


<commit_before><commit_msg>Implement std::error::Error for PortMidiError<commit_after><|endoftext|>