<commit_before>// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_name = "gobject-2_0-sys"]
#![crate_type = "lib"]

#![allow(missing_copy_implementations)]

extern crate "glib-2_0-sys" as glib;

use glib::types::{gboolean, gchar, gdouble, gfloat, gint, glong};
use glib::types::{gsize, guchar, guint, gulong};
use glib::types::{gpointer, gconstpointer};

pub type GType = gsize;

#[repr(C)]
pub struct GTypeInstance {
    g_class: gpointer
}

#[repr(C)]
pub struct GObject {
    g_type_instance: GTypeInstance,
    ref_count: guint,
    data: gpointer
}

#[repr(C)]
pub struct GValue {
    pub g_type: GType,
    // If the data enum layout turns out to be different on some arch,
    // we'd need arch-specific redefinitions
    data: [u64; 2]
}

pub type GBoxedCopyFunc = extern "C" fn (gpointer) -> gpointer;
pub type GBoxedFreeFunc = extern "C" fn (gpointer);

extern {
    pub fn g_boxed_type_register_static(name: *const gchar, boxed_copy: GBoxedCopyFunc, boxed_free: GBoxedFreeFunc) -> GType;
    pub fn g_error_get_type() -> GType;
    pub fn g_main_context_get_type() -> GType;
    pub fn g_main_loop_get_type() -> GType;
    pub fn g_object_get_type() -> GType;
    pub fn g_object_ref(obj: gpointer) -> gpointer;
    pub fn g_object_unref(obj: gpointer);
    pub fn g_strdup_value_contents(value: *const GValue) -> *mut gchar;
    pub fn g_type_check_instance_is_a(instance: *const GTypeInstance, iface_type: GType) -> gboolean;
    pub fn g_type_from_name(name: *const gchar) -> GType;
    pub fn g_type_name(t: GType) -> *const gchar;
    pub fn g_value_copy(src: *const GValue, dst: *mut GValue);
    pub fn g_value_get_boolean(value: *const GValue) -> gboolean;
    pub fn g_value_get_boxed(value: *const GValue) -> gpointer;
    pub fn g_value_get_char(value: *const GValue) -> gchar;
    pub fn g_value_get_double(value: *const GValue) -> gdouble;
    pub fn g_value_get_float(value: *const GValue) -> gfloat;
    pub fn g_value_get_int(value: *const GValue) -> gint;
    pub fn g_value_get_int64(value: *const GValue) -> i64;
    pub fn g_value_get_long(value: *const GValue) -> glong;
    pub fn g_value_get_object(value: *const GValue) -> gpointer;
    pub fn g_value_get_schar(value: *const GValue) -> i8;
    pub fn g_value_get_string(value: *const GValue) -> *const gchar;
    pub fn g_value_get_uchar(value: *const GValue) -> guchar;
    pub fn g_value_get_uint(value: *const GValue) -> guint;
    pub fn g_value_get_uint64(value: *const GValue) -> u64;
    pub fn g_value_get_ulong(value: *const GValue) -> gulong;
    pub fn g_value_dup_boxed(value: *const GValue) -> gpointer;
    pub fn g_value_init(value: *mut GValue, type_id: GType) -> *mut GValue;
    pub fn g_value_reset(value: *mut GValue) -> *mut GValue;
    pub fn g_value_set_boolean(value: *mut GValue, v_boolean: gboolean);
    pub fn g_value_set_char(value: *mut GValue, v_char: gchar);
    pub fn g_value_set_double(value: *mut GValue, v_double: gdouble);
    pub fn g_value_set_float(value: *mut GValue, v_float: gfloat);
    pub fn g_value_set_int(value: *mut GValue, v_int: gint);
    pub fn g_value_set_int64(value: *mut GValue, v_int: i64);
    pub fn g_value_set_long(value: *mut GValue, v_long: glong);
    pub fn g_value_set_object(value: *mut GValue, v_object: gpointer);
    pub fn g_value_set_schar(value: *mut GValue, v_char: i8);
    pub fn g_value_set_string(value: *mut GValue, v_string: *const gchar);
    pub fn g_value_set_static_string(value: *mut GValue, v_string: *const gchar);
    pub fn g_value_set_uchar(value: *mut GValue, v_char: guchar);
    pub fn g_value_set_uint(value: *mut GValue, v_uint: guint);
    pub fn g_value_set_uint64(value: *mut GValue, v_uint: u64);
    pub fn g_value_set_ulong(value: *mut GValue, v_ulong: gulong);
    pub fn g_value_take_boxed(value: *mut GValue, v_boxed: gconstpointer);
    pub fn g_value_take_string(value: *mut GValue, v_string: *mut gchar);
    pub fn g_value_unset(value: *mut GValue);
}
<commit_msg>Added g_value_{get,set}_enum<commit_after>// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#![crate_name = "gobject-2_0-sys"]
#![crate_type = "lib"]

#![allow(missing_copy_implementations)]

extern crate "glib-2_0-sys" as glib;

use glib::types::{gboolean, gchar, gdouble, gfloat, gint, glong};
use glib::types::{gsize, guchar, guint, gulong};
use glib::types::{gpointer, gconstpointer};

pub type GType = gsize;

#[repr(C)]
pub struct GTypeInstance {
    g_class: gpointer
}

#[repr(C)]
pub struct GObject {
    g_type_instance: GTypeInstance,
    ref_count: guint,
    data: gpointer
}

#[repr(C)]
pub struct GValue {
    pub g_type: GType,
    // If the data enum layout turns out to be different on some arch,
    // we'd need arch-specific redefinitions
    data: [u64; 2]
}

pub type GBoxedCopyFunc = extern "C" fn (gpointer) -> gpointer;
pub type GBoxedFreeFunc = extern "C" fn (gpointer);

extern {
    pub fn g_boxed_type_register_static(name: *const gchar, boxed_copy: GBoxedCopyFunc, boxed_free: GBoxedFreeFunc) -> GType;
    pub fn g_error_get_type() -> GType;
    pub fn g_main_context_get_type() -> GType;
    pub fn g_main_loop_get_type() -> GType;
    pub fn g_object_get_type() -> GType;
    pub fn g_object_ref(obj: gpointer) -> gpointer;
    pub fn g_object_unref(obj: gpointer);
    pub fn g_strdup_value_contents(value: *const GValue) -> *mut gchar;
    pub fn g_type_check_instance_is_a(instance: *const GTypeInstance, iface_type: GType) -> gboolean;
    pub fn g_type_from_name(name: *const gchar) -> GType;
    pub fn g_type_name(t: GType) -> *const gchar;
    pub fn g_value_copy(src: *const GValue, dst: *mut GValue);
    pub fn g_value_get_boolean(value: *const GValue) -> gboolean;
    pub fn g_value_get_boxed(value: *const GValue) -> gpointer;
    pub fn g_value_get_char(value: *const GValue) -> gchar;
    pub fn g_value_get_double(value: *const GValue) -> gdouble;
    pub fn g_value_get_enum(value: *const GValue) -> gint;
    pub fn g_value_get_float(value: *const GValue) -> gfloat;
    pub fn g_value_get_int(value: *const GValue) -> gint;
    pub fn g_value_get_int64(value: *const GValue) -> i64;
    pub fn g_value_get_long(value: *const GValue) -> glong;
    pub fn g_value_get_object(value: *const GValue) -> gpointer;
    pub fn g_value_get_schar(value: *const GValue) -> i8;
    pub fn g_value_get_string(value: *const GValue) -> *const gchar;
    pub fn g_value_get_uchar(value: *const GValue) -> guchar;
    pub fn g_value_get_uint(value: *const GValue) -> guint;
    pub fn g_value_get_uint64(value: *const GValue) -> u64;
    pub fn g_value_get_ulong(value: *const GValue) -> gulong;
    pub fn g_value_dup_boxed(value: *const GValue) -> gpointer;
    pub fn g_value_init(value: *mut GValue, type_id: GType) -> *mut GValue;
    pub fn g_value_reset(value: *mut GValue) -> *mut GValue;
    pub fn g_value_set_boolean(value: *mut GValue, v_boolean: gboolean);
    pub fn g_value_set_char(value: *mut GValue, v_char: gchar);
    pub fn g_value_set_double(value: *mut GValue, v_double: gdouble);
    pub fn g_value_set_enum(value: *mut GValue, v_enum: gint);
    pub fn g_value_set_float(value: *mut GValue, v_float: gfloat);
    pub fn g_value_set_int(value: *mut GValue, v_int: gint);
    pub fn g_value_set_int64(value: *mut GValue, v_int: i64);
    pub fn g_value_set_long(value: *mut GValue, v_long: glong);
    pub fn g_value_set_object(value: *mut GValue, v_object: gpointer);
    pub fn g_value_set_schar(value: *mut GValue, v_char: i8);
    pub fn g_value_set_string(value: *mut GValue, v_string: *const gchar);
    pub fn g_value_set_static_string(value: *mut GValue, v_string: *const gchar);
    pub fn g_value_set_uchar(value: *mut GValue, v_char: guchar);
    pub fn g_value_set_uint(value: *mut GValue, v_uint: guint);
    pub fn g_value_set_uint64(value: *mut GValue, v_uint: u64);
    pub fn g_value_set_ulong(value: *mut GValue, v_ulong: gulong);
    pub fn g_value_take_boxed(value: *mut GValue, v_boxed: gconstpointer);
    pub fn g_value_take_string(value: *mut GValue, v_string: *mut gchar);
    pub fn g_value_unset(value: *mut GValue);
}
<|endoftext|>


<commit_before>use std::collections::HashSet;

#[derive(PartialEq, Debug)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

#[derive(Hash, PartialEq, Eq, Copy, Clone)]
pub struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn distance_to_origin(&self) -> u32 {
        (self.x.abs() + self.y.abs()) as u32
    }
}

pub fn distance(input: &str) -> u32 {
    let mut visited_locations = HashSet::new();

    let mut location = Point { x: 0, y: 0 };
    let mut direction = Direction::North;

    for instruction in input.split(", ") {
        let (turn_dir, num_blocks) = instruction.split_at(1);

        println!("Now processing ({}) ({})", turn_dir, num_blocks);
        direction = turn(direction, turn_dir);
        let num_blocks: i32 = num_blocks.to_string()
                                        .trim()
                                        .parse()
                                        .expect("Cannot parse");
        println!("Going {:?} {} blocks", direction, num_blocks);
        match direction {
            Direction::North => location.y += num_blocks,
            Direction::East  => location.x += num_blocks,
            Direction::South => location.y -= num_blocks,
            Direction::West  => location.x -= num_blocks,
        }

        if visited_locations.contains(&location) {
            return location.distance_to_origin();
        } else {
            visited_locations.insert(location);
        }
        println!("Location: ({}, {})", location.x, location.y);
    }
    panic!("No location visited twice.");
}

pub fn turn(initial_direction: Direction, turn_command: &str) -> Direction {
    match (turn_command, initial_direction) {
        ("L", Direction::North) => Direction::West,
        ("L", Direction::West) => Direction::South,
        ("L", Direction::South) => Direction::East,
        ("L", Direction::East) => Direction::North,

        ("R", Direction::North) => Direction::East,
        ("R", Direction::East) => Direction::South,
        ("R", Direction::South) => Direction::West,
        ("R", Direction::West) => Direction::North,

        (unknown_turn_command, dir) => panic!("\
            I don't know how to turn {} from {:?}!",
            unknown_turn_command,
            dir
        ),
    }
}

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

    #[test]
    fn hq_is_first_location_visited_twice() {
        assert_eq!(distance("R2, L1, L1, L1, L1, R5"), 1);
    }

    #[test]
    fn turn_left() {
        let mut dir = Direction::North;
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::North);
    }

    #[test]
    fn turn_right() {
        let mut dir = Direction::North;
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::North);
    }
}
<commit_msg>Update test to look for intersection of the path<commit_after>use std::collections::HashSet;

#[derive(PartialEq, Debug)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

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

impl Point {
    fn distance_to_origin(&self) -> u32 {
        (self.x.abs() + self.y.abs()) as u32
    }
}

pub fn distance(input: &str) -> u32 {
    let mut visited_locations = HashSet::new();

    let mut location = Point { x: 0, y: 0 };
    let mut direction = Direction::North;

    for instruction in input.split(", ") {
        let (turn_dir, num_blocks) = instruction.split_at(1);

        direction = turn(direction, turn_dir);
        let num_blocks: i32 = num_blocks.to_string()
                                        .trim()
                                        .parse()
                                        .expect("Cannot parse");
        for _ in 0..num_blocks {
            match direction {
                Direction::North => location.y += 1,
                Direction::East  => location.x += 1,
                Direction::South => location.y -= 1,
                Direction::West  => location.x -= 1,
            }
            println!("{:?}", location);
            if visited_locations.contains(&location) {
                return location.distance_to_origin();
            } else {
                visited_locations.insert(location);
            }
        }
    }
    panic!("No location visited twice.");
}

pub fn turn(initial_direction: Direction, turn_command: &str) -> Direction {
    match (turn_command, initial_direction) {
        ("L", Direction::North) => Direction::West,
        ("L", Direction::West) => Direction::South,
        ("L", Direction::South) => Direction::East,
        ("L", Direction::East) => Direction::North,

        ("R", Direction::North) => Direction::East,
        ("R", Direction::East) => Direction::South,
        ("R", Direction::South) => Direction::West,
        ("R", Direction::West) => Direction::North,

        (unknown_turn_command, dir) => panic!("\
            I don't know how to turn {} from {:?}!",
            unknown_turn_command,
            dir
        ),
    }
}

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

    #[test]
    fn hq_is_first_location_visited_twice() {
        assert_eq!(distance("R2, L1, L1, L1, L1, R5"), 1);
    }

    #[test]
    fn turn_left() {
        let mut dir = Direction::North;
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::North);
    }

    #[test]
    fn turn_right() {
        let mut dir = Direction::North;
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::North);
    }
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;
extern crate chrono;
extern crate hyper;

#[macro_use]
extern crate log;

pub mod message_templates;
pub mod payloads;
pub mod pipeline;

#[macro_export]
#[doc(hidden)]
macro_rules! __emit_get_event_data {
    ($s:expr, $( $n:ident: $v:expr ),* ) => {{
        #[allow(unused_imports)]
        use std::fmt::Write;
        use std::collections;

        // Underscores avoid the unused_mut warning
        let mut _names: Vec<&str> = vec![];
        let mut _properties: collections::BTreeMap<&'static str, String> = collections::BTreeMap::new();

        $(
            _names.push(stringify!($n));
            _properties.insert(stringify!($n), $crate::message_templates::capture(&$v));
        )*

        let template = $crate::message_templates::build_template($s, &_names);

        (template, _properties)
    }};
}

#[macro_export]
macro_rules! emit {
    ( $s:expr, $( $n:ident: $v:expr ),* ) => {{
        let (template, properties) = __emit_get_event_data!($s, $($n: $v),*);
        $crate::pipeline::emit(&template, &properties);
    }};

    ( $s:expr ) => {{
        emit!($s,);
    }};
}

#[cfg(test)]
mod tests {
    use pipeline;

    #[test]
    fn unparameterized_templates_are_captured() {
        let (template, properties) = __emit_get_event_data!("Starting...",);
        assert!(template == "Starting...");
        assert!(properties.len() == 0);
    }

    #[test]
    fn template_and_properties_are_captured() {
        let u = "nblumhardt";
        let q = 42;

        let (template, properties) = __emit_get_event_data!("User {} exceeded quota of {}!", user: u, quota: q);
        assert!(template == "User {user} exceeded quota of {quota}!");
        assert!(properties.get("user") == Some(&"\"nblumhardt\"".to_owned()));
        assert!(properties.get("quota") == Some(&"42".to_owned()));
    }

    #[test]
    pub fn emitted_events_are_flushed() {
        let _flush = pipeline::init("http://localhost:5341/", None);
        emit!("Hello");
    }
}
<commit_msg>Support target expressions and include as a `target` property; push all events through `log!()`<commit_after>extern crate serde;
extern crate serde_json;
extern crate chrono;
extern crate hyper;

#[macro_use]
extern crate log;

pub mod message_templates;
pub mod payloads;
pub mod pipeline;

#[macro_export]
#[doc(hidden)]
macro_rules! __emit_get_event_data {
    ($target:expr, $s:expr, $( $n:ident: $v:expr ),* ) => {{
        #[allow(unused_imports)]
        use std::fmt::Write;
        use std::collections;

        // Underscores avoid the unused_mut warning
        let mut _names: Vec<&str> = vec![];
        let mut _properties: collections::BTreeMap<&'static str, String> = collections::BTreeMap::new();

        $(
            _names.push(stringify!($n));
            _properties.insert(stringify!($n), $crate::message_templates::capture(&$v));
        )*

        _properties.insert("target", $crate::message_templates::capture(&$target));

        let template = $crate::message_templates::build_template($s, &_names);

        (template, _properties)
    }};
}

#[macro_export]
macro_rules! emit {
    ( target: $target:expr, $s:expr, $( $n:ident: $v:expr ),* ) => {{
        use log::LogLevel;
        log!(target: $target, LogLevel::Info, $s, $($v),*);
        let (template, properties) = __emit_get_event_data!($target, $s, $($n: $v),*);
        $crate::pipeline::emit(&template, &properties);
    }};

    ( target: $target:expr, $s:expr ) => {{
        emit!(target: $target, $s,);
    }};

    ( $s:expr, $( $n:ident: $v:expr ),* ) => {{
        emit!(target: module_path!(), $s, $($n: $v),*);
    }};

    ( $s:expr ) => {{
        emit!(target: module_path!(), $s,);
    }};
}

#[cfg(test)]
mod tests {
    use pipeline;
    use std::env;

    #[test]
    fn unparameterized_templates_are_captured() {
        let (template, properties) = __emit_get_event_data!("t", "Starting...",);
        assert!(template == "Starting...");
        assert!(properties.len() == 1);
    }

    #[test]
    fn template_and_properties_are_captured() {
        let u = "nblumhardt";
        let q = 42;

        let (template, properties) = __emit_get_event_data!("t", "User {} exceeded quota of {}!", user: u, quota: q);
        assert!(template == "User {user} exceeded quota of {quota}!");
        assert!(properties.get("user") == Some(&"\"nblumhardt\"".to_owned()));
        assert!(properties.get("quota") == Some(&"42".to_owned()));
        assert!(properties.len() == 3);
    }

    #[test]
    pub fn emitted_events_are_flushed() {
        let _flush = pipeline::init("http://localhost:5341/", None);
        emit!("Hello, {}!", name: env::var("USERNAME").unwrap());
    }
}
<|endoftext|>


<commit_before>extern crate emailaddress;
#[macro_use]
extern crate log;
extern crate hyper;
extern crate iron;
extern crate lettre;
extern crate redis;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate url;
extern crate urlencoded;

use emailaddress::EmailAddress;
use iron::headers::{ContentType, Location};
use iron::middleware::Handler;
use iron::modifiers;
use iron::method::Method;
use iron::prelude::*;
use iron::status;
use iron::Url;
use serde_json::builder::{ArrayBuilder, ObjectBuilder};
use serde_json::value::Value;
use std::env;
use std::fs::File;
use std::io::{BufReader, Read};
use std::sync::Arc;
use std::error::Error;
use time::now_utc;
use urlencoded::{UrlEncodedBody, UrlEncodedQuery};

pub mod error;
pub mod config;
pub use config::AppConfig;
pub mod crypto;
pub mod email;
pub mod oidc;
pub mod store;
pub mod store_cache;

use error::{BrokerResult, BrokerError};

/// Macro that creates Handler implementations that log the request,
/// and keep a reference to the AppConfig.
macro_rules! broker_handler {
    ( $name:ident , | $app:ident, $req:ident | $body:block ) => {
        pub struct $name {
            pub app: Arc<AppConfig>,
        }
        impl $name {
            pub fn new(app: &Arc<AppConfig>) -> Self {
                $name { app: app.clone() }
            }
            fn handle_body($app: &AppConfig, $req: &mut Request)
                -> BrokerResult<Response> $body
        }
        impl Handler for $name {
            fn handle(&self, req: &mut Request) -> IronResult<Response> {
                info!("{} {}", req.method, req.url);
                Self::handle_body(&self.app, req)
                    .or_else(|e| handle_error(&self.app, req, e))
            }
        }
    }
}

/// Macro used to extract a parameter from a QueryMap.
///
/// Will return from the caller with a BrokerError if the parameter is missing.
///
/// ```
/// let foo = try_get_param!(params, "foo");
/// ```
macro_rules! try_get_param {
    ( $input:expr , $param:tt ) => {
        try!($input.get($param).map(|list| &list[0]).ok_or_else(|| {
            BrokerError::Input(concat!("missing request parameter ", $param).to_string())
        }))
    }
}

/// Handle an BrokerError and create an IronResult.
///
/// The `broker_handler!` macro calls this on error. We don't use a `From`
/// implementation, because this way we get app and request context, and we
/// don't necessarily have to pass the error on to Iron.
fn handle_error(app: &AppConfig, _: &mut Request, err: BrokerError) -> IronResult<Response> {
    match err {
        BrokerError::Input(_) => {
            let obj = ObjectBuilder::new()
                .insert("error", err.description())
                .build();
            let content = serde_json::to_string(&obj).unwrap();
            let content_type = modifiers::Header(ContentType::json());
            Ok(Response::with((status::BadRequest, content_type, content)))
        }
        BrokerError::Provider(_) => {
            // TODO: Redirect to RP with the error description
            Err(IronError::new(err, status::ServiceUnavailable))
        }
        _ => {
            Err(IronError::new(err, (status::InternalServerError,
                                     modifiers::Header(ContentType::html()),
                                     app.templates.error.render(&[]))))
        }
    }
}

/// Helper function for returning an Iron response with JSON data.
///
/// Serializes the argument value to JSON and returns a HTTP 200 response
/// code with the serialized JSON as the body.
fn json_response(obj: &Value) -> BrokerResult<Response> {
    let content = serde_json::to_string(&obj).unwrap();
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::json()),
                       content)))
}

/// Iron handler for the root path, returns human-friendly message.
///
/// This is not actually used in the protocol.
broker_handler!(WelcomeHandler, |_app, _req| {
    json_response(&ObjectBuilder::new()
        .insert("ladaemon", "Welcome")
        .insert("version", env!("CARGO_PKG_VERSION"))
        .build())
});

/// Iron handler for files in .well-known.
///
/// Mainly directed at Let's Encrypt verification. Returns text/plain always.
broker_handler!(WellKnownHandler, |_app, req| {
    let mut file_name = env::current_dir().unwrap();
    file_name.push(req.url.path().join("/"));
    let file_res = File::open(file_name);
    if file_res.is_err() {
        return Ok(Response::with((status::NotFound)));
    }
    let mut bytes = Vec::<u8>::new();
    let mut reader = BufReader::new(file_res.unwrap());
    let _ = reader.read_to_end(&mut bytes).unwrap();
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::plaintext()),
                       bytes)))
});

/// Iron handler to return the OpenID Discovery document.
///
/// Most of this is hard-coded for now, although the URLs are constructed by
/// using the base URL as configured in the `base_url` configuration value.
broker_handler!(OIDConfigHandler, |app, _req| {
    json_response(&ObjectBuilder::new()
        .insert("issuer", &app.base_url)
        .insert("authorization_endpoint",
                format!("{}/auth", app.base_url))
        .insert("jwks_uri", format!("{}/keys.json", app.base_url))
        .insert("scopes_supported", vec!["openid", "email"])
        .insert("claims_supported",
                vec!["aud", "email", "email_verified", "exp", "iat", "iss", "sub"])
        .insert("response_types_supported", vec!["id_token"])
        .insert("response_modes_supported", vec!["form_post"])
        .insert("grant_types_supported", vec!["implicit"])
        .insert("subject_types_supported", vec!["public"])
        .insert("id_token_signing_alg_values_supported", vec!["RS256"])
        .build())
});

/// Iron handler for the JSON Web Key Set document.
///
/// Respond with the JWK key set containing all of the configured keys.
///
/// Relying Parties will need to fetch this data to be able to verify identity
/// tokens issued by this daemon instance.
broker_handler!(KeysHandler, |app, _req| {
    let mut keys = ArrayBuilder::new();
    for key in &app.keys {
        keys = keys.push(key.public_jwk())
    }
    json_response(&ObjectBuilder::new()
                      .insert("keys", keys.build())
                      .build())
});

/// Iron handler for authentication requests from the RP.
///
/// Calls the `oidc::request()` function if the provided email address's
/// domain matches one of the configured famous providers. Otherwise, calls the
/// `email::request()` function to allow authentication through the email loop.
broker_handler!(AuthHandler, |app, req| {
    let params = try!(
        match req.method {
            Method::Get => {
                req.compute::<UrlEncodedQuery>()
                    .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
            },
            Method::Post => {
                req.compute::<UrlEncodedBody>()
                    .map_err(|_| BrokerError::Input("no query string in POST data".to_string()))
            },
            _ => {
                panic!("Unsupported method: {}", req.method)
            }
        }
    );
    let client_id = try_get_param!(params, "client_id");
    let nonce = try_get_param!(params, "nonce");
    let redirect_uri = try!(
        Url::parse(try_get_param!(params, "redirect_uri"))
            .map_err(|_| BrokerError::Input("redirect_uri is not a valid URL".to_string()))
    );
    let email_addr = try!(
        EmailAddress::new(try_get_param!(params, "login_hint"))
            .map_err(|_| BrokerError::Input("login_hint is not a valid email address".to_string()))
    );
    if app.providers.contains_key(&email_addr.domain) {

        // OIDC authentication. Redirect to the identity provider.
        let auth_url = try!(oidc::request(app, email_addr, client_id, nonce, &redirect_uri));
        Ok(Response::with((status::SeeOther, modifiers::Header(Location(auth_url.to_string())))))

    } else {

        // Email loop authentication. Render a message and form.
        let session_id = try!(email::request(app, email_addr, client_id, nonce, &redirect_uri));
        Ok(Response::with((status::Ok,
                           modifiers::Header(ContentType::html()),
                           app.templates.confirm_email.render(&[
                               ("client_id", &client_id),
                               ("session_id", &session_id),
                           ]))))

    }
});

/// Helper method to create a JWT for a given email address and origin.
///
/// Builds the JSON payload, then signs it using the last key provided in
/// the configuration object.
fn create_jwt(app: &AppConfig, email: &str, origin: &str, nonce: &str) -> String {
    let now = now_utc().to_timespec().sec;
    let payload = &ObjectBuilder::new()
        .insert("aud", origin)
        .insert("email", email)
        .insert("email_verified", email)
        .insert("exp", now + app.token_validity as i64)
        .insert("iat", now)
        .insert("iss", &app.base_url)
        .insert("sub", email)
        .insert("nonce", nonce)
        .build();
    app.keys.last().unwrap().sign_jws(&payload)
}

/// Helper function for returning result to the Relying Party.
///
/// Takes a `(jwt, redirect)` pair from one of the verification functions and
/// embeds it in a form in `tmpl/forward.html`, from where it's POSTed to
/// the RP's `redirect` as soon as the page has loaded.
fn return_to_relier(app: &AppConfig, result: (String, String)) -> BrokerResult<Response> {
    let (jwt, redirect) = result;
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::html()),
                       app.templates.forward.render(&[
                           ("return_url", &redirect),
                           ("jwt", &jwt),
                       ]))))
}

/// Iron handler for one-time pad email loop confirmation.
///
/// Retrieves the session based session ID and the expected one-time pad.
/// Verify the code and return the resulting token or error to the RP.
broker_handler!(ConfirmHandler, |app, req| {
    let params = try!(
        req.compute::<UrlEncodedQuery>()
            .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
    );
    let stored = try!(app.store.get_session("email", &try_get_param!(params, "session")));
    let code = try_get_param!(params, "code");
    return_to_relier(app, try!(email::verify(app, &stored, code)))
});

/// Iron handler for OAuth callbacks
///
/// After the user allows or denies the Authentication Request with the famous
/// identity provider, they will be redirected back to the callback handler.
/// Verify the callback data and return the resulting token or error.
broker_handler!(CallbackHandler, |app, req| {
    let params = try!(
        req.compute::<UrlEncodedQuery>()
            .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
    );
    let stored = try!(app.store.get_session("oidc", &try_get_param!(params, "state")));
    let code = try_get_param!(params, "code");
    return_to_relier(app, try!(oidc::verify(app, &stored, code)))
});
<commit_msg>Track redirect_uri as a request extension.<commit_after>extern crate emailaddress;
#[macro_use]
extern crate log;
extern crate hyper;
extern crate iron;
extern crate lettre;
extern crate redis;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate url;
extern crate urlencoded;

use emailaddress::EmailAddress;
use iron::headers::{ContentType, Location};
use iron::middleware::Handler;
use iron::modifiers;
use iron::method::Method;
use iron::prelude::*;
use iron::status;
use iron::typemap;
use iron::Url;
use serde_json::builder::{ArrayBuilder, ObjectBuilder};
use serde_json::value::Value;
use std::env;
use std::fs::File;
use std::io::{BufReader, Read};
use std::sync::Arc;
use std::error::Error;
use time::now_utc;
use urlencoded::{UrlEncodedBody, UrlEncodedQuery};

pub mod error;
pub mod config;
pub use config::AppConfig;
pub mod crypto;
pub mod email;
pub mod oidc;
pub mod store;
pub mod store_cache;

use error::{BrokerResult, BrokerError};

/// Iron extension key we use to store the redirect_uri.
/// Once set, the error handler will return errors to the RP.
struct RedirectUri;
impl typemap::Key for RedirectUri { type Value = Url; }

/// Macro that creates Handler implementations that log the request,
/// and keep a reference to the AppConfig.
macro_rules! broker_handler {
    ( $name:ident , | $app:ident, $req:ident | $body:block ) => {
        pub struct $name {
            pub app: Arc<AppConfig>,
        }
        impl $name {
            pub fn new(app: &Arc<AppConfig>) -> Self {
                $name { app: app.clone() }
            }
            fn handle_body($app: &AppConfig, $req: &mut Request)
                -> BrokerResult<Response> $body
        }
        impl Handler for $name {
            fn handle(&self, req: &mut Request) -> IronResult<Response> {
                info!("{} {}", req.method, req.url);
                Self::handle_body(&self.app, req)
                    .or_else(|e| handle_error(&self.app, req, e))
            }
        }
    }
}

/// Macro used to extract a parameter from a QueryMap.
///
/// Will return from the caller with a BrokerError if the parameter is missing.
///
/// ```
/// let foo = try_get_param!(params, "foo");
/// ```
macro_rules! try_get_param {
    ( $input:expr , $param:tt ) => {
        try!($input.get($param).map(|list| &list[0]).ok_or_else(|| {
            BrokerError::Input(concat!("missing request parameter ", $param).to_string())
        }))
    }
}

/// Handle an BrokerError and create an IronResult.
///
/// The `broker_handler!` macro calls this on error. We don't use a `From`
/// implementation, because this way we get app and request context, and we
/// don't necessarily have to pass the error on to Iron.
fn handle_error(app: &AppConfig, _: &mut Request, err: BrokerError) -> IronResult<Response> {
    match err {
        BrokerError::Input(_) => {
            let obj = ObjectBuilder::new()
                .insert("error", err.description())
                .build();
            let content = serde_json::to_string(&obj).unwrap();
            let content_type = modifiers::Header(ContentType::json());
            Ok(Response::with((status::BadRequest, content_type, content)))
        }
        BrokerError::Provider(_) => {
            // TODO: Redirect to RP with the error description
            Err(IronError::new(err, status::ServiceUnavailable))
        }
        _ => {
            Err(IronError::new(err, (status::InternalServerError,
                                     modifiers::Header(ContentType::html()),
                                     app.templates.error.render(&[]))))
        }
    }
}

/// Helper function for returning an Iron response with JSON data.
///
/// Serializes the argument value to JSON and returns a HTTP 200 response
/// code with the serialized JSON as the body.
fn json_response(obj: &Value) -> BrokerResult<Response> {
    let content = serde_json::to_string(&obj).unwrap();
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::json()),
                       content)))
}

/// Iron handler for the root path, returns human-friendly message.
///
/// This is not actually used in the protocol.
broker_handler!(WelcomeHandler, |_app, _req| {
    json_response(&ObjectBuilder::new()
        .insert("ladaemon", "Welcome")
        .insert("version", env!("CARGO_PKG_VERSION"))
        .build())
});

/// Iron handler for files in .well-known.
///
/// Mainly directed at Let's Encrypt verification. Returns text/plain always.
broker_handler!(WellKnownHandler, |_app, req| {
    let mut file_name = env::current_dir().unwrap();
    file_name.push(req.url.path().join("/"));
    let file_res = File::open(file_name);
    if file_res.is_err() {
        return Ok(Response::with((status::NotFound)));
    }
    let mut bytes = Vec::<u8>::new();
    let mut reader = BufReader::new(file_res.unwrap());
    let _ = reader.read_to_end(&mut bytes).unwrap();
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::plaintext()),
                       bytes)))
});

/// Iron handler to return the OpenID Discovery document.
///
/// Most of this is hard-coded for now, although the URLs are constructed by
/// using the base URL as configured in the `base_url` configuration value.
broker_handler!(OIDConfigHandler, |app, _req| {
    json_response(&ObjectBuilder::new()
        .insert("issuer", &app.base_url)
        .insert("authorization_endpoint",
                format!("{}/auth", app.base_url))
        .insert("jwks_uri", format!("{}/keys.json", app.base_url))
        .insert("scopes_supported", vec!["openid", "email"])
        .insert("claims_supported",
                vec!["aud", "email", "email_verified", "exp", "iat", "iss", "sub"])
        .insert("response_types_supported", vec!["id_token"])
        .insert("response_modes_supported", vec!["form_post"])
        .insert("grant_types_supported", vec!["implicit"])
        .insert("subject_types_supported", vec!["public"])
        .insert("id_token_signing_alg_values_supported", vec!["RS256"])
        .build())
});

/// Iron handler for the JSON Web Key Set document.
///
/// Respond with the JWK key set containing all of the configured keys.
///
/// Relying Parties will need to fetch this data to be able to verify identity
/// tokens issued by this daemon instance.
broker_handler!(KeysHandler, |app, _req| {
    let mut keys = ArrayBuilder::new();
    for key in &app.keys {
        keys = keys.push(key.public_jwk())
    }
    json_response(&ObjectBuilder::new()
                      .insert("keys", keys.build())
                      .build())
});

/// Iron handler for authentication requests from the RP.
///
/// Calls the `oidc::request()` function if the provided email address's
/// domain matches one of the configured famous providers. Otherwise, calls the
/// `email::request()` function to allow authentication through the email loop.
broker_handler!(AuthHandler, |app, req| {
    let params = try!(
        match req.method {
            Method::Get => {
                req.compute::<UrlEncodedQuery>()
                    .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
            },
            Method::Post => {
                req.compute::<UrlEncodedBody>()
                    .map_err(|_| BrokerError::Input("no query string in POST data".to_string()))
            },
            _ => {
                panic!("Unsupported method: {}", req.method)
            }
        }
    );

    // Per the OAuth2 spec, we may redirect to the RP once we have validated client_id and
    // redirect_uri. In our case, this means we make redirect_uri available to error handling.
    let client_id = try_get_param!(params, "client_id");
    let redirect_uri = try!(
        Url::parse(try_get_param!(params, "redirect_uri"))
            .map_err(|_| BrokerError::Input("redirect_uri is not a valid URL".to_string()))
    );
    req.extensions.insert::<RedirectUri>(redirect_uri.clone());

    let email_addr = try!(
        EmailAddress::new(try_get_param!(params, "login_hint"))
            .map_err(|_| BrokerError::Input("login_hint is not a valid email address".to_string()))
    );
    let nonce = try_get_param!(params, "nonce");
    if app.providers.contains_key(&email_addr.domain) {

        // OIDC authentication. Redirect to the identity provider.
        let auth_url = try!(oidc::request(app, email_addr, client_id, nonce, &redirect_uri));
        Ok(Response::with((status::SeeOther, modifiers::Header(Location(auth_url.to_string())))))

    } else {

        // Email loop authentication. Render a message and form.
        let session_id = try!(email::request(app, email_addr, client_id, nonce, &redirect_uri));
        Ok(Response::with((status::Ok,
                           modifiers::Header(ContentType::html()),
                           app.templates.confirm_email.render(&[
                               ("client_id", &client_id),
                               ("session_id", &session_id),
                           ]))))

    }
});

/// Helper method to create a JWT for a given email address and origin.
///
/// Builds the JSON payload, then signs it using the last key provided in
/// the configuration object.
fn create_jwt(app: &AppConfig, email: &str, origin: &str, nonce: &str) -> String {
    let now = now_utc().to_timespec().sec;
    let payload = &ObjectBuilder::new()
        .insert("aud", origin)
        .insert("email", email)
        .insert("email_verified", email)
        .insert("exp", now + app.token_validity as i64)
        .insert("iat", now)
        .insert("iss", &app.base_url)
        .insert("sub", email)
        .insert("nonce", nonce)
        .build();
    app.keys.last().unwrap().sign_jws(&payload)
}

/// Helper function for returning result to the Relying Party.
///
/// Takes a `(jwt, redirect)` pair from one of the verification functions and
/// embeds it in a form in `tmpl/forward.html`, from where it's POSTed to
/// the RP's `redirect` as soon as the page has loaded.
fn return_to_relier(app: &AppConfig, result: (String, String)) -> BrokerResult<Response> {
    let (jwt, redirect) = result;
    Ok(Response::with((status::Ok,
                       modifiers::Header(ContentType::html()),
                       app.templates.forward.render(&[
                           ("return_url", &redirect),
                           ("jwt", &jwt),
                       ]))))
}

/// Iron handler for one-time pad email loop confirmation.
///
/// Retrieves the session based session ID and the expected one-time pad.
/// Verify the code and return the resulting token or error to the RP.
broker_handler!(ConfirmHandler, |app, req| {
    let params = try!(
        req.compute::<UrlEncodedQuery>()
            .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
    );

    let stored = try!(app.store.get_session("email", &try_get_param!(params, "session")));
    req.extensions.insert::<RedirectUri>(Url::parse(&stored["redirect"]).unwrap());

    let code = try_get_param!(params, "code");
    return_to_relier(app, try!(email::verify(app, &stored, code)))
});

/// Iron handler for OAuth callbacks
///
/// After the user allows or denies the Authentication Request with the famous
/// identity provider, they will be redirected back to the callback handler.
/// Verify the callback data and return the resulting token or error.
broker_handler!(CallbackHandler, |app, req| {
    let params = try!(
        req.compute::<UrlEncodedQuery>()
            .map_err(|_| BrokerError::Input("no query string in GET request".to_string()))
    );

    let stored = try!(app.store.get_session("oidc", &try_get_param!(params, "state")));
    req.extensions.insert::<RedirectUri>(Url::parse(&stored["redirect"]).unwrap());

    let code = try_get_param!(params, "code");
    return_to_relier(app, try!(oidc::verify(app, &stored, code)))
});
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;
extern crate range;

pub use whitespace::{ Whitespace, WHITESPACE };
pub use parse_error_handler::{ ParseErrorHandler, ParseStdErr };
pub use parse_error::ParseError;
pub use ty::Type;
pub use token::Token;
pub use select::Select;
pub use parameter::Parameter;
pub use optional::Optional;
pub use until_any_or_whitespace::UntilAnyOrWhitespace;
pub use text::Text;
pub use number::Number;
pub use rule::Rule;
pub use meta_reader::MetaReader;

use std::rc::Rc;
use std::cell::RefCell;

mod parse_error;
mod parse_error_handler;
mod ty;
mod token;
mod whitespace;
mod select;
mod parameter;
mod optional;
mod until_any_or_whitespace;
mod text;
mod number;
mod rule;
mod meta_reader;

/// Represents meta data.
pub enum MetaData<'a> {
    /// Starts node.
    StartNode(&'a str),
    /// Ends node.
    EndNode,
    /// Sets bool property.
    Bool(&'a str, bool),
    /// Sets f64 property.
    F64(&'a str, f64),
    /// Sets string property.
    String(&'a str, String),
}

/// Implemented by meta writers.
pub trait MetaWriter {
    /// Starts encoding a node.
    fn start_node(&mut self, name: &str);
    /// Ends encoding a node.
    fn end_node(&mut self, name: &str);
    /// Get bool property.
    fn get_as_bool(&mut self, name: &str) -> Option<bool>;
    /// Get str property.
    fn get_as_str<F, U>(&mut self, name: &str, f: F) -> Option<U>
        where F: FnOnce(&str) -> U;
    /// Get f64 property.
    fn get_as_f64(&mut self, name: &str) -> Option<f64>;
}

#[inline(always)]
fn update<'a>(range: range::Range, chars: &mut &'a [char], offset: &mut usize) {
    let next_offset = range.next_offset();
    *chars = &chars[next_offset - *offset..];
    *offset = next_offset;
}

/// Used by meta readers to handle or forward a state.
/// This makes it easier to write generic meta readers wrapping a sub reader.
pub enum CommandState<T, U> {
    /// Handle state.
    Handle(T),
    /// Forward command to sub meta reader.
    Forward(U),
}
<commit_msg>Added `Struct` and `Data`<commit_after>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;
extern crate range;

pub use whitespace::{ Whitespace, WHITESPACE };
pub use parse_error_handler::{ ParseErrorHandler, ParseStdErr };
pub use parse_error::ParseError;
pub use ty::Type;
pub use token::Token;
pub use select::Select;
pub use parameter::Parameter;
pub use optional::Optional;
pub use until_any_or_whitespace::UntilAnyOrWhitespace;
pub use text::Text;
pub use number::Number;
pub use rule::Rule;
pub use meta_reader::MetaReader;

use std::rc::Rc;
use std::cell::RefCell;

mod parse_error;
mod parse_error_handler;
mod ty;
mod token;
mod whitespace;
mod select;
mod parameter;
mod optional;
mod until_any_or_whitespace;
mod text;
mod number;
mod rule;
mod meta_reader;

/// Represents a data structure to read into.
pub struct Struct<'a> {
    /// The fields of a struct.
    pub fields: &'a mut [Data<'a>],
}

/// Allocated data for reading.
pub enum Data<'a> {
    /// Hash a f64 property.
    F64(&'a str, &'a mut f64),
    /// Has a bool property.
    Bool(&'a str, &'a mut bool),
    /// Has a string property.
    String(&'a str, &'a mut String),
    /// Has a sub node.
    Node(&'a str),
}

/// Represents meta data.
pub enum MetaData<'a> {
    /// Starts node.
    StartNode(&'a str),
    /// Ends node.
    EndNode,
    /// Sets bool property.
    Bool(&'a str, bool),
    /// Sets f64 property.
    F64(&'a str, f64),
    /// Sets string property.
    String(&'a str, String),
}

/// Implemented by meta writers.
pub trait MetaWriter {
    /// Starts encoding a node.
    fn start_node(&mut self, name: &str);
    /// Ends encoding a node.
    fn end_node(&mut self, name: &str);
    /// Get bool property.
    fn get_as_bool(&mut self, name: &str) -> Option<bool>;
    /// Get str property.
    fn get_as_str<F, U>(&mut self, name: &str, f: F) -> Option<U>
        where F: FnOnce(&str) -> U;
    /// Get f64 property.
    fn get_as_f64(&mut self, name: &str) -> Option<f64>;
}

#[inline(always)]
fn update<'a>(range: range::Range, chars: &mut &'a [char], offset: &mut usize) {
    let next_offset = range.next_offset();
    *chars = &chars[next_offset - *offset..];
    *offset = next_offset;
}

/// Used by meta readers to handle or forward a state.
/// This makes it easier to write generic meta readers wrapping a sub reader.
pub enum CommandState<T, U> {
    /// Handle state.
    Handle(T),
    /// Forward command to sub meta reader.
    Forward(U),
}
<|endoftext|>


<commit_before>use std::fmt;

pub mod instr;
use instr::Instr;

mod kleisli;
pub use kleisli::Kleisli;

pub enum Program<'a, I: Instr, A> {
    Pure(Box<A>),
    Then(Box<I>, Kleisli<'a, I, I::Param, A>)
}

impl<'a, I: 'a + Instr, A> Program<'a, I, A> {

    pub fn new(a: A) -> Program<'a, I, A> {
        Program::Pure(Box::new(a))
    }

    fn and_then_boxed<B, F>(self, js: F) -> Program<'a, I, B>
        where F: 'a + Fn(Box<A>) -> Program<'a, I, B> {
        match self {
            Program::Pure(a) => js(a),
            Program::Then(i, is) => Program::Then(i, kleisli::append_boxed(is, js))
        }
    }

    pub fn and_then<B, F>(self, js: F) -> Program<'a, I, B>
        where F: 'a + Fn(A) -> Program<'a, I, B> {
        match self {
            Program::Pure(a) => js(*a),
            Program::Then(i, is) => Program::Then(i, is.append(js))
        }
    }

}

impl<'a, I: 'a + Instr, A: PartialEq> PartialEq for Program<'a, I, A> {
    fn eq(&self, other: &Program<'a, I, A>) -> bool {
        match (self, other) {
            (&Program::Pure(ref a), &Program::Pure(ref b)) => a == b,
            _ => false
        }
    }
}

impl<'a, I: 'a + Instr, A: fmt::Debug> fmt::Debug for Program<'a, I, A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Program::Pure(ref a) => write!(f, "Pure({:?})", a),
            &Program::Then(_, _) => write!(f, "Then(..)")
        }
    }
}
<commit_msg>add map function<commit_after>use std::fmt;

pub mod instr;
use instr::Instr;

mod kleisli;
pub use kleisli::Kleisli;

pub enum Program<'a, I: Instr, A> {
    Pure(Box<A>),
    Then(Box<I>, Kleisli<'a, I, I::Param, A>)
}

impl<'a, I: 'a + Instr, A> Program<'a, I, A> {

    pub fn new(a: A) -> Program<'a, I, A> {
        Program::Pure(Box::new(a))
    }

    fn and_then_boxed<B, F>(self, js: F) -> Program<'a, I, B>
        where F: 'a + Fn(Box<A>) -> Program<'a, I, B> {
        match self {
            Program::Pure(a) => js(a),
            Program::Then(i, is) => Program::Then(i, kleisli::append_boxed(is, js))
        }
    }

    pub fn and_then<B, F>(self, js: F) -> Program<'a, I, B>
        where F: 'a + Fn(A) -> Program<'a, I, B> {
        match self {
            Program::Pure(a) => js(*a),
            Program::Then(i, is) => Program::Then(i, is.append(js))
        }
    }

    pub fn map<B, F>(self, f: F) -> Program<'a, I, B>
        where F: 'a + Fn(A) -> B {
        self.and_then(move |a| Program::new(f(a)))
    }

}

impl<'a, I: 'a + Instr, A: PartialEq> PartialEq for Program<'a, I, A> {
    fn eq(&self, other: &Program<'a, I, A>) -> bool {
        match (self, other) {
            (&Program::Pure(ref a), &Program::Pure(ref b)) => a == b,
            _ => false
        }
    }
}

impl<'a, I: 'a + Instr, A: fmt::Debug> fmt::Debug for Program<'a, I, A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Program::Pure(ref a) => write!(f, "Pure({:?})", a),
            &Program::Then(_, _) => write!(f, "Then(..)")
        }
    }
}
<|endoftext|>


<commit_before>//! This crate explores [genetic
//! programming](https://en.wikipedia.org/wiki/Genetic_programming). Genetic
//! programming is
//!
//! > a technique whereby computer programs are encoded as a set of genes that
//! > are then modified (evolved) using an evolutionary algorithm.
//!
//! The problem we are trying to tackle with genetic programming is that of
//! landing a [moon lander](https://en.wikipedia.org/wiki/Lunar_lander). I.e.
//! land a moon lander safely on the surface of a moon without user
//! intervention. A nice interactive game that gives a feel for the problem can be
//! found [here](http://moonlander.seb.ly/).

extern crate rustc_serialize;
pub mod macros;
pub mod structure;
pub mod data;
pub mod source;
pub mod random;
pub mod simulation;
pub mod darwin;
<commit_msg>Signal to use the pick macro<commit_after>//! This crate explores [genetic
//! programming](https://en.wikipedia.org/wiki/Genetic_programming). Genetic
//! programming is
//!
//! > a technique whereby computer programs are encoded as a set of genes that
//! > are then modified (evolved) using an evolutionary algorithm.
//!
//! The problem we are trying to tackle with genetic programming is that of
//! landing a [moon lander](https://en.wikipedia.org/wiki/Lunar_lander). I.e.
//! land a moon lander safely on the surface of a moon without user
//! intervention. A nice interactive game that gives a feel for the problem can be
//! found [here](http://moonlander.seb.ly/).

extern crate rustc_serialize;
#[macro_use]
pub mod pick;
pub mod macros;
pub mod structure;
pub mod data;
pub mod source;
pub mod random;
pub mod simulation;
pub mod darwin;
<|endoftext|>


<commit_before>//! libracerd provides an http server and set of completion engines for consumption by rust
//! developer tools. The http server itself is a few JSON endpoints providing completion, definition
//! look-up, and compilation. The endpoints are backed by an object implementing `SemanticEngine`
//!
//! Documentation for the HTTP endpoints can be found in the http module header.
//!
//! This project's source code is [available on GitHub](https://github.com/jwilm/racerd).
extern crate iron;
extern crate rustc_serialize;
#[macro_use]
extern crate router;
extern crate bodyparser;
extern crate racer;
extern crate crypto;
extern crate hyper;
extern crate persistent;
extern crate logger;

mod util;
pub mod http;
pub mod engine;

/// Configuration flags and values
///
/// This object contains all switches the consumer has control of.
#[derive(Debug, Default)]
pub struct Config {
    pub port: u16,
    pub secret_file: String,
    pub print_http_logs: bool,
}

impl Config {
    /// Build a default config object
    pub fn new() -> Config {
        Default::default()
    }
}
<commit_msg>Annotate crates used<commit_after>//! libracerd provides an http server and set of completion engines for consumption by rust
//! developer tools. The http server itself is a few JSON endpoints providing completion, definition
//! look-up, and compilation. The endpoints are backed by an object implementing `SemanticEngine`
//!
//! Documentation for the HTTP endpoints can be found in the http module header.
//!
//! This project's source code is [available on GitHub](https://github.com/jwilm/racerd).
extern crate rustc_serialize;

#[macro_use]
extern crate router;     // Iron routing handler
extern crate bodyparser; // Iron body parsing middleware
extern crate persistent; // Iron storage middleware
extern crate logger;     // Iron logging middleware
extern crate iron;       // http framework

extern crate hyper;      // Provides `Listening` type returned by Iron

#[macro_use]
extern crate log;        // log macros
extern crate racer;      // rust code analysis
extern crate crypto;     // crypto algorithms for HMAC auth middleware

mod util;
pub mod http;
pub mod engine;

/// Configuration flags and values
///
/// This object contains all switches the consumer has control of.
#[derive(Debug, Default)]
pub struct Config {
    pub port: u16,
    pub secret_file: String,
    pub print_http_logs: bool,
}

impl Config {
    /// Build a default config object
    pub fn new() -> Config {
        Default::default()
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_private, core, std_misc)]
#![deny(warnings)]

extern crate syntax;

use std::borrow::ToOwned;
use std::thread::Thread;
use syntax::parse;
use syntax::ext::expand;
use syntax::attr::AttrMetaMethods;

mod item;
mod var;
mod util;
mod ty;
mod fun;
mod expr;
mod block;

const NAME: &'static str = "<glassful shader>";

/// Translate a glassful program to GLSL, or panic.
pub fn translate(source: String) -> String {
    // parse
    let sess = parse::new_parse_sess();
    let diag = &sess.span_diagnostic;
    let krate = parse::parse_crate_from_source_str(
        NAME.to_owned(), source, vec![], &sess);

    diag.handler.abort_if_errors();

    // expand macros
    let ecfg = expand::ExpansionConfig::default(NAME.to_owned());
    let krate = expand::expand_crate(&sess, ecfg, vec![], vec![], krate);

    // process attributes
    let mut glsl_version = None;
    for attr in krate.attrs.iter() {
        if attr.check_name("version") {
            if let Some(val) = attr.value_str() {
                if glsl_version.is_some() {
                    diag.span_err(attr.span, "version given twice");
                }
                glsl_version = Some((*val).to_string());
            } else {
                diag.span_err(attr.span, "version not given");
            }
        } else {
            diag.span_err(attr.span, "unknown attribute");
        }
    }

    diag.handler.abort_if_errors();

    // translate!

    let mut out = match glsl_version {
        Some(v) => format!("#version {}\n\n", v),
        None => "".to_owned(),
    };

    for item in krate.module.items.iter() {
        item::translate(&sess, &mut out, &**item);
    }

    diag.handler.abort_if_errors();

    out
}

/// Translate a glassful program to GLSL, or return `None'.
///
/// Because the `libsyntax` parser uses `panic!` internally,
/// this spawns a new thread for the duration of the call.
pub fn try_translate(source: String) -> Option<String> {
    Thread::scoped(move || {
        translate(source)
    }).join().ok()
}
<commit_msg>Construct the option type with the Some constructor<commit_after>#![feature(rustc_private, core, std_misc)]
#![deny(warnings)]

extern crate syntax;

use std::borrow::ToOwned;
use std::thread::Thread;
use syntax::parse;
use syntax::ext::expand;
use syntax::attr::AttrMetaMethods;

mod item;
mod var;
mod util;
mod ty;
mod fun;
mod expr;
mod block;

const NAME: &'static str = "<glassful shader>";

/// Translate a glassful program to GLSL, or panic.
pub fn translate(source: String) -> String {
    // parse
    let sess = parse::new_parse_sess();
    let diag = &sess.span_diagnostic;
    let krate = parse::parse_crate_from_source_str(
        NAME.to_owned(), source, vec![], &sess);

    diag.handler.abort_if_errors();

    // expand macros
    let ecfg = expand::ExpansionConfig::default(NAME.to_owned());
    let krate = expand::expand_crate(&sess, ecfg, vec![], vec![], krate);

    // process attributes
    let mut glsl_version = None;
    for attr in krate.attrs.iter() {
        if attr.check_name("version") {
            if let Some(val) = attr.value_str() {
                if glsl_version.is_some() {
                    diag.span_err(attr.span, "version given twice");
                }
                glsl_version = Some((*val).to_string());
            } else {
                diag.span_err(attr.span, "version not given");
            }
        } else {
            diag.span_err(attr.span, "unknown attribute");
        }
    }

    diag.handler.abort_if_errors();

    // translate!

    let mut out = match glsl_version {
        Some(v) => format!("#version {}\n\n", v),
        None => "".to_owned(),
    };

    for item in krate.module.items.iter() {
        item::translate(&sess, &mut out, &**item);
    }

    diag.handler.abort_if_errors();

    out
}

/// Translate a glassful program to GLSL, or return `None'.
///
/// Because the `libsyntax` parser uses `panic!` internally,
/// this spawns a new thread for the duration of the call.
pub fn try_translate(source: String) -> Option<String> {
    Option::Some(
        Thread::scoped(move || {translate(source)})
            .join())
}
<|endoftext|>


<commit_before>//! EventFD binding
//!
//! This crate implements a simple binding for Linux eventfd(). See
//! eventfd(2) for specific details of behaviour.

extern crate libc;

use libc::{c_int, c_uint, c_void};
use std::io::{IoResult, IoError};
use std::os::unix::{AsRawFd,Fd};

#[deriving(Send)]
#[deriving(Sync)]
pub struct EventFD {
    fd: uint,
    flags: uint,
}

/// Construct a semaphore-style EventFD.
pub const EFD_SEMAPHORE: uint = 0x00001; // 00000001

/// In non-blocking mode, reads and writes will return IoError
/// containing EAGAIN rather than blocking.
pub const EFD_NONBLOCK: uint  = 0x00800; // 00004000

/// Set the close-on-exec flag on the eventfd.
pub const EFD_CLOEXEC: uint   = 0x80000; // 02000000

impl EventFD {
    /// Create a new EventFD. Flags is the bitwise OR of EFD_* constants, or 0 for no flags.
    /// The underlying file descriptor is closed when the EventFD instance's lifetime ends.
    ///
    /// TODO: work out how to integrate this FD into the wider world
    /// of fds. There's currently no way to poll/select on the fd.
    pub fn new(initval: uint, flags: uint) -> IoResult<EventFD> {
        let r = unsafe { eventfd(initval as u32, flags as u32) };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(EventFD { fd: r as uint, flags: flags })
        }
    }

    /// Read the current value of the eventfd. This will block until
    /// the value is non-zero. In semaphore mode this will only ever
    /// decrement the count by 1 and return 1; otherwise it atomically
    /// returns the current value and sets it to zero.
    pub fn read(&self) -> IoResult<u64> {
        let mut ret : u64 = 0;
        let r = unsafe {
            let ptr : *mut u64 = &mut ret;
            ::libc::read(self.fd as c_int, ptr as *mut c_void, std::mem::size_of_val(&ret) as u64)
        };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(ret)
        }
    }

    /// Add to the current value. Blocks if the value would wrap u64.
    pub fn write(&self, val: u64) -> IoResult<()> {
        let r = unsafe {
            let ptr : *const u64 = &val;
            ::libc::write(self.fd as c_int, ptr as *const c_void, std::mem::size_of_val(&val) as u64)
        };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(())
        }
    }

    /// Return a stream of events. The channel has a synchronous
    /// sender because there's no point in building up a queue of
    /// events; if this task blocks on send, the event state will
    /// still update.
    ///
    /// The task will exit if the receiver end is shut down.
    ///
    /// This will be a CPU-spin loop if the EventFD is created
    /// non-blocking.
    ///
    /// XXX FIXME This has no way of terminating except if the other
    /// end closes the connection, and only then if we're not blocked
    /// in the read()...
    pub fn events(&self) -> std::comm::Receiver<u64> {
        let (tx, rx) = std::comm::sync_channel(1);
        let c = self.clone();

        spawn(proc() {
            loop {
                match c.read() {
                    Ok(v) => match tx.send_opt(v) {
                        Ok(_) => (),
                        Err(_) => break,
                    },
                    Err(e) => panic!("read failed: {}", e),
                }
            }
        });

        rx
    }
}

impl AsRawFd for EventFD {
    /// Return the raw underlying fd. The caller must make sure self's
    /// lifetime is longer than any users of the fd.
    fn as_raw_fd(&self) -> Fd {
        self.fd as Fd
    }
}

impl Drop for EventFD {
    fn drop(&mut self) {
        let r = unsafe { ::libc::close(self.fd as c_int) };
        if r < 0 {
            panic!("eventfd close {} failed", self.fd)
        }
    }
}

/// Construct a linked clone of an existing EventFD. Once created, the
/// new instance interacts with the original in a way that's
/// indistinguishable from the original.
impl Clone for EventFD {
    fn clone(&self) -> EventFD {
        let r = unsafe { ::libc::dup(self.fd as c_int) };
        if r < 0 {
            panic!("EventFD clone dup failed: {}", IoError::last_error())
        }

        EventFD { fd: r as uint, flags: self.flags }
    }
}

#[link(name = "c")]
extern "C" {
    fn eventfd(initval: c_uint, flags: c_uint) -> c_int;
}

#[test]
fn test_basic() {
    let (tx,rx) = std::comm::channel();
    let efd = match EventFD::new(10, 0) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };
    let cefd = efd.clone();

    assert!(efd.read() == Ok(10));

    spawn(proc() {
        assert!(cefd.read() == Ok(7));
        assert!(cefd.write(1) == Ok(()));
        assert!(cefd.write(2) == Ok(()));
        tx.send(());
    });

    assert!(efd.write(7) == Ok(()));
    rx.recv();
    assert!(efd.read() == Ok(3));
}

#[test]
fn test_sema() {
    let efd = match EventFD::new(0, EFD_SEMAPHORE | EFD_NONBLOCK) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };

    match efd.read() {
        Err(ref e) if e.kind == std::io::ResourceUnavailable => (), // ok
        Err(e) => panic!("unexpected error {}", e),
        Ok(v) => panic!("unexpected success {}", v),
    }

    assert!(efd.write(5) == Ok(()));

    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    match efd.read() {
        Err(ref e) if e.kind == std::io::ResourceUnavailable => (), // ok
        Err(e) => panic!("unexpected error {}", e),
        Ok(v) => panic!("unexpected success {}", v),
    }
}

#[test]
fn test_stream() {
    let efd = match EventFD::new(11, EFD_SEMAPHORE) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };
    let mut count = 0;

    // only take 10 of 11 so the stream task doesn't block in read and hang the test
    for v in efd.events().iter().take(10) {
        assert!(v == 1);
        count += v;
    }

    assert!(count == 10)
}

#[test]
fn test_chan() {
    let (tx,rx) = std::comm::channel();
    let efd = match EventFD::new(10, 0) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };

    assert!(efd.write(1) == Ok(()));
    tx.send(efd);

    let t = std::task::try(proc() {
        let efd = rx.recv();
        assert!(efd.read() == Ok(11))
    });

    match t {
        Ok(_) => println!("ok"),
        Err(_) => panic!("failed"),
    }
}
<commit_msg>updated proc/spawn syntax to nightly<commit_after>//! EventFD binding
//!
//! This crate implements a simple binding for Linux eventfd(). See
//! eventfd(2) for specific details of behaviour.

extern crate libc;

use libc::{c_int, c_uint, c_void};
use std::io::{IoResult, IoError};
use std::os::unix::{AsRawFd,Fd};

pub struct EventFD {
    fd: uint,
    flags: uint,
}

unsafe impl Send for EventFD {}
unsafe impl Sync for EventFD {}

/// Construct a semaphore-style EventFD.
pub const EFD_SEMAPHORE: uint = 0x00001; // 00000001

/// In non-blocking mode, reads and writes will return IoError
/// containing EAGAIN rather than blocking.
pub const EFD_NONBLOCK: uint  = 0x00800; // 00004000

/// Set the close-on-exec flag on the eventfd.
pub const EFD_CLOEXEC: uint   = 0x80000; // 02000000

impl EventFD {
    /// Create a new EventFD. Flags is the bitwise OR of EFD_* constants, or 0 for no flags.
    /// The underlying file descriptor is closed when the EventFD instance's lifetime ends.
    ///
    /// TODO: work out how to integrate this FD into the wider world
    /// of fds. There's currently no way to poll/select on the fd.
    pub fn new(initval: uint, flags: uint) -> IoResult<EventFD> {
        let r = unsafe { eventfd(initval as u32, flags as u32) };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(EventFD { fd: r as uint, flags: flags })
        }
    }

    /// Read the current value of the eventfd. This will block until
    /// the value is non-zero. In semaphore mode this will only ever
    /// decrement the count by 1 and return 1; otherwise it atomically
    /// returns the current value and sets it to zero.
    pub fn read(&self) -> IoResult<u64> {
        let mut ret : u64 = 0;
        let r = unsafe {
            let ptr : *mut u64 = &mut ret;
            ::libc::read(self.fd as c_int, ptr as *mut c_void, std::mem::size_of_val(&ret) as u64)
        };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(ret)
        }
    }

    /// Add to the current value. Blocks if the value would wrap u64.
    pub fn write(&self, val: u64) -> IoResult<()> {
        let r = unsafe {
            let ptr : *const u64 = &val;
            ::libc::write(self.fd as c_int, ptr as *const c_void, std::mem::size_of_val(&val) as u64)
        };

        if r < 0 {
            Err(IoError::last_error())
        } else {
            Ok(())
        }
    }

    /// Return a stream of events. The channel has a synchronous
    /// sender because there's no point in building up a queue of
    /// events; if this task blocks on send, the event state will
    /// still update.
    ///
    /// The task will exit if the receiver end is shut down.
    ///
    /// This will be a CPU-spin loop if the EventFD is created
    /// non-blocking.
    ///
    /// XXX FIXME This has no way of terminating except if the other
    /// end closes the connection, and only then if we're not blocked
    /// in the read()...
    pub fn events(&self) -> std::comm::Receiver<u64> {
        let (tx, rx) = std::comm::sync_channel(1);
        let c = self.clone();

        std::thread::Thread::spawn(move || {
            loop {
                match c.read() {
                    Ok(v) => match tx.send_opt(v) {
                        Ok(_) => (),
                        Err(_) => break,
                    },
                    Err(e) => panic!("read failed: {}", e),
                }
            }
        }).detach();

        rx
    }
}

impl AsRawFd for EventFD {
    /// Return the raw underlying fd. The caller must make sure self's
    /// lifetime is longer than any users of the fd.
    fn as_raw_fd(&self) -> Fd {
        self.fd as Fd
    }
}

impl Drop for EventFD {
    fn drop(&mut self) {
        let r = unsafe { ::libc::close(self.fd as c_int) };
        if r < 0 {
            panic!("eventfd close {} failed", self.fd)
        }
    }
}

/// Construct a linked clone of an existing EventFD. Once created, the
/// new instance interacts with the original in a way that's
/// indistinguishable from the original.
impl Clone for EventFD {
    fn clone(&self) -> EventFD {
        let r = unsafe { ::libc::dup(self.fd as c_int) };
        if r < 0 {
            panic!("EventFD clone dup failed: {}", IoError::last_error())
        }

        EventFD { fd: r as uint, flags: self.flags }
    }
}

#[link(name = "c")]
extern "C" {
    fn eventfd(initval: c_uint, flags: c_uint) -> c_int;
}

#[test]
fn test_basic() {
    let (tx,rx) = std::comm::channel();
    let efd = match EventFD::new(10, 0) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };
    let cefd = efd.clone();

    assert!(efd.read() == Ok(10));

    std::thread::Thread::spawn(move || {
        assert!(cefd.read() == Ok(7));
        assert!(cefd.write(1) == Ok(()));
        assert!(cefd.write(2) == Ok(()));
        tx.send(());
    }).detach();

    assert!(efd.write(7) == Ok(()));
    rx.recv();
    assert!(efd.read() == Ok(3));
}

#[test]
fn test_sema() {
    let efd = match EventFD::new(0, EFD_SEMAPHORE | EFD_NONBLOCK) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };

    match efd.read() {
        Err(ref e) if e.kind == std::io::ResourceUnavailable => (), // ok
        Err(e) => panic!("unexpected error {}", e),
        Ok(v) => panic!("unexpected success {}", v),
    }

    assert!(efd.write(5) == Ok(()));

    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    assert!(efd.read() == Ok(1));
    match efd.read() {
        Err(ref e) if e.kind == std::io::ResourceUnavailable => (), // ok
        Err(e) => panic!("unexpected error {}", e),
        Ok(v) => panic!("unexpected success {}", v),
    }
}

#[test]
fn test_stream() {
    let efd = match EventFD::new(11, EFD_SEMAPHORE) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };
    let mut count = 0;

    // only take 10 of 11 so the stream task doesn't block in read and hang the test
    for v in efd.events().iter().take(10) {
        assert!(v == 1);
        count += v;
    }

    assert!(count == 10)
}

#[test]
fn test_chan() {
    let (tx,rx) = std::comm::channel();
    let efd = match EventFD::new(10, 0) {
        Err(e) => panic!("new failed {}", e),
        Ok(fd) => fd,
    };

    assert!(efd.write(1) == Ok(()));
    tx.send(efd);

    let t = std::thread::Thread::spawn(move || {
        let efd = rx.recv();
        assert!(efd.read() == Ok(11))
    }).join();

    match t {
        Ok(_) => println!("ok"),
        Err(_) => panic!("failed"),
    }
}
<|endoftext|>


<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.
#[macro_use] extern crate log;
#[macro_use] extern crate error_type;
extern crate rustc_serialize;
extern crate iron;
extern crate hyper;
extern crate router;
extern crate urlencoded;
extern crate redis;
extern crate spaceapi;

pub use spaceapi as api;
pub use iron::error::HttpResult;
pub use hyper::server::Listening;

mod server;
mod errors;
pub mod sensors;
pub mod modifiers;

pub use server::SpaceapiServer;
pub use errors::SpaceapiServerError;
<commit_msg>Set html_root_url<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.

#![doc(html_root_url = "https://coredump-ch.github.io/spaceapi-server-rs/")]

#[macro_use] extern crate log;
#[macro_use] extern crate error_type;
extern crate rustc_serialize;
extern crate iron;
extern crate hyper;
extern crate router;
extern crate urlencoded;
extern crate redis;
extern crate spaceapi;

pub use spaceapi as api;
pub use iron::error::HttpResult;
pub use hyper::server::Listening;

mod server;
mod errors;
pub mod sensors;
pub mod modifiers;

pub use server::SpaceapiServer;
pub use errors::SpaceapiServerError;
<|endoftext|>


<commit_before>#[macro_use]
extern crate maplit;
extern crate uuid;
extern crate serde;
extern crate serde_json;
extern crate rustc_serialize;
extern crate handlebars;
#[macro_use]
extern crate log;
#[macro_use]
mod macros;

pub use correlator::Correlator;
pub use config::action::ActionType;
pub use dispatcher::{Response};
pub use message::Message;

pub mod conditions;
pub mod config;
pub mod action;
pub mod condition;
mod context;
mod correlator;
mod dispatcher;
pub mod message;
mod state;
mod reactor;
mod timer;

pub type MiliSec = u32;
<commit_msg>lib: export some modules<commit_after>#[macro_use]
extern crate maplit;
extern crate uuid;
extern crate serde;
extern crate serde_json;
extern crate rustc_serialize;
extern crate handlebars;
#[macro_use]
extern crate log;
#[macro_use]
mod macros;

pub use correlator::Correlator;
pub use config::action::ActionType;
pub use dispatcher::{Response};
pub use message::Message;

pub mod conditions;
pub mod config;
pub mod action;
pub mod condition;
mod context;
mod correlator;
pub mod dispatcher;
pub mod message;
pub mod reactor;
mod state;
mod timer;

pub type MiliSec = u32;
<|endoftext|>


<commit_before>//! # mdBook
//!
//! **mdBook** is similar to Gitbook but implemented in Rust.
//! It offers a command line interface, but can also be used as a regular crate.
//!
//! This is the API doc, but you can find a [less "low-level" documentation here](../index.html)
//! that contains information about the command line tool, format, structure etc.
//! It is also rendered with mdBook to showcase the features and default theme.
//!
//! Some reasons why you would want to use the crate (over the cli):
//!
//! - Integrate mdbook in a current project
//! - Extend the capabilities of mdBook
//! - Do some processing or test before building your book
//! - Write a new Renderer
//! - ...
//!
//! ## Example
//!
//! ```no_run
//! extern crate mdbook;
//!
//! use mdbook::MDBook;
//!
//! # #[allow(unused_variables)]
//! fn main() {
//!     let mut book =  MDBook::new("my-book")        // Path to root
//!                         .with_source("src")       // Path from root to source directory
//!                         .with_destination("book") // Path from root to output directory
//!                         .read_config()            // Parse book.toml configuration file
//!                         .expect("I don't handle configuration file errors, but you should!");
//!
//!     book.build().unwrap();                        // Render the book
//! }
//! ```
//!
//! ## Implementing a new Renderer
//!
//! If you want to create a new renderer for mdBook, the only thing you have to do is to implement
//! the [Renderer trait](renderer/renderer/trait.Renderer.html)
//!
//! And then you can swap in your renderer like this:
//!
//! ```no_run
//! # extern crate mdbook;
//! #
//! # use mdbook::MDBook;
//! # use mdbook::renderer::HtmlHandlebars;
//! #
//! # #[allow(unused_variables)]
//! # fn main() {
//! #   let your_renderer = HtmlHandlebars::new();
//! #
//! let book = MDBook::new("my-book").set_renderer(Box::new(your_renderer));
//! # }
//! ```
//! If you make a renderer, you get the book constructed in form of `Vec<BookItems>` and you get
//! the book config in a `BookConfig` struct.
//!
//! It's your responsability to create the necessary files in the correct directories.
//!
//! ## utils
//!
//! I have regrouped some useful functions in the [utils](utils/index.html) module, like the
//! following function [`utils::fs::create_file(path:
//! &Path)`](utils/fs/fn.create_file.html)
//!
//! This function creates a file and returns it. But before creating the file
//! it checks every directory in the path to see if it exists, and if it does
//! not it will be created.
//!
//! Make sure to take a look at it.

#[macro_use]
extern crate error_chain;
extern crate handlebars;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate pulldown_cmark;
extern crate regex;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tempdir;

mod parse;
mod preprocess;
pub mod book;
pub mod config;
pub mod renderer;
pub mod theme;
pub mod utils;

pub use book::MDBook;
pub use book::BookItem;
pub use renderer::Renderer;

/// The error types used through out this crate.
pub mod errors {
    error_chain!{
        foreign_links {
            Io(::std::io::Error);
            HandlebarsRender(::handlebars::RenderError);
            HandlebarsTemplate(::handlebars::TemplateError);
            Utf8(::std::string::FromUtf8Error);
        }

        errors {
            Subprocess(message: String, output: ::std::process::Output) {
                description("A subprocess failed")
                display("{}: {}", message, String::from_utf8_lossy(&output.stdout))
            }
        }
    }
}
<commit_msg>Box Handlebars template error<commit_after>//! # mdBook
//!
//! **mdBook** is similar to Gitbook but implemented in Rust.
//! It offers a command line interface, but can also be used as a regular crate.
//!
//! This is the API doc, but you can find a [less "low-level" documentation here](../index.html)
//! that contains information about the command line tool, format, structure etc.
//! It is also rendered with mdBook to showcase the features and default theme.
//!
//! Some reasons why you would want to use the crate (over the cli):
//!
//! - Integrate mdbook in a current project
//! - Extend the capabilities of mdBook
//! - Do some processing or test before building your book
//! - Write a new Renderer
//! - ...
//!
//! ## Example
//!
//! ```no_run
//! extern crate mdbook;
//!
//! use mdbook::MDBook;
//!
//! # #[allow(unused_variables)]
//! fn main() {
//!     let mut book =  MDBook::new("my-book")        // Path to root
//!                         .with_source("src")       // Path from root to source directory
//!                         .with_destination("book") // Path from root to output directory
//!                         .read_config()            // Parse book.toml configuration file
//!                         .expect("I don't handle configuration file errors, but you should!");
//!
//!     book.build().unwrap();                        // Render the book
//! }
//! ```
//!
//! ## Implementing a new Renderer
//!
//! If you want to create a new renderer for mdBook, the only thing you have to do is to implement
//! the [Renderer trait](renderer/renderer/trait.Renderer.html)
//!
//! And then you can swap in your renderer like this:
//!
//! ```no_run
//! # extern crate mdbook;
//! #
//! # use mdbook::MDBook;
//! # use mdbook::renderer::HtmlHandlebars;
//! #
//! # #[allow(unused_variables)]
//! # fn main() {
//! #   let your_renderer = HtmlHandlebars::new();
//! #
//! let book = MDBook::new("my-book").set_renderer(Box::new(your_renderer));
//! # }
//! ```
//! If you make a renderer, you get the book constructed in form of `Vec<BookItems>` and you get
//! the book config in a `BookConfig` struct.
//!
//! It's your responsability to create the necessary files in the correct directories.
//!
//! ## utils
//!
//! I have regrouped some useful functions in the [utils](utils/index.html) module, like the
//! following function [`utils::fs::create_file(path:
//! &Path)`](utils/fs/fn.create_file.html)
//!
//! This function creates a file and returns it. But before creating the file
//! it checks every directory in the path to see if it exists, and if it does
//! not it will be created.
//!
//! Make sure to take a look at it.

#[macro_use]
extern crate error_chain;
extern crate handlebars;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate pulldown_cmark;
extern crate regex;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate tempdir;

mod parse;
mod preprocess;
pub mod book;
pub mod config;
pub mod renderer;
pub mod theme;
pub mod utils;

pub use book::MDBook;
pub use book::BookItem;
pub use renderer::Renderer;

/// The error types used through out this crate.
pub mod errors {
    error_chain!{
        foreign_links {
            Io(::std::io::Error);
            HandlebarsRender(::handlebars::RenderError);
            HandlebarsTemplate(Box<::handlebars::TemplateError>);
            Utf8(::std::string::FromUtf8Error);
        }

        errors {
            Subprocess(message: String, output: ::std::process::Output) {
                description("A subprocess failed")
                display("{}: {}", message, String::from_utf8_lossy(&output.stdout))
            }
        }
    }

    // Box to halve the size of Error
    impl From<::handlebars::TemplateError> for Error {
        fn from(e: ::handlebars::TemplateError) -> Error {
            From::from(Box::new(e))
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
#[macro_use]
pub extern crate log;

pub type RequestId = i32;

pub mod asn1 {
    //! ASN.1 structure construction and parsing.
    //!
    //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
    //! be extensively overhauled in the future. If you need examples of using the present interface
    //! for, e.g., implementing a new extended operation or a control, consult the source of existing
    //! exops/controls.
    pub use lber::common::TagClass;
    pub use lber::parse::{parse_tag, parse_uint};
    pub use lber::structure::{StructureTag, PL};
    pub use lber::structures::{
        ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
    };
    pub use lber::write;
    pub use lber::IResult;
}
mod conn;
pub mod controls {
    //! Control construction and parsing.
    //!
    //! A control can be associated with a request or a response. Several common
    //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
    //! directly by this library. If an implemented control has the same form for
    //! the request and the response, there will be a single structure for both.
    //! (This is the case for `PagedResults`.) If the response control is different,
    //! its name will consist of the request control name with the `Resp` suffix.
    //!
    //! A request control can be created by instantiating its structure and converting
    //! it to ASN.1 with `into()` when passing the instance or constructing the request
    //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
    //! A third-party control must implement the conversion from an instance
    //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
    //!
    //! `RawControl`, together with an optional instance of [`ControlType`](types/index.html),
    //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
    //! of the result of all LDAP operation which return one.
    //!
    //! The first element of `Control` will have a value if the parser recognizes
    //! the control's OID as one that is implemented by the library itself. Since the
    //! list of implemented controls is expected to grow, matching those values must
    //! be done through reexported types in the [`types`](types/index.html) module,
    //! and cannot be exhaustive.
    //!
    //! A recognized response control can be parsed by calling
    //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
    //! representing it. A third-party control must implement the
    //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
    pub use crate::controls_impl::types;
    pub use crate::controls_impl::{Assertion, PagedResults, ProxyAuth, RelaxRules};
    pub use crate::controls_impl::{
        Control, ControlParser, CriticalControl, MakeCritical, RawControl,
    };
    pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
}
mod controls_impl;
mod exop_impl;
pub mod exop {
    //! Extended operation construction and parsing.
    //!
    //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
    //! exop is implemented by this library, it may have one or two associated structs;
    //! one for constructing requests, and another for parsing responses. If request and
    //! response are the same, there is only the request struct; if they are different,
    //! the response struct's name will consist of the request struct name with the
    //! `Resp` suffix.
    //!
    //! A request struct must implement the `From` conversion of itself into `Exop`.
    //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
    //! trait.
    pub use crate::exop_impl::{Exop, ExopParser, WhoAmI, WhoAmIResp};
}
mod filter;
mod ldap;
mod protocol;
pub mod result;
mod search;
#[cfg(feature = "sync")]
mod sync;

pub use conn::{LdapConnAsync, LdapConnSettings};
pub use filter::parse as parse_filter;
pub use ldap::{Ldap, Mod};
pub use result::{LdapError, LdapResult};
pub use search::{Scope, SearchEntry, SearchStream};
#[cfg(feature = "sync")]
pub use sync::LdapConn;
<commit_msg>Reexport ASN.1 types<commit_after>#[macro_use]
extern crate nom;
#[macro_use]
pub extern crate log;

pub type RequestId = i32;

pub mod asn1 {
    //! ASN.1 structure construction and parsing.
    //!
    //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
    //! be extensively overhauled in the future. If you need examples of using the present interface
    //! for, e.g., implementing a new extended operation or a control, consult the source of existing
    //! exops/controls.
    pub use lber::common::TagClass;
    pub use lber::parse::{parse_tag, parse_uint};
    pub use lber::structure::{StructureTag, PL};
    pub use lber::structures::{
        ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
    };
    pub use lber::universal::Types;
    pub use lber::write;
    pub use lber::IResult;
}
mod conn;
pub mod controls {
    //! Control construction and parsing.
    //!
    //! A control can be associated with a request or a response. Several common
    //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
    //! directly by this library. If an implemented control has the same form for
    //! the request and the response, there will be a single structure for both.
    //! (This is the case for `PagedResults`.) If the response control is different,
    //! its name will consist of the request control name with the `Resp` suffix.
    //!
    //! A request control can be created by instantiating its structure and converting
    //! it to ASN.1 with `into()` when passing the instance or constructing the request
    //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
    //! A third-party control must implement the conversion from an instance
    //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
    //!
    //! `RawControl`, together with an optional instance of [`ControlType`](types/index.html),
    //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
    //! of the result of all LDAP operation which return one.
    //!
    //! The first element of `Control` will have a value if the parser recognizes
    //! the control's OID as one that is implemented by the library itself. Since the
    //! list of implemented controls is expected to grow, matching those values must
    //! be done through reexported types in the [`types`](types/index.html) module,
    //! and cannot be exhaustive.
    //!
    //! A recognized response control can be parsed by calling
    //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
    //! representing it. A third-party control must implement the
    //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
    pub use crate::controls_impl::types;
    pub use crate::controls_impl::{Assertion, PagedResults, ProxyAuth, RelaxRules};
    pub use crate::controls_impl::{
        Control, ControlParser, CriticalControl, MakeCritical, RawControl,
    };
    pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
}
mod controls_impl;
mod exop_impl;
pub mod exop {
    //! Extended operation construction and parsing.
    //!
    //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
    //! exop is implemented by this library, it may have one or two associated structs;
    //! one for constructing requests, and another for parsing responses. If request and
    //! response are the same, there is only the request struct; if they are different,
    //! the response struct's name will consist of the request struct name with the
    //! `Resp` suffix.
    //!
    //! A request struct must implement the `From` conversion of itself into `Exop`.
    //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
    //! trait.
    pub use crate::exop_impl::{Exop, ExopParser, WhoAmI, WhoAmIResp};
}
mod filter;
mod ldap;
mod protocol;
pub mod result;
mod search;
#[cfg(feature = "sync")]
mod sync;

pub use conn::{LdapConnAsync, LdapConnSettings};
pub use filter::parse as parse_filter;
pub use ldap::{Ldap, Mod};
pub use result::{LdapError, LdapResult};
pub use search::{Scope, SearchEntry, SearchStream};
#[cfg(feature = "sync")]
pub use sync::LdapConn;
<|endoftext|>