<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use std::fmt::Display;
use std::path::Path;
use std::vec::Vec;
use std::rc::Rc;
use std::cell::RefCell;

use dbus;
use dbus::Connection;
use dbus::BusType;
use dbus::Message;
use dbus::MessageItem;
use dbus::NameFlag;
use dbus::arg::Array;
use dbus::arg::IterAppend;
use dbus::tree::Access;
use dbus::tree::EmitsChangedSignal;
use dbus::tree::Factory;
use dbus::tree::MethodErr;
use dbus::tree::MTFn;
use dbus::tree::MethodResult;
use dbus::tree::MethodInfo;
use dbus::tree::PropInfo;
use dbus::tree::Tree;
use dbus::ConnectionItem;

use engine::{Engine, Redundancy};
use stratis::VERSION;

use super::filesystem::create_dbus_filesystem;
use super::blockdev::create_dbus_blockdev;
use super::pool::create_dbus_pool;
use super::types::{DeferredAction, DbusContext, DbusErrorEnum, TData};
use super::util::STRATIS_BASE_PATH;
use super::util::STRATIS_BASE_SERVICE;
use super::util::code_to_message_items;
use super::util::default_object_path;
use super::util::engine_to_dbus_err;
use super::util::get_next_arg;
use super::util::ok_message_items;
use super::util::tuple_to_option;

fn create_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let name: &str = get_next_arg(&mut iter, 0)?;
    let redundancy: (bool, u16) = get_next_arg(&mut iter, 1)?;
    let force: bool = get_next_arg(&mut iter, 2)?;
    let devs: Array<&str, _> = get_next_arg(&mut iter, 3)?;

    let blockdevs = devs.map(|x| Path::new(x)).collect::<Vec<&Path>>();

    let object_path = m.path.get_name();
    let dbus_context = m.tree.get_data();
    let mut engine = dbus_context.engine.borrow_mut();
    let result = engine.create_pool(name, &blockdevs, tuple_to_option(redundancy), force);

    let return_message = message.method_return();

    let msg = match result {
        Ok(pool_uuid) => {
            let pool_object_path: dbus::Path =
                create_dbus_pool(dbus_context, object_path.clone(), pool_uuid);
            let default_return =
                MessageItem::Struct(vec![MessageItem::ObjectPath(default_object_path()),
                                         MessageItem::Array(vec![], "o".into())]);
            let pool = get_mut_pool!(engine; pool_uuid; default_return; return_message);

            let bd_object_paths = pool.blockdevs()
                .iter()
                .map(|bd| {
                         MessageItem::ObjectPath(create_dbus_blockdev(dbus_context,
                                                                      pool_object_path.clone(),
                                                                      bd.uuid()))
                     })
                .collect::<Vec<_>>();

            let return_path = MessageItem::ObjectPath(pool_object_path);
            let return_list = MessageItem::Array(bd_object_paths, "o".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = ok_message_items();
            return_message.append3(return_value, rc, rs)
        }
        Err(x) => {
            let return_path = MessageItem::ObjectPath(default_object_path());
            let return_list = MessageItem::Array(vec![], "s".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = engine_to_dbus_err(&x);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(return_value, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn destroy_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {

    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let object_path: dbus::Path<'static> = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();

    let default_return = MessageItem::Bool(false);
    let return_message = message.method_return();

    let pool_uuid = match m.tree.get(&object_path) {
        Some(pool_path) => get_data!(pool_path; default_return; return_message).uuid,
        None => {
            let (rc, rs) = ok_message_items();
            return Ok(vec![return_message.append3(default_return, rc, rs)]);
        }
    };

    let msg = match dbus_context.engine.borrow_mut().destroy_pool(pool_uuid) {
        Ok(action) => {
            dbus_context
                .actions
                .borrow_mut()
                .push_remove(object_path);
            let (rc, rs) = ok_message_items();
            return_message.append3(MessageItem::Bool(action), rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(default_return, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_list_items<T, I>(i: &mut IterAppend, iter: I) -> Result<(), MethodErr>
    where T: Display + Into<u16>,
          I: Iterator<Item = T>
{
    let msg_vec = iter.map(|item| {
                               MessageItem::Struct(vec![MessageItem::Str(format!("{}", item)),
                                                        MessageItem::UInt16(item.into())])
                           })
        .collect::<Vec<MessageItem>>();
    i.append(MessageItem::Array(msg_vec, Cow::Borrowed("(sq)")));
    Ok(())
}

fn get_error_values(i: &mut IterAppend,
                    _p: &PropInfo<MTFn<TData>, TData>)
                    -> Result<(), MethodErr> {
    get_list_items(i, DbusErrorEnum::iter_variants())
}

fn get_redundancy_values(i: &mut IterAppend,
                         _p: &PropInfo<MTFn<TData>, TData>)
                         -> Result<(), MethodErr> {
    get_list_items(i, Redundancy::iter_variants())
}

fn get_version(i: &mut IterAppend, _p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    i.append(VERSION);
    Ok(())
}

fn configure_simulator(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message = m.msg;
    let mut iter = message.iter_init();

    let denominator: u32 = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();
    let result = dbus_context
        .engine
        .borrow_mut()
        .configure_simulator(denominator);

    let return_message = message.method_return();

    let msg = match result {
        Ok(_) => {
            let (rc, rs) = ok_message_items();
            return_message.append2(rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append2(rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_base_tree<'a>(dbus_context: DbusContext) -> (Tree<MTFn<TData>, TData>, dbus::Path<'a>) {

    let f = Factory::new_fn();

    let base_tree = f.tree(dbus_context);

    let create_pool_method = f.method("CreatePool", (), create_pool)
        .in_arg(("name", "s"))
        .in_arg(("redundancy", "(bq)"))
        .in_arg(("force", "b"))
        .in_arg(("devices", "as"))
        .out_arg(("result", "(oao)"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroy_pool_method = f.method("DestroyPool", (), destroy_pool)
        .in_arg(("pool", "o"))
        .out_arg(("action", "b"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let configure_simulator_method = f.method("ConfigureSimulator", (), configure_simulator)
        .in_arg(("denominator", "u"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let redundancy_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("RedundancyValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_redundancy_values);

    let error_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("ErrorValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_error_values);

    let version_property = f.property::<&str, _>("Version", ())
        .access(Access::Read)
        .emits_changed(EmitsChangedSignal::Const)
        .on_get(get_version);

    let interface_name = format!("{}.{}", STRATIS_BASE_SERVICE, "Manager");

    let obj_path = f.object_path(STRATIS_BASE_PATH, None)
        .introspectable()
        .object_manager()
        .add(f.interface(interface_name, ())
                 .add_m(create_pool_method)
                 .add_m(destroy_pool_method)
                 .add_m(configure_simulator_method)
                 .add_p(error_values_property)
                 .add_p(redundancy_values_property)
                 .add_p(version_property));

    let path = obj_path.get_name().to_owned();
    (base_tree.add(obj_path), path)
}

#[allow(type_complexity)]
pub fn connect(engine: Rc<RefCell<Engine>>)
               -> Result<(Connection, Tree<MTFn<TData>, TData>, DbusContext), dbus::Error> {
    let c = Connection::get_private(BusType::System)?;

    let local_engine = Rc::clone(&engine);

    let (tree, object_path) = get_base_tree(DbusContext::new(engine));
    let dbus_context = tree.get_data().clone();

    // This should never panic as create_dbus_pool(),
    // create_dbus_filesystem(), and create_dbus_blockdev() do not borrow the
    // engine.
    for pool in local_engine.borrow().pools() {
        let pool_path = create_dbus_pool(&dbus_context, object_path.clone(), pool.uuid());
        for fs_uuid in pool.filesystems().iter().map(|f| f.uuid()) {
            create_dbus_filesystem(&dbus_context, pool_path.clone(), fs_uuid);
        }
        for dev_uuid in pool.blockdevs().iter().map(|bd| bd.uuid()) {
            create_dbus_blockdev(&dbus_context, pool_path.clone(), dev_uuid);
        }
    }

    tree.set_registered(&c, true)?;

    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32)?;

    Ok((c, tree, dbus_context))
}

pub fn handle(c: &Connection,
              item: &ConnectionItem,
              tree: &mut Tree<MTFn<TData>, TData>,
              dbus_context: &DbusContext)
              -> Result<(), dbus::Error> {
    if let ConnectionItem::MethodCall(ref msg) = *item {
        if let Some(v) = tree.handle(msg) {
            // Probably the wisest is to ignore any send errors here -
            // maybe the remote has disconnected during our processing.
            for m in v {
                let _ = c.send(m);
            }
        }

        let mut b_actions = dbus_context.actions.borrow_mut();
        for action in b_actions.drain() {
            match action {
                DeferredAction::Add(path) => {
                    c.register_object_path(path.get_name())?;
                    tree.insert(path);
                }
                DeferredAction::Remove(path) => {
                    c.unregister_object_path(&path);
                    tree.remove(&path);
                }
            }
        }
    }

    Ok(())
}
<commit_msg>dbus api: Handle deferred at start up<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use std::fmt::Display;
use std::path::Path;
use std::vec::Vec;
use std::rc::Rc;
use std::cell::RefCell;

use dbus;
use dbus::Connection;
use dbus::BusType;
use dbus::Message;
use dbus::MessageItem;
use dbus::NameFlag;
use dbus::arg::Array;
use dbus::arg::IterAppend;
use dbus::tree::Access;
use dbus::tree::EmitsChangedSignal;
use dbus::tree::Factory;
use dbus::tree::MethodErr;
use dbus::tree::MTFn;
use dbus::tree::MethodResult;
use dbus::tree::MethodInfo;
use dbus::tree::PropInfo;
use dbus::tree::Tree;
use dbus::ConnectionItem;

use engine::{Engine, Redundancy};
use stratis::VERSION;

use super::filesystem::create_dbus_filesystem;
use super::blockdev::create_dbus_blockdev;
use super::pool::create_dbus_pool;
use super::types::{ActionQueue, DeferredAction, DbusContext, DbusErrorEnum, TData};
use super::util::STRATIS_BASE_PATH;
use super::util::STRATIS_BASE_SERVICE;
use super::util::code_to_message_items;
use super::util::default_object_path;
use super::util::engine_to_dbus_err;
use super::util::get_next_arg;
use super::util::ok_message_items;
use super::util::tuple_to_option;

fn create_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let name: &str = get_next_arg(&mut iter, 0)?;
    let redundancy: (bool, u16) = get_next_arg(&mut iter, 1)?;
    let force: bool = get_next_arg(&mut iter, 2)?;
    let devs: Array<&str, _> = get_next_arg(&mut iter, 3)?;

    let blockdevs = devs.map(|x| Path::new(x)).collect::<Vec<&Path>>();

    let object_path = m.path.get_name();
    let dbus_context = m.tree.get_data();
    let mut engine = dbus_context.engine.borrow_mut();
    let result = engine.create_pool(name, &blockdevs, tuple_to_option(redundancy), force);

    let return_message = message.method_return();

    let msg = match result {
        Ok(pool_uuid) => {
            let pool_object_path: dbus::Path =
                create_dbus_pool(dbus_context, object_path.clone(), pool_uuid);
            let default_return =
                MessageItem::Struct(vec![MessageItem::ObjectPath(default_object_path()),
                                         MessageItem::Array(vec![], "o".into())]);
            let pool = get_mut_pool!(engine; pool_uuid; default_return; return_message);

            let bd_object_paths = pool.blockdevs()
                .iter()
                .map(|bd| {
                         MessageItem::ObjectPath(create_dbus_blockdev(dbus_context,
                                                                      pool_object_path.clone(),
                                                                      bd.uuid()))
                     })
                .collect::<Vec<_>>();

            let return_path = MessageItem::ObjectPath(pool_object_path);
            let return_list = MessageItem::Array(bd_object_paths, "o".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = ok_message_items();
            return_message.append3(return_value, rc, rs)
        }
        Err(x) => {
            let return_path = MessageItem::ObjectPath(default_object_path());
            let return_list = MessageItem::Array(vec![], "s".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = engine_to_dbus_err(&x);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(return_value, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn destroy_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {

    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let object_path: dbus::Path<'static> = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();

    let default_return = MessageItem::Bool(false);
    let return_message = message.method_return();

    let pool_uuid = match m.tree.get(&object_path) {
        Some(pool_path) => get_data!(pool_path; default_return; return_message).uuid,
        None => {
            let (rc, rs) = ok_message_items();
            return Ok(vec![return_message.append3(default_return, rc, rs)]);
        }
    };

    let msg = match dbus_context.engine.borrow_mut().destroy_pool(pool_uuid) {
        Ok(action) => {
            dbus_context
                .actions
                .borrow_mut()
                .push_remove(object_path);
            let (rc, rs) = ok_message_items();
            return_message.append3(MessageItem::Bool(action), rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(default_return, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_list_items<T, I>(i: &mut IterAppend, iter: I) -> Result<(), MethodErr>
    where T: Display + Into<u16>,
          I: Iterator<Item = T>
{
    let msg_vec = iter.map(|item| {
                               MessageItem::Struct(vec![MessageItem::Str(format!("{}", item)),
                                                        MessageItem::UInt16(item.into())])
                           })
        .collect::<Vec<MessageItem>>();
    i.append(MessageItem::Array(msg_vec, Cow::Borrowed("(sq)")));
    Ok(())
}

fn get_error_values(i: &mut IterAppend,
                    _p: &PropInfo<MTFn<TData>, TData>)
                    -> Result<(), MethodErr> {
    get_list_items(i, DbusErrorEnum::iter_variants())
}

fn get_redundancy_values(i: &mut IterAppend,
                         _p: &PropInfo<MTFn<TData>, TData>)
                         -> Result<(), MethodErr> {
    get_list_items(i, Redundancy::iter_variants())
}

fn get_version(i: &mut IterAppend, _p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    i.append(VERSION);
    Ok(())
}

fn configure_simulator(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message = m.msg;
    let mut iter = message.iter_init();

    let denominator: u32 = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();
    let result = dbus_context
        .engine
        .borrow_mut()
        .configure_simulator(denominator);

    let return_message = message.method_return();

    let msg = match result {
        Ok(_) => {
            let (rc, rs) = ok_message_items();
            return_message.append2(rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append2(rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_base_tree<'a>(dbus_context: DbusContext) -> (Tree<MTFn<TData>, TData>, dbus::Path<'a>) {

    let f = Factory::new_fn();

    let base_tree = f.tree(dbus_context);

    let create_pool_method = f.method("CreatePool", (), create_pool)
        .in_arg(("name", "s"))
        .in_arg(("redundancy", "(bq)"))
        .in_arg(("force", "b"))
        .in_arg(("devices", "as"))
        .out_arg(("result", "(oao)"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroy_pool_method = f.method("DestroyPool", (), destroy_pool)
        .in_arg(("pool", "o"))
        .out_arg(("action", "b"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let configure_simulator_method = f.method("ConfigureSimulator", (), configure_simulator)
        .in_arg(("denominator", "u"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let redundancy_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("RedundancyValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_redundancy_values);

    let error_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("ErrorValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_error_values);

    let version_property = f.property::<&str, _>("Version", ())
        .access(Access::Read)
        .emits_changed(EmitsChangedSignal::Const)
        .on_get(get_version);

    let interface_name = format!("{}.{}", STRATIS_BASE_SERVICE, "Manager");

    let obj_path = f.object_path(STRATIS_BASE_PATH, None)
        .introspectable()
        .object_manager()
        .add(f.interface(interface_name, ())
                 .add_m(create_pool_method)
                 .add_m(destroy_pool_method)
                 .add_m(configure_simulator_method)
                 .add_p(error_values_property)
                 .add_p(redundancy_values_property)
                 .add_p(version_property));

    let path = obj_path.get_name().to_owned();
    (base_tree.add(obj_path), path)
}

#[allow(type_complexity)]
pub fn connect(engine: Rc<RefCell<Engine>>)
               -> Result<(Connection, Tree<MTFn<TData>, TData>, DbusContext), dbus::Error> {
    let c = Connection::get_private(BusType::System)?;

    let local_engine = Rc::clone(&engine);

    let (mut tree, object_path) = get_base_tree(DbusContext::new(engine));
    let dbus_context = tree.get_data().clone();

    // This should never panic as create_dbus_pool(),
    // create_dbus_filesystem(), and create_dbus_blockdev() do not borrow the
    // engine.
    for pool in local_engine.borrow().pools() {
        let pool_path = create_dbus_pool(&dbus_context, object_path.clone(), pool.uuid());
        for fs_uuid in pool.filesystems().iter().map(|f| f.uuid()) {
            create_dbus_filesystem(&dbus_context, pool_path.clone(), fs_uuid);
        }
        for dev_uuid in pool.blockdevs().iter().map(|bd| bd.uuid()) {
            create_dbus_blockdev(&dbus_context, pool_path.clone(), dev_uuid);
        }
    }

    tree.set_registered(&c, true)?;

    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32)?;

    process_deferred_actions(&c, &mut tree, &dbus_context.actions)?;

    Ok((c, tree, dbus_context))
}

/// Update the dbus tree with deferred adds and removes.
fn process_deferred_actions(c: &Connection,
                            tree: &mut Tree<MTFn<TData>, TData>,
                            actions: &Rc<RefCell<ActionQueue>>)
                            -> Result<(), dbus::Error> {
    let mut b_actions = actions.borrow_mut();
    for action in b_actions.drain() {
        match action {
            DeferredAction::Add(path) => {
                c.register_object_path(path.get_name())?;
                tree.insert(path);
            }
            DeferredAction::Remove(path) => {
                c.unregister_object_path(&path);
                tree.remove(&path);
            }
        }
    }
    Ok(())
}

pub fn handle(c: &Connection,
              item: &ConnectionItem,
              tree: &mut Tree<MTFn<TData>, TData>,
              dbus_context: &DbusContext)
              -> Result<(), dbus::Error> {
    if let ConnectionItem::MethodCall(ref msg) = *item {
        if let Some(v) = tree.handle(msg) {
            // Probably the wisest is to ignore any send errors here -
            // maybe the remote has disconnected during our processing.
            for m in v {
                let _ = c.send(m);
            }
        }

        process_deferred_actions(c, tree, &dbus_context.actions)?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>use decoders::tiff::*;
use std::fmt;

/// Representation of the color filter array pattern in raw cameras
///
/// # Example
/// ```
/// use rawloader::CFA;
/// let cfa = CFA::new("RGGB");
/// assert_eq!(cfa.color_at(0,0), 0);
/// assert_eq!(cfa.color_at(0,1), 1);
/// assert_eq!(cfa.color_at(1,0), 1);
/// assert_eq!(cfa.color_at(1,1), 2);
/// ```
///
/// You will almost always get your CFA struct from a RawImage decode, already fully
/// initialized and ready to be used in processing. The color_at() implementation is
/// designed to be fast so it can be called inside the inner loop of demosaic or other
/// color-aware algorithms that work on pre-demosaic data
pub struct CFA {
  pub name: String,
  pub width: usize,
  pub height: usize,

  pattern: [[usize;48];48],
}

impl CFA {
  #[doc(hidden)] pub fn new_from_tag(pat: &TiffEntry) -> CFA {
    let mut patname = String::new();
    for i in 0..pat.count() {
      patname.push(match pat.get_u32(i as usize) {
        0 => 'R',
        1 => 'G',
        2 => 'B',
        _ => 'U',
      });
    }
    CFA::new(&patname)
  }

  /// Create a new CFA from a string describing it. For simplicity the pattern is specified
  /// as each pixel being one of R/G/B/E representing the 0/1/2/3 colors in a 4 color image.
  /// The pattern is specified as the colors in each row concatenated so RGGB means that
  /// the first row is RG and the second row GB. Row size is determined by pattern size
  /// (e.g., the xtrans pattern is 6x6 and thus 36 characters long). In theory this could
  /// lead to confusion between different pattern sizes but in practice there are only
  /// a few oddball cameras no one cares about that do anything but 2x2 and 6x6 (and those
  /// work fine with this as well).
  pub fn new(patname: &str) -> CFA {
    let (width, height) = match patname.len() {
      0 => (0,0),
      4 => (2,2),
      36 => (6,6),
      16 => (2,8),
      144 => (12,12),
      _ => panic!(format!("Unknown CFA size \"{}\"", patname).to_string()),
    };
    let mut pattern: [[usize;48];48] = [[0;48];48];

    if width > 0 {
      // copy the pattern into the top left
      for (i,c) in patname.bytes().enumerate() {
        pattern[i/width][i%width] = match c {
          b'R' => 0,
          b'G' => 1,
          b'B' => 2,
          b'E' => 3,
          b'M' => 1,
          b'Y' => 3,
          _   => panic!(format!("Unknown CFA color \"{}\"", c).to_string()),
        };
      }

      // extend the pattern into the full matrix
      for row in 0..48 {
        for col in 0..48 {
          pattern[row][col] = pattern[row%height][col%width];
        }
      }
    }

    CFA {
      name: patname.to_string(),
      pattern: pattern,
      width: width,
      height: height,
    }
  }

  /// Get the color index at the given position. Designed to be fast so it can be called
  /// from inner loops without performance issues.
  pub fn color_at(&self, row: usize, col: usize) -> usize {
    self.pattern[(row+48) % 48][(col+48) % 48]
  }

  /// Shift the pattern left and/or down. This is useful when cropping the image to get
  /// the equivalent pattern of the crop when it's not a multiple of the pattern size.
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.color_at(0,0), 0);
  /// assert_eq!(cfa.color_at(0,1), 1);
  /// assert_eq!(cfa.color_at(1,0), 1);
  /// assert_eq!(cfa.color_at(1,1), 2);
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.color_at(0,0), 2);
  /// assert_eq!(shifted.color_at(0,1), 1);
  /// assert_eq!(shifted.color_at(1,0), 1);
  /// assert_eq!(shifted.color_at(1,1), 0);
  /// ```
  pub fn shift(&self, x: usize, y: usize) -> CFA {
    let mut pattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        pattern[row][col] = self.color_at(row+y,col+x);
      }
    }

    let mut name = "".to_string();
    for row in 0..self.height {
      for col in 0..self.width {
        name.push_str(match pattern[row][col] {
          0 => "R",
          1 => "G",
          2 => "B",
          3 => "E",
          x => panic!(format!("Unknown CFA color \"{}\"", x).to_string()),
        });
      }
    }

    CFA {
      name: name,
      pattern: pattern,
      width: self.width,
      height: self.height,
    }
  }

  /// Test if this is actually a valid CFA pattern
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert!(cfa.is_valid());
  ///
  /// let cfa = CFA::new("");
  /// assert!(!cfa.is_valid());
  /// ```
  pub fn is_valid(&self) -> bool {
    self.width != 0 && self.height != 0
  }

  /// Convert the CFA back into a pattern string
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.to_string(), "RGGB");
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.to_string(), "BGGR");
  /// ```
  pub fn to_string(&self) -> String {
    self.name.clone()
  }
}

impl fmt::Debug for CFA {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "CFA {{ {} }}", self.name)
  }
}

impl Clone for CFA {
  fn clone(&self) -> CFA {
    let mut cpattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        cpattern[row][col] = self.pattern[row][col];
      }
    }
    CFA {
      name: self.name.clone(),
      pattern: cpattern,
      width: self.width,
      height: self.height,
    }
  }
}
<commit_msg>Simplified panic message formatting for unknown cfa colors<commit_after>use decoders::tiff::*;
use std::fmt;

/// Representation of the color filter array pattern in raw cameras
///
/// # Example
/// ```
/// use rawloader::CFA;
/// let cfa = CFA::new("RGGB");
/// assert_eq!(cfa.color_at(0,0), 0);
/// assert_eq!(cfa.color_at(0,1), 1);
/// assert_eq!(cfa.color_at(1,0), 1);
/// assert_eq!(cfa.color_at(1,1), 2);
/// ```
///
/// You will almost always get your CFA struct from a RawImage decode, already fully
/// initialized and ready to be used in processing. The color_at() implementation is
/// designed to be fast so it can be called inside the inner loop of demosaic or other
/// color-aware algorithms that work on pre-demosaic data
pub struct CFA {
  pub name: String,
  pub width: usize,
  pub height: usize,

  pattern: [[usize;48];48],
}

impl CFA {
  #[doc(hidden)] pub fn new_from_tag(pat: &TiffEntry) -> CFA {
    let mut patname = String::new();
    for i in 0..pat.count() {
      patname.push(match pat.get_u32(i as usize) {
        0 => 'R',
        1 => 'G',
        2 => 'B',
        _ => 'U',
      });
    }
    CFA::new(&patname)
  }

  /// Create a new CFA from a string describing it. For simplicity the pattern is specified
  /// as each pixel being one of R/G/B/E representing the 0/1/2/3 colors in a 4 color image.
  /// The pattern is specified as the colors in each row concatenated so RGGB means that
  /// the first row is RG and the second row GB. Row size is determined by pattern size
  /// (e.g., the xtrans pattern is 6x6 and thus 36 characters long). In theory this could
  /// lead to confusion between different pattern sizes but in practice there are only
  /// a few oddball cameras no one cares about that do anything but 2x2 and 6x6 (and those
  /// work fine with this as well).
  pub fn new(patname: &str) -> CFA {
    let (width, height) = match patname.len() {
      0 => (0,0),
      4 => (2,2),
      36 => (6,6),
      16 => (2,8),
      144 => (12,12),
      _ => panic!(format!("Unknown CFA size \"{}\"", patname).to_string()),
    };
    let mut pattern: [[usize;48];48] = [[0;48];48];

    if width > 0 {
      // copy the pattern into the top left
      for (i,c) in patname.bytes().enumerate() {
        pattern[i/width][i%width] = match c {
          b'R' => 0,
          b'G' => 1,
          b'B' => 2,
          b'E' => 3,
          b'M' => 1,
          b'Y' => 3,
          _    => panic!("Unknown CFA color \"{}\"", c),
        };
      }

      // extend the pattern into the full matrix
      for row in 0..48 {
        for col in 0..48 {
          pattern[row][col] = pattern[row%height][col%width];
        }
      }
    }

    CFA {
      name: patname.to_string(),
      pattern: pattern,
      width: width,
      height: height,
    }
  }

  /// Get the color index at the given position. Designed to be fast so it can be called
  /// from inner loops without performance issues.
  pub fn color_at(&self, row: usize, col: usize) -> usize {
    self.pattern[(row+48) % 48][(col+48) % 48]
  }

  /// Shift the pattern left and/or down. This is useful when cropping the image to get
  /// the equivalent pattern of the crop when it's not a multiple of the pattern size.
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.color_at(0,0), 0);
  /// assert_eq!(cfa.color_at(0,1), 1);
  /// assert_eq!(cfa.color_at(1,0), 1);
  /// assert_eq!(cfa.color_at(1,1), 2);
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.color_at(0,0), 2);
  /// assert_eq!(shifted.color_at(0,1), 1);
  /// assert_eq!(shifted.color_at(1,0), 1);
  /// assert_eq!(shifted.color_at(1,1), 0);
  /// ```
  pub fn shift(&self, x: usize, y: usize) -> CFA {
    let mut pattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        pattern[row][col] = self.color_at(row+y,col+x);
      }
    }

    let mut name = "".to_string();
    for row in 0..self.height {
      for col in 0..self.width {
        name.push_str(match pattern[row][col] {
          0 => "R",
          1 => "G",
          2 => "B",
          3 => "E",
          x => panic!(format!("Unknown CFA color \"{}\"", x).to_string()),
        });
      }
    }

    CFA {
      name: name,
      pattern: pattern,
      width: self.width,
      height: self.height,
    }
  }

  /// Test if this is actually a valid CFA pattern
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert!(cfa.is_valid());
  ///
  /// let cfa = CFA::new("");
  /// assert!(!cfa.is_valid());
  /// ```
  pub fn is_valid(&self) -> bool {
    self.width != 0 && self.height != 0
  }

  /// Convert the CFA back into a pattern string
  ///
  /// # Example
  /// ```
  /// use rawloader::CFA;
  /// let cfa = CFA::new("RGGB");
  /// assert_eq!(cfa.to_string(), "RGGB");
  ///
  /// let shifted = cfa.shift(1,1);
  /// assert_eq!(shifted.to_string(), "BGGR");
  /// ```
  pub fn to_string(&self) -> String {
    self.name.clone()
  }
}

impl fmt::Debug for CFA {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "CFA {{ {} }}", self.name)
  }
}

impl Clone for CFA {
  fn clone(&self) -> CFA {
    let mut cpattern: [[usize;48];48] = [[0;48];48];
    for row in 0..48 {
      for col in 0..48 {
        cpattern[row][col] = self.pattern[row][col];
      }
    }
    CFA {
      name: self.name.clone(),
      pattern: cpattern,
      width: self.width,
      height: self.height,
    }
  }
}
<|endoftext|>


<commit_before>use registry::{Enum, Registry, Cmd, Ns};
use syntax::ast;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;

mod ty;
pub mod global_gen;
pub mod static_gen;
pub mod struct_gen;

/// Trait for a bindings generator.
pub trait Generator {
    /// Builds the GL bindings.
    fn write(&self, &ExtCtxt, registry: &Registry, ns: Ns) -> Vec<P<ast::Item>>;
}

/// This function generates a `const name: type = value;` item.
fn gen_enum_item(ecx: &ExtCtxt, enm: &Enum, types_prefix: &str) -> P<ast::Item> {
    use syntax::ext::quote::rt::ExtParseUtils;

    // computing the name of the enum
    // if the original starts with a digit, adding an underscore prefix.
    let ident = if (enm.ident.as_slice().char_at(0)).is_digit() {
        format!("_{}", enm.ident)
    } else {
        enm.ident.clone()
    };

    // computing the type of the enum
    let ty = {
        // some enums have a value of the form `((Type)Value)` ; if this is the case, we need to
        //  replace the type of the enum (which is GLenum by default) by the type in the expression

        // matches `((a)b)`
        let regex = regex!(r"\(\((\w+)\).+\)");

        if (regex).is_match(enm.value.as_slice()) {
            // if the value is like `((Type)Value)`, then the type is `types::Type`
            regex.replace(enm.value.as_slice(), format!("{}$1", types_prefix).as_slice())

        } else if enm.value.as_slice().starts_with("\"") {
            // some values are of the form "Value" ; if this is the case, we use `&'static str`
            //  instead of `GLenum`
            "&'static str".to_string()

        } else {
            // some values are `TRUE` or `FALSE`, in which case we use `GLboolean` instead of
            //  `GLenum`
            match ident.as_slice() {
                "TRUE" | "FALSE" => format!("{}GLboolean", types_prefix),
                _ => match enm.ty {
                    Some(ref s) if s.as_slice() == "ull" => format!("{}GLuint64", types_prefix),
                    _ => format!("{}GLenum", types_prefix)
                }
            }
        }
    };

    // computing the value of the enum
    let value = {
        // similar to the type, some values are `((Type)Value)`
        // replacing "((Type)Value)" by "Value as types::Type"
        let regex = regex!(r"\(\((\w+)\)(.+)\)");
        regex.replace(enm.value.as_slice(), format!("$2 as {}$1", types_prefix).as_slice())
    };

    ecx.parse_item(format!("
        #[stable]
        #[allow(dead_code)]
        #[allow(non_upper_case_globals)]
        pub const {}: {} = {};"
    , ident, ty, value))
}

/// Generates all the type aliases for a namespace.
///
/// Aliases are either `pub type = ...` or `#[repr(C)] pub struct ... { ... }` and contain all the
///  things that we can't obtain from the XML files.
pub fn gen_type_aliases(ecx: &ExtCtxt, namespace: &Ns) -> Vec<P<ast::Item>> {
    let mut result = Vec::new();

    match *namespace {
        Ns::Gl | Ns::Gles1 | Ns::Gles2 => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
        }

        Ns::Glx => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_x_aliases(ecx).into_iter());
            result.extend(ty::build_glx_aliases(ecx).into_iter());
        }

        Ns::Wgl => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_win_aliases(ecx).into_iter());
            result.extend(ty::build_wgl_aliases(ecx).into_iter());
        }

        Ns::Egl => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_egl_aliases(ecx).into_iter());
        }
    }

    result
}

/// Generates the list of Rust `Arg`s that a `Cmd` requires.
pub fn gen_parameters(ecx: &ExtCtxt, cmd: &Cmd) -> Vec<ast::Arg> {
    use syntax::ext::build::AstBuilder;

    cmd.params.iter()
        .map(|binding| {
            // variable name of the binding
            let ident = match binding.ident.as_slice() {
                "in" => ecx.ident_of("in_"),
                "ref" => ecx.ident_of("ref_"),
                "type" => ecx.ident_of("type_"),
                ident => ecx.ident_of(ident),
            };

            // rust type of the binding
            let ty = ty::to_rust_ty(ecx, binding.ty.as_slice());

            // returning
            // TODO: don't use call_site()?
            ecx.arg(ecx.call_site(), ident, ty)
        })
        .collect()
}

/// Generates the Rust return type of a `Cmd`.
pub fn gen_return_type(ecx: &ExtCtxt, cmd: &Cmd) -> P<ast::Ty> {
    // turn the return type into a Rust type
    let ty = ty::to_rust_ty(ecx, cmd.proto.ty.as_slice());

    // ... but there is one more step: if the Rust type ends with `c_void`, we replace it with `()`
    match ty.node {
        ast::TyPath(ref path, _ ,_)
            if path.segments.last().unwrap().identifier.as_str() == "c_void"
                => return quote_ty!(ecx, ()),
        _ => ()
    };

    ty
}

/// Generates the native symbol name of a `Cmd`.
///
/// Example results: `"glClear"`, `"wglCreateContext"`, etc.
pub fn gen_symbol_name(ns: &Ns, cmd: &str) -> String {
    (match *ns {
        Ns::Gl | Ns::Gles1 | Ns::Gles2 => "gl",
        Ns::Glx => "glX",
        Ns::Wgl => "wgl",
        Ns::Egl => "egl",
    }).to_string() + cmd
}
<commit_msg>Update for rustc<commit_after>use registry::{Enum, Registry, Cmd, Ns};
use syntax::ast;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;

mod ty;
pub mod global_gen;
pub mod static_gen;
pub mod struct_gen;

/// Trait for a bindings generator.
pub trait Generator {
    /// Builds the GL bindings.
    fn write(&self, &ExtCtxt, registry: &Registry, ns: Ns) -> Vec<P<ast::Item>>;
}

/// This function generates a `const name: type = value;` item.
fn gen_enum_item(ecx: &ExtCtxt, enm: &Enum, types_prefix: &str) -> P<ast::Item> {
    use syntax::ext::quote::rt::ExtParseUtils;

    // computing the name of the enum
    // if the original starts with a digit, adding an underscore prefix.
    let ident = if (enm.ident.as_slice().char_at(0)).is_numeric() {
        format!("_{}", enm.ident)
    } else {
        enm.ident.clone()
    };

    // computing the type of the enum
    let ty = {
        // some enums have a value of the form `((Type)Value)` ; if this is the case, we need to
        //  replace the type of the enum (which is GLenum by default) by the type in the expression

        // matches `((a)b)`
        let regex = regex!(r"\(\((\w+)\).+\)");

        if (regex).is_match(enm.value.as_slice()) {
            // if the value is like `((Type)Value)`, then the type is `types::Type`
            regex.replace(enm.value.as_slice(), format!("{}$1", types_prefix).as_slice())

        } else if enm.value.as_slice().starts_with("\"") {
            // some values are of the form "Value" ; if this is the case, we use `&'static str`
            //  instead of `GLenum`
            "&'static str".to_string()

        } else {
            // some values are `TRUE` or `FALSE`, in which case we use `GLboolean` instead of
            //  `GLenum`
            match ident.as_slice() {
                "TRUE" | "FALSE" => format!("{}GLboolean", types_prefix),
                _ => match enm.ty {
                    Some(ref s) if s.as_slice() == "ull" => format!("{}GLuint64", types_prefix),
                    _ => format!("{}GLenum", types_prefix)
                }
            }
        }
    };

    // computing the value of the enum
    let value = {
        // similar to the type, some values are `((Type)Value)`
        // replacing "((Type)Value)" by "Value as types::Type"
        let regex = regex!(r"\(\((\w+)\)(.+)\)");
        regex.replace(enm.value.as_slice(), format!("$2 as {}$1", types_prefix).as_slice())
    };

    ecx.parse_item(format!("
        #[stable]
        #[allow(dead_code)]
        #[allow(non_upper_case_globals)]
        pub const {}: {} = {};"
    , ident, ty, value))
}

/// Generates all the type aliases for a namespace.
///
/// Aliases are either `pub type = ...` or `#[repr(C)] pub struct ... { ... }` and contain all the
///  things that we can't obtain from the XML files.
pub fn gen_type_aliases(ecx: &ExtCtxt, namespace: &Ns) -> Vec<P<ast::Item>> {
    let mut result = Vec::new();

    match *namespace {
        Ns::Gl | Ns::Gles1 | Ns::Gles2 => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
        }

        Ns::Glx => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_x_aliases(ecx).into_iter());
            result.extend(ty::build_glx_aliases(ecx).into_iter());
        }

        Ns::Wgl => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_win_aliases(ecx).into_iter());
            result.extend(ty::build_wgl_aliases(ecx).into_iter());
        }

        Ns::Egl => {
            result.extend(ty::build_gl_aliases(ecx).into_iter());
            result.extend(ty::build_egl_aliases(ecx).into_iter());
        }
    }

    result
}

/// Generates the list of Rust `Arg`s that a `Cmd` requires.
pub fn gen_parameters(ecx: &ExtCtxt, cmd: &Cmd) -> Vec<ast::Arg> {
    use syntax::ext::build::AstBuilder;

    cmd.params.iter()
        .map(|binding| {
            // variable name of the binding
            let ident = match binding.ident.as_slice() {
                "in" => ecx.ident_of("in_"),
                "ref" => ecx.ident_of("ref_"),
                "type" => ecx.ident_of("type_"),
                ident => ecx.ident_of(ident),
            };

            // rust type of the binding
            let ty = ty::to_rust_ty(ecx, binding.ty.as_slice());

            // returning
            // TODO: don't use call_site()?
            ecx.arg(ecx.call_site(), ident, ty)
        })
        .collect()
}

/// Generates the Rust return type of a `Cmd`.
pub fn gen_return_type(ecx: &ExtCtxt, cmd: &Cmd) -> P<ast::Ty> {
    // turn the return type into a Rust type
    let ty = ty::to_rust_ty(ecx, cmd.proto.ty.as_slice());

    // ... but there is one more step: if the Rust type ends with `c_void`, we replace it with `()`
    match ty.node {
        ast::TyPath(ref path, _ ,_)
            if path.segments.last().unwrap().identifier.as_str() == "c_void"
                => return quote_ty!(ecx, ()),
        _ => ()
    };

    ty
}

/// Generates the native symbol name of a `Cmd`.
///
/// Example results: `"glClear"`, `"wglCreateContext"`, etc.
pub fn gen_symbol_name(ns: &Ns, cmd: &str) -> String {
    (match *ns {
        Ns::Gl | Ns::Gles1 | Ns::Gles2 => "gl",
        Ns::Glx => "glX",
        Ns::Wgl => "wgl",
        Ns::Egl => "egl",
    }).to_string() + cmd
}
<|endoftext|>


<commit_before>extern crate file;
extern crate tempdir;
extern crate difference;

use std::process;
use std::env;
use std::path::{PathBuf, Path};

use tempdir::TempDir;

fn generator_path() -> PathBuf {
    let test_exe = env::current_exe().unwrap();
    test_exe.parent().unwrap().parent().unwrap().join("gen")
}

fn check_by_path<T: AsRef<Path>>(grammar: T) {
    let grammar = grammar.as_ref();
    let input = file::get_text(grammar).unwrap();
    let expected = file::get_text(grammar.with_extension("rs")).unwrap();
    do_test(&input, &expected);
}

fn do_test(grammar: &str, expected: &str) {
    let dir = TempDir::new("gen-tests").unwrap();
    let grammar_path = dir.path().join("weird.fall");
    file::put_text(&grammar_path, grammar).unwrap();

    let output = process::Command::new(generator_path())
        .arg(&grammar_path)
        .output()
        .expect("Failed to execute process");

    if !output.status.success() {
        panic!("Generator exited with code {:?}\n----\n{}\n----\n",
               output.status.code(), std::str::from_utf8(&output.stderr).unwrap())
    }

    let actual = file::get_text(grammar_path.with_extension("rs")).unwrap();

    let expected = expected.trim();
    let actual = actual.trim();
    if expected != actual {
        let difference = difference::Changeset::new(expected, actual, "\n");
        println!("{}", difference);
        panic!("Mismatch!")
    }
}

#[test]
fn test_grammars_are_fresh() {
    check_by_path("../fall_test/src/sexp.fall");
    check_by_path("../fall_test/src/rust.fall");
    check_by_path("../fall_test/src/weird.fall");
    check_by_path("../fall_test/src/json.fall");
    check_by_path("./src/syntax.fall");
}
<commit_msg>Better test reporting<commit_after>extern crate file;
extern crate tempdir;
extern crate difference;

use std::process;
use std::env;
use std::path::{PathBuf, Path};

use tempdir::TempDir;

fn generator_path() -> PathBuf {
    let test_exe = env::current_exe().unwrap();
    test_exe.parent().unwrap().parent().unwrap().join("gen")
}

fn check_by_path<T: AsRef<Path>>(grammar: T) {
    let grammar = grammar.as_ref();
    let file_name = grammar.display().to_string();
    let input = file::get_text(grammar).unwrap();
    let expected = file::get_text(grammar.with_extension("rs")).unwrap();
    do_test(&input, &expected, &file_name);
}

fn do_test(grammar: &str, expected: &str, file_name: &str) {
    let dir = TempDir::new("gen-tests").unwrap();
    let grammar_path = dir.path().join("weird.fall");
    file::put_text(&grammar_path, grammar).unwrap();

    let output = process::Command::new(generator_path())
        .arg(&grammar_path)
        .output()
        .expect("Failed to execute process");

    if !output.status.success() {
        panic!("Generator exited with code {:?}\n----\n{}\n----\n",
               output.status.code(), std::str::from_utf8(&output.stderr).unwrap())
    }

    let actual = file::get_text(grammar_path.with_extension("rs")).unwrap();

    let expected = expected.trim();
    let actual = actual.trim();
    if expected != actual {
        let difference = difference::Changeset::new(expected, actual, "\n");
        println!("{}\n{}", file_name, difference);
        panic!("Mismatch!")
    }
}

#[test]
fn test_grammars_are_fresh() {
    check_by_path("../fall_test/src/sexp.fall");
    check_by_path("../fall_test/src/rust.fall");
    check_by_path("../fall_test/src/weird.fall");
    check_by_path("../fall_test/src/json.fall");
    check_by_path("./src/syntax.fall");
}
<|endoftext|>


<commit_before><commit_msg>FIx link to license file<commit_after><|endoftext|>


<commit_before>
pub fn puzzle(input: &str) -> usize {
    0
}

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

        // br.exec_command("value 5 goes to bot 2");
        // br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        // br.exec_command("value 3 goes to bot 1");
        // br.exec_command("bot 1 gives low to output 1 and high to bot 0");
        // br.exec_command("bot 0 gives low to output 2 and high to output 0");
        // br.exec_command("value 2 goes to bot 2");
}
<commit_msg>Start restructuring somewhat differently<commit_after>use std::collections::HashMap;

pub fn puzzle(input: &str) -> usize {
    0
}

pub enum BotOrOutput {
    Bot,
    Output
}

pub struct Command {
    low_value_type: BotOrOutput,
    low_value_key: usize,
    high_value_type: BotOrOutput,
    high_value_key: usize,
}

pub struct BotCommandCenter {
    bots: HashMap<usize, Bot>,
    outputs: HashMap<usize, Vec<usize>>,
    saved_commands: HashMap<usize, Command>,
}

pub struct Bot {
    key: usize,
    chip1: Option<usize>,
    chip2: Option<usize>,
}

impl Bot {
    pub fn new(key: usize) -> Bot {
        Bot {
            key: key,
            chip1: None, chip2: None,
        }
    }

    pub fn has_two_chips(&self) -> bool {
        match (self.chip1, self.chip2) {
            (Some(_), Some(_)) => true,
            _ => false,
        }
    }

    pub fn receive_chip(&mut self, chip: usize) {
        if self.chip1.is_none() {
            println!("bot {}, chip1 = {}", self.key, chip);
            self.chip1 = Some(chip);
        } else if self.chip2.is_none() {
            println!("bot {}, chip2 = {}", self.key, chip);
            self.chip2 = Some(chip);
        } else {
            panic!("Cannot hold more than two chips");
        }
    }
}

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

    #[test]
    fn new_bot_does_not_have_two_chips() {
        let bot = Bot::new(0);
        assert!( ! bot.has_two_chips() );
    }

    #[test]
    fn bot_gets_a_chip_still_not_two() {
        let mut bot = Bot::new(0);
        bot.receive_chip(1);
        assert!( ! bot.has_two_chips() );
    }

    #[test]
    fn bot_gets_two_chips() {
        let mut bot = Bot::new(0);
        bot.receive_chip(1);
        bot.receive_chip(4);
        assert!(bot.has_two_chips());
    }
        // br.exec_command("value 5 goes to bot 2");
        // br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        // br.exec_command("value 3 goes to bot 1");
        // br.exec_command("bot 1 gives low to output 1 and high to bot 0");
        // br.exec_command("bot 0 gives low to output 2 and high to output 0");
        // br.exec_command("value 2 goes to bot 2");
}
<|endoftext|>


<commit_before><commit_msg>Add additional tests<commit_after><|endoftext|>


<commit_before><commit_msg>binding: Implement params and basic encoder open/close<commit_after><|endoftext|>


<commit_before><commit_msg>macro syntax changes<commit_after><|endoftext|>


<commit_before><commit_msg>Do not deny all warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Fix colorspace doc string<commit_after><|endoftext|>


<commit_before><commit_msg>Add Citeproc option<commit_after><|endoftext|>


<commit_before><commit_msg>Implement Pattern and Searcher for substring searches<commit_after><|endoftext|>


<commit_before><commit_msg>doc: Document parentheses as an operator in expression reference<commit_after><|endoftext|>


<commit_before><commit_msg>Remove license attribute.<commit_after><|endoftext|>


<commit_before><commit_msg>Add `level` method<commit_after><|endoftext|>


<commit_before><commit_msg>Add SortedUniqueVec#push() method.<commit_after><|endoftext|>


<commit_before>// Copyright 2015 Till Höppner
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io::{ BufRead, Write };
use std::borrow::{ ToOwned, Cow, IntoCow };
use std::iter::{ Iterator };
use std::marker::PhantomData;

use event::{ Event, Type, Time };
use context::Context;
use format::{ Encode, Decode, rejoin, strip_one };

use l::LogLevel::Info;

use chrono::*;

pub struct Weechat3;

static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";

pub struct Iter<'a, R: 'a> where R: BufRead {
    context: &'a Context,
    input: R,
    buffer: String
}

impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead {
    type Item = ::Result<Event<'static>>;
    fn next(&mut self) -> Option<::Result<Event<'static>>> {
        fn parse_time(c: &Context, date: &str, time: &str) -> Time {
            Time::from_format(&c.timezone, &format!("{} {}", date, time), TIME_DATE_FORMAT)
        }

        loop {
            let mut buffer = String::new();
            match self.input.read_line(&mut buffer) {
                Ok(0) | Err(_) => return None,
                Ok(_) => ()
            }

            let mut split_tokens: Vec<char> = Vec::new();
            let tokens = buffer.split(|c: char| {
                if c.is_whitespace() { split_tokens.push(c); true } else { false }
            }).collect::<Vec<_>>();

            /*if log_enabled!(Info) {
                info!("Original:  `{}`", self.buffer);
                info!("Parsing:   {:?}", tokens);
            }*/

            match &tokens[..tokens.len() - 1] {
                /*[date, time, "-->", nick, host, "has", "joined", channel, _..]
                => return Some(Ok(Event {
                    ty: Type::Join {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        time: timestamp(date, time)
                    },
                    channel: Some(channel.into_cow()),
                })),
                [date, time, "<--", nick, host, "has", "left", channel, reason..]
                => return Some(Ok(Event {
                    ty: Type::Part {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        reason: Some(strip_one(&rejoin(reason, &split_tokens[8..]))),
                    },
                    channel: Some(channel.to_owned()),
                    time: timestamp(date, time)
                })),
                [date, time, "<--", nick, host, "has", "quit", reason..]
                => return Some(Ok(Event {
                    ty: Type::Quit {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        reason: Some(strip_one(&rejoin(reason, &split_tokens[7..]))),
                    }
                })),
                [date, time, "--", notice, content..]
                    if notice.starts_with("Notice(")
                => return Some(Ok(Event {
                    ty: Type::Notice {
                        nick: notice["Notice(".len()..notice.len() - 2].to_owned(),
                        content: rejoin(content, &split_tokens[4..]),
                        time: timestamp(date, time)
                    }
                })),
                [date, time, "--", "irc:", "disconnected", "from", "server", _..]
                => return Some(Ok(Event {
                        ty: Type::Disconnect {
                        time: timestamp(date, time)
                    }
                })),
                [date, time, "--", nick, verb, "now", "known", "as", new_nick]
                    if verb == "is" || verb == "are"
                => return Some(Ok(Event {
                    ty: Type::Nick {
                    old: nick.to_owned(), new: new_nick.to_owned(), time: timestamp(date, time)
                    }
                })),*/
                [date, time, sp, "*", nick, msg..]
                    if sp.clone().is_empty()
                => return Some(Ok(Event {
                    ty: Type::Action {
                        from: nick.clone().into_cow(),
                        content: rejoin(msg, &split_tokens[5..]),
                    },
                    time: parse_time(&self.context, &date.clone().to_owned(), &time.clone().to_owned()),
                    channel: None
                })),
                /*[date, time, nick, msg..]
                => return Some(Ok(Event {
                    ty: Type::Msg {
                        from: nick.into(),
                        content: rejoin(msg, &split_tokens[3..]),
                    },
                    time: parse_time(&self.context, &date, &time),
                    channel: None
                })),*/
                _ => ()
            }
        }
    }
}

impl<'a, R: 'a> Decode<'static, R, Iter<'a, R>> for Weechat3 where R: BufRead {
    fn decode(&'a mut self, context: &'a Context, input: R) -> Iter<R> {
        Iter {
            context: context,
            input: input,
            buffer: String::new()
        }
    }
}

impl<'a, W> Encode<'a, W> for Weechat3 where W: Write {
    fn encode(&'a self, context: &'a Context, mut output: W, event: &'a Event) -> ::Result<()> {
        fn date(t: i64) -> String {
            format!("{}", UTC.timestamp(t, 0).format(TIME_DATE_FORMAT))
        }
        match event {
            &Event { ty: Type::Msg { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output, "{}\t{}\t{}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT), from, content))
            },
            &Event { ty: Type::Action { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output, "{}\t *\t{} {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT), from, content))
            },
            /*&Event::Join { ref nick, ref mask, ref channel, ref time } => {
                try!(writeln!(&mut output, "{}\t-->\t{} ({}) has joined {}",
                date(*time), nick, mask, channel))
            },
            &Event::Part { ref nick, ref mask, ref channel, ref time, ref reason } => {
                try!(write!(&mut output, "{}\t<--\t{} ({}) has left {}",
                date(*time), nick, mask, channel));
                if reason.len() > 0 {
                    try!(write!(&mut output, " ({})", reason));
                }
                try!(write!(&mut output, "\n"))
            },
            &Event::Quit { ref nick, ref mask, ref time, ref reason } => {
                try!(write!(&mut output, "{}\t<--\t{} ({}) has quit", date(*time), nick, mask));
                if reason.len() > 0 {
                    try!(write!(&mut output, " ({})", reason));
                }
                try!(write!(&mut output, "\n"))
            },
            &Event::Disconnect { ref time } => {
                try!(writeln!(&mut output, "{}\t--\tirc: disconnected from server", date(*time)))
            },
            &Event::Notice { ref nick, ref content, ref time } => {
                try!(writeln!(&mut output, "{}\t--\tNotice({}): {}", date(*time), nick, content))
            },*/
            _ => ()
        }
        Ok(())
    }
}
<commit_msg>Figure out that .to_owned().into() is needed, instead of .into()<commit_after>// Copyright 2015 Till Höppner
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::io::{ BufRead, Write };
use std::borrow::{ ToOwned, Cow, IntoCow };
use std::iter::{ Iterator };
use std::marker::PhantomData;

use event::{ Event, Type, Time };
use context::Context;
use format::{ Encode, Decode, rejoin, strip_one };

use l::LogLevel::Info;

use chrono::*;

pub struct Weechat3;

static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";

pub struct Iter<'a, R: 'a> where R: BufRead {
    context: &'a Context,
    input: R,
    buffer: String
}

impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead {
    type Item = ::Result<Event<'static>>;
    fn next(&mut self) -> Option<::Result<Event<'static>>> {
        fn parse_time(c: &Context, date: &str, time: &str) -> Time {
            Time::from_format(&c.timezone, &format!("{} {}", date, time), TIME_DATE_FORMAT)
        }

        loop {
            let mut buffer = String::new();
            match self.input.read_line(&mut buffer) {
                Ok(0) | Err(_) => return None,
                Ok(_) => ()
            }

            let mut split_tokens: Vec<char> = Vec::new();
            let tokens = buffer.split(|c: char| {
                if c.is_whitespace() { split_tokens.push(c); true } else { false }
            }).collect::<Vec<_>>();

            /*if log_enabled!(Info) {
                info!("Original:  `{}`", self.buffer);
                info!("Parsing:   {:?}", tokens);
            }*/

            match &tokens[..tokens.len() - 1] {
                /*[date, time, "-->", nick, host, "has", "joined", channel, _..]
                => return Some(Ok(Event {
                    ty: Type::Join {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        time: timestamp(date, time)
                    },
                    channel: Some(channel.into_cow()),
                })),
                [date, time, "<--", nick, host, "has", "left", channel, reason..]
                => return Some(Ok(Event {
                    ty: Type::Part {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        reason: Some(strip_one(&rejoin(reason, &split_tokens[8..]))),
                    },
                    channel: Some(channel.to_owned()),
                    time: timestamp(date, time)
                })),
                [date, time, "<--", nick, host, "has", "quit", reason..]
                => return Some(Ok(Event {
                    ty: Type::Quit {
                        nick: nick.to_owned(),
                        mask: Some(strip_one(host)),
                        reason: Some(strip_one(&rejoin(reason, &split_tokens[7..]))),
                    }
                })),
                [date, time, "--", notice, content..]
                    if notice.starts_with("Notice(")
                => return Some(Ok(Event {
                    ty: Type::Notice {
                        nick: notice["Notice(".len()..notice.len() - 2].to_owned(),
                        content: rejoin(content, &split_tokens[4..]),
                        time: timestamp(date, time)
                    }
                })),
                [date, time, "--", "irc:", "disconnected", "from", "server", _..]
                => return Some(Ok(Event {
                        ty: Type::Disconnect {
                        time: timestamp(date, time)
                    }
                })),
                [date, time, "--", nick, verb, "now", "known", "as", new_nick]
                    if verb == "is" || verb == "are"
                => return Some(Ok(Event {
                    ty: Type::Nick {
                    old: nick.to_owned(), new: new_nick.to_owned(), time: timestamp(date, time)
                    }
                })),*/
                [date, time, sp, "*", nick, msg..]
                    if sp.clone().is_empty()
                => return Some(Ok(Event {
                    ty: Type::Action {
                        from: nick.to_owned().into(),
                        content: rejoin(msg, &split_tokens[5..]),
                    },
                    time: parse_time(&self.context, &date.clone().to_owned(), &time.clone().to_owned()),
                    channel: None
                })),
                [date, time, nick, msg..]
                => return Some(Ok(Event {
                    ty: Type::Msg {
                        from: nick.to_owned().into(),
                        content: rejoin(msg, &split_tokens[3..]),
                    },
                    time: parse_time(&self.context, &date, &time),
                    channel: None
                })),
                _ => ()
            }
        }
    }
}

impl<'a, R: 'a> Decode<'static, R, Iter<'a, R>> for Weechat3 where R: BufRead {
    fn decode(&'a mut self, context: &'a Context, input: R) -> Iter<R> {
        Iter {
            context: context,
            input: input,
            buffer: String::new()
        }
    }
}

impl<'a, W> Encode<'a, W> for Weechat3 where W: Write {
    fn encode(&'a self, context: &'a Context, mut output: W, event: &'a Event) -> ::Result<()> {
        fn date(t: i64) -> String {
            format!("{}", UTC.timestamp(t, 0).format(TIME_DATE_FORMAT))
        }
        match event {
            &Event { ty: Type::Msg { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output, "{}\t{}\t{}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT), from, content))
            },
            &Event { ty: Type::Action { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output, "{}\t *\t{} {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT), from, content))
            },
            /*&Event::Join { ref nick, ref mask, ref channel, ref time } => {
                try!(writeln!(&mut output, "{}\t-->\t{} ({}) has joined {}",
                date(*time), nick, mask, channel))
            },
            &Event::Part { ref nick, ref mask, ref channel, ref time, ref reason } => {
                try!(write!(&mut output, "{}\t<--\t{} ({}) has left {}",
                date(*time), nick, mask, channel));
                if reason.len() > 0 {
                    try!(write!(&mut output, " ({})", reason));
                }
                try!(write!(&mut output, "\n"))
            },
            &Event::Quit { ref nick, ref mask, ref time, ref reason } => {
                try!(write!(&mut output, "{}\t<--\t{} ({}) has quit", date(*time), nick, mask));
                if reason.len() > 0 {
                    try!(write!(&mut output, " ({})", reason));
                }
                try!(write!(&mut output, "\n"))
            },
            &Event::Disconnect { ref time } => {
                try!(writeln!(&mut output, "{}\t--\tirc: disconnected from server", date(*time)))
            },
            &Event::Notice { ref nick, ref content, ref time } => {
                try!(writeln!(&mut output, "{}\t--\tNotice({}): {}", date(*time), nick, content))
            },*/
            _ => ()
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::iter::FromIterator;
use std::slice::Iter;
use rand::ThreadRng;

use super::Span;
use super::dimensions;
use super::dimensions::{Dimension, Partitioned};

pub trait Space {
    type Repr;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr;

    fn dim(&self) -> usize;
    fn span(&self) -> Span;
}

pub type ActionSpace = UnitarySpace<dimensions::Discrete>;

pub struct UnitarySpace<D: Dimension>(D);

impl<D: Dimension> UnitarySpace<D> {
    pub fn new(d: D) -> Self {
        UnitarySpace(d)
    }
}

impl<D: Dimension> Space for UnitarySpace<D> {
    type Repr = D::Value;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        self.0.sample(rng)
    }

    fn dim(&self) -> usize {
        1
    }

    fn span(&self) -> Span {
        self.0.span()
    }
}

pub struct RegularSpace<D: Dimension> {
    dimensions: Vec<D>,
    span: Span,
}

impl<D: Dimension> RegularSpace<D> {
    pub fn new() -> Self {
        RegularSpace {
            dimensions: vec![],
            span: Span::Null,
        }
    }

    pub fn push(mut self, d: D) -> Self {
        self.span = self.span * d.span();
        self.dimensions.push(d);
        self
    }

    pub fn iter(&self) -> Iter<D> {
        self.dimensions.iter()
    }
}

impl<D: Dimension> Space for RegularSpace<D> {
    type Repr = Vec<D::Value>;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        self.dimensions.iter().map(|d| d.sample(rng)).collect()
    }

    fn dim(&self) -> usize {
        self.dimensions.len()
    }

    fn span(&self) -> Span {
        self.span
    }
}

impl RegularSpace<dimensions::Continuous> {
    pub fn partitioned(self, density: usize) -> RegularSpace<Partitioned> {
        self.into_iter()
            .map(|d| Partitioned::from_continuous(d, density))
            .collect()
    }
}

impl RegularSpace<dimensions::Partitioned> {
    pub fn centres(&self) -> Vec<Vec<f64>> {
        self.dimensions.iter()
            .map(|d| d.centres())
            .collect()
    }
}

impl<D: Dimension> FromIterator<D> for RegularSpace<D> {
    fn from_iter<I: IntoIterator<Item = D>>(iter: I) -> Self {
        let mut s = Self::new();

        for i in iter {
            s = s.push(i);
        }

        s
    }
}

impl<D: Dimension> IntoIterator for RegularSpace<D> {
    type Item = D;
    type IntoIter = ::std::vec::IntoIter<D>;

    fn into_iter(self) -> Self::IntoIter {
        self.dimensions.into_iter()
    }
}

// TODO: Bring back support for Null/Pair spaces.
// pub struct NullSpace(dimensions::Null);

// impl Space for NullSpace {
// type Repr = ();

// fn dim(&self) -> usize {
// 0
// }

// fn span(&self) -> Span {
// Span::Null
// }
// }

pub struct PairSpace<D1, D2>((D1, D2))
    where D1: Dimension,
          D2: Dimension;

impl<D1: Dimension, D2: Dimension> PairSpace<D1, D2> {
    pub fn new(d1: D1, d2: D2) -> Self {
        PairSpace((d1, d2))
    }
}

impl<D1: Dimension, D2: Dimension> Space for PairSpace<D1, D2> {
    type Repr = (D1::Value, D2::Value);

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        ((self.0).0.sample(rng), (self.0).1.sample(rng))
    }

    fn dim(&self) -> usize {
        2
    }

    fn span(&self) -> Span {
        (self.0).0.span() * (self.0).1.span()
    }
}

impl PairSpace<dimensions::Continuous, dimensions::Continuous> {
    pub fn partitioned(self, density: usize) -> PairSpace<Partitioned, Partitioned> {
        PairSpace((Partitioned::from_continuous((self.0).0, density),
                   Partitioned::from_continuous((self.0).1, density)))
    }
}

// pub struct MultiSpace<D: Dimension> {
// dimensions: Vec<D>,
// span: Span
// }

// impl<D: Dimension> MultiSpace<D> {
// pub fn new() -> Self {
// MultiSpace {
// dimensions: vec![],
// span: Span::Null
// }
// }

// pub fn push(mut self, d: D) -> Self {
// self.span = self.span * d.span();
// self.dimensions.push(d);
// self
// }

// pub fn iter(&self) -> Iter<D> {
// self.dimensions.iter()
// }
// }

// impl<D: Dimension> Space for MultiSpace<D> {
// type Repr = Vec<D::Value>;

// fn dim(&self) -> usize {
// self.dimensions.len()
// }

// fn span(&self) -> Span {
// self.span
// }
// }

// impl MultiSpace<dimensions::Continuous> {
// pub fn with_partitions(self, density: usize) -> MultiSpace<Partitioned> {
// self.into_iter().map(
// |d| Partitioned::from_continuous(d, density)).collect()
// }
// }
<commit_msg>Re-added NullSpace and began tests for spaces<commit_after>use std::iter::FromIterator;
use std::slice::Iter;
use rand::ThreadRng;

use super::Span;
use super::dimensions;
use super::dimensions::{Dimension, Partitioned};

pub trait Space {
    type Repr;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr;

    fn dim(&self) -> usize;
    fn span(&self) -> Span;
}

pub type ActionSpace = UnitarySpace<dimensions::Discrete>;

pub struct NullSpace;

impl Space for NullSpace {
    type Repr = ();

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        ()
    }

    fn dim(&self) -> usize {
        0
    }

    fn span(&self) -> Span {
        Span::Null
    }
}

pub struct UnitarySpace<D: Dimension>(D);

impl<D: Dimension> UnitarySpace<D> {
    pub fn new(d: D) -> Self {
        UnitarySpace(d)
    }
}

impl<D: Dimension> Space for UnitarySpace<D> {
    type Repr = D::Value;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        self.0.sample(rng)
    }

    fn dim(&self) -> usize {
        1
    }

    fn span(&self) -> Span {
        self.0.span()
    }
}

pub struct PairSpace<D1, D2>((D1, D2))
    where D1: Dimension,
          D2: Dimension;

impl<D1: Dimension, D2: Dimension> PairSpace<D1, D2> {
    pub fn new(d1: D1, d2: D2) -> Self {
        PairSpace((d1, d2))
    }
}

impl<D1: Dimension, D2: Dimension> Space for PairSpace<D1, D2> {
    type Repr = (D1::Value, D2::Value);

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        ((self.0).0.sample(rng), (self.0).1.sample(rng))
    }

    fn dim(&self) -> usize {
        2
    }

    fn span(&self) -> Span {
        (self.0).0.span() * (self.0).1.span()
    }
}

impl PairSpace<dimensions::Continuous, dimensions::Continuous> {
    pub fn partitioned(self, density: usize) -> PairSpace<Partitioned, Partitioned> {
        PairSpace((Partitioned::from_continuous((self.0).0, density),
                   Partitioned::from_continuous((self.0).1, density)))
    }
}

pub struct RegularSpace<D: Dimension> {
    dimensions: Vec<D>,
    span: Span,
}

impl<D: Dimension> RegularSpace<D> {
    pub fn new() -> Self {
        RegularSpace {
            dimensions: vec![],
            span: Span::Null,
        }
    }

    pub fn push(mut self, d: D) -> Self {
        self.span = self.span * d.span();
        self.dimensions.push(d);
        self
    }

    pub fn iter(&self) -> Iter<D> {
        self.dimensions.iter()
    }
}

impl<D: Dimension> Space for RegularSpace<D> {
    type Repr = Vec<D::Value>;

    fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        self.dimensions.iter().map(|d| d.sample(rng)).collect()
    }

    fn dim(&self) -> usize {
        self.dimensions.len()
    }

    fn span(&self) -> Span {
        self.span
    }
}

impl RegularSpace<dimensions::Continuous> {
    pub fn partitioned(self, density: usize) -> RegularSpace<Partitioned> {
        self.into_iter()
            .map(|d| Partitioned::from_continuous(d, density))
            .collect()
    }
}

impl RegularSpace<dimensions::Partitioned> {
    pub fn centres(&self) -> Vec<Vec<f64>> {
        self.dimensions.iter()
            .map(|d| d.centres())
            .collect()
    }
}

impl<D: Dimension> FromIterator<D> for RegularSpace<D> {
    fn from_iter<I: IntoIterator<Item = D>>(iter: I) -> Self {
        let mut s = Self::new();

        for i in iter {
            s = s.push(i);
        }

        s
    }
}

impl<D: Dimension> IntoIterator for RegularSpace<D> {
    type Item = D;
    type IntoIter = ::std::vec::IntoIter<D>;

    fn into_iter(self) -> Self::IntoIter {
        self.dimensions.into_iter()
    }
}

// pub struct HeterogeneousSpace {
    // dimensions: Vec<Dimension>,
    // span: Span
// }

// impl HeterogeneousSpace {
    // pub fn new() -> Self {
     // HeterogeneousSpace {
            // dimensions: vec![],
            // span: Span::Null
        // }
    // }

    // pub fn push(mut self, d: D) -> Self {
        // self.span = self.span * d.span();
        // self.dimensions.push(d);
        // self
    // }

    // pub fn iter(&self) -> Iter<Dimension> {
        // self.dimensions.iter()
    // }
// }

// impl<D: Dimension> Space for HeterogeneousSpace<D> {
    // type Repr = Vec<D::Value>;

    // fn sample(&self, rng: &mut ThreadRng) -> Self::Repr {
        // self.dimensions.iter().map(|d| d.sample(rng)).collect()
    // }

    // fn dim(&self) -> usize {
        // self.dimensions.len()
    // }

    // fn span(&self) -> Span {
        // self.span
    // }
// }

    // fn sample(&self, rng: &mut ThreadRng) -> Self::Repr;

    // fn dim(&self) -> usize;
    // fn span(&self) -> Span;

#[cfg(test)]
mod tests {
    use super::{Space, NullSpace, UnitarySpace, PairSpace, RegularSpace};

    use rand::thread_rng;
    use geometry::Span;
    use geometry::dimensions::*;

    #[test]
    fn test_null_space() {
        let ns = NullSpace;
        let mut rng = thread_rng();

        assert_eq!(ns.sample(&mut rng), ());
        assert_eq!(ns.dim(), 0);
        assert_eq!(ns.span(), Span::Null);
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Handle_a_signal
//
// Note that this solution only works on Unix.

extern crate libc;
extern crate time;

#[cfg(all(unix, not(test)))]
fn main()
{
    use libc::consts::os::posix88::SIGINT;
    use libc::funcs::posix01::signal;
    use std::io::timer::Timer;
    use std::mem;
    use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL};
    use std::sync::atomics;
    use std::time::duration::Duration;

    // The time between ticks of our counter.
    let duration = Duration::seconds(1) / 2;
    let mut timer = Timer::new().unwrap();
    // "SIGINT received" global variable.
    static mut GOT_SIGINT: AtomicBool = INIT_ATOMIC_BOOL;
    unsafe {
        // Initially, "SIGINT received" is false.
        GOT_SIGINT.store(false, atomics::Release);
        // Interrupt handler that handles the SIGINT signal
        unsafe fn handle_sigint() {
            // It is dangerous to perform any system calls in interrupts, so just set the atomic
            // "SIGINT received" global to true when it arrives.
            GOT_SIGINT.store(true, atomics::Release);
        }
        // Make handle_sigint the signal handler for SIGINT.
        signal::signal(SIGINT, mem::transmute(handle_sigint));
    }
    let periodic = timer.periodic(duration);
    // Get the start time...
    let start = time::precise_time_ns();
    // Integer counter
    let mut i = 0u32;
    // Every `duration`...
    for _ in periodic.iter() {
        // Break if SIGINT was handled
        if unsafe { GOT_SIGINT.load(atomics::Acquire) } { break }
        // Otherwise, increment and display the integer and continue the loop.
        i += 1;
        println!("{}", i);
    }
    // Get the end time.
    let end = time::precise_time_ns();
    // Compute the difference
    let diff = Duration::nanoseconds((end - start) as i64);
    // Print the difference and exit
    println!("Program has run for {} seconds", diff);
}

#[cfg(not(unix))]
fn main()
{
    println!("Not supported on this platform");
}
<commit_msg>renaming atomics -> atomic<commit_after>// Implements http://rosettacode.org/wiki/Handle_a_signal
//
// Note that this solution only works on Unix.

extern crate libc;
extern crate time;

#[cfg(all(unix, not(test)))]
fn main()
{
    use libc::consts::os::posix88::SIGINT;
    use libc::funcs::posix01::signal;
    use std::io::timer::Timer;
    use std::mem;
    use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL};
    use std::sync::atomic;
    use std::time::duration::Duration;

    // The time between ticks of our counter.
    let duration = Duration::seconds(1) / 2;
    let mut timer = Timer::new().unwrap();
    // "SIGINT received" global variable.
    static mut GOT_SIGINT: AtomicBool = INIT_ATOMIC_BOOL;
    unsafe {
        // Initially, "SIGINT received" is false.
        GOT_SIGINT.store(false, atomic::Release);
        // Interrupt handler that handles the SIGINT signal
        unsafe fn handle_sigint() {
            // It is dangerous to perform any system calls in interrupts, so just set the atomic
            // "SIGINT received" global to true when it arrives.
            GOT_SIGINT.store(true, atomic::Release);
        }
        // Make handle_sigint the signal handler for SIGINT.
        signal::signal(SIGINT, mem::transmute(handle_sigint));
    }
    let periodic = timer.periodic(duration);
    // Get the start time...
    let start = time::precise_time_ns();
    // Integer counter
    let mut i = 0u32;
    // Every `duration`...
    for _ in periodic.iter() {
        // Break if SIGINT was handled
        if unsafe { GOT_SIGINT.load(atomic::Acquire) } { break }
        // Otherwise, increment and display the integer and continue the loop.
        i += 1;
        println!("{}", i);
    }
    // Get the end time.
    let end = time::precise_time_ns();
    // Compute the difference
    let diff = Duration::nanoseconds((end - start) as i64);
    // Print the difference and exit
    println!("Program has run for {} seconds", diff);
}

#[cfg(not(unix))]
fn main()
{
    println!("Not supported on this platform");
}
<|endoftext|>


<commit_before><commit_msg>Add probing function for NTP<commit_after><|endoftext|>


<commit_before><commit_msg>Check header of file before loading it in memory<commit_after><|endoftext|>


<commit_before><commit_msg>Fix ray/AABB benchmarks<commit_after><|endoftext|>


<commit_before>//! Defines the Path integrator which implements path tracing with
//! explicit light sampling

use std::vec::Vec;
use std::iter;
use std::num::Float;
use rand::{Rng, StdRng};

use scene::Scene;
use linalg;
use linalg::Ray;
use geometry::Intersection;
use film::Colorf;
use integrator::Integrator;
use bxdf::BxDFType;
use sampler::{Sampler, Sample};

/// The path integrator implementing Path tracing with explicit light sampling
/// See [Kajiya, The Rendering Equation](http://dl.acm.org/citation.cfm?id=15902)
#[derive(Copy, Debug)]
pub struct Path {
    min_depth: usize,
    max_depth: usize,
}

impl Path {
    /// Create a new path integrator with the min and max length desired for paths
    pub fn new(min_depth: u32, max_depth: u32) -> Path {
        Path { min_depth: min_depth as usize, max_depth: max_depth as usize }
    }
}

impl Integrator for Path {
    fn illumination(&self, scene: &Scene, r: &Ray, hit: &Intersection, sampler: &mut Sampler,
                    rng: &mut StdRng) -> Colorf {
        // TODO: We really need the memory pool now
        let mut l_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut l_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        let mut bsdf_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut bsdf_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        let mut path_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut path_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        sampler.get_samples_2d(&mut l_samples[], rng);
        sampler.get_samples_2d(&mut bsdf_samples[], rng);
        sampler.get_samples_2d(&mut path_samples[], rng);
        sampler.get_samples_1d(&mut l_samples_comp[], rng);
        sampler.get_samples_1d(&mut bsdf_samples_comp[], rng);
        sampler.get_samples_1d(&mut path_samples_comp[], rng);

        let mut illum = Colorf::black();
        let mut path_throughput = Colorf::broadcast(1.0);
        // Track if the previous bounce was a specular one
        let mut specular_bounce = false;
        let mut current_hit = *hit;
        let mut ray = *r;
        let mut bounce = 0us;
        loop {
            // TODO: Sample emissive objects on first bounce and specular bounces
            // when emissive objects are added
            /*
            if bounce == 0 || specular_bounce {
            }
            */
            let bsdf = current_hit.instance.material.bsdf(&current_hit);
            let w_o = -ray.d;
            let light_sample = Sample::new(&l_samples[bounce], l_samples_comp[bounce]);
            let bsdf_sample = Sample::new(&bsdf_samples[bounce], bsdf_samples_comp[bounce]);
            let li = self.sample_one_light(scene, &w_o, &bsdf, &light_sample, &bsdf_sample);
            illum = illum + path_throughput * li;

            // Determine the next direction to take the path by sampling the BSDF
            let path_sample = Sample::new(&path_samples[bounce], path_samples_comp[bounce]);
            let (f, w_i, pdf, sampled_type) = bsdf.sample(&w_o, BxDFType::all(), &path_sample);
            if f.is_black() || pdf == 0.0 {
                break;
            }
            specular_bounce = sampled_type.contains(&BxDFType::Specular);
            path_throughput = path_throughput * f * Float::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;

            // Check if we're beyond the min depth at which point we start trying to
            // terminate rays using Russian Roulette
            if bounce > self.min_depth {
                let cont_prob = Float::min(0.5, path_throughput.luminance());
                if rng.next_f32() > cont_prob {
                    break;
                }
                // Re-weight the sum terms accordingly with the Russian roulette weight
                path_throughput = path_throughput / cont_prob;
            }
            if bounce == self.max_depth {
                break;
            }

            ray = ray.child(&bsdf.p, &w_i.normalized());
            ray.min_t = 0.001;
            // Find the next vertex on the path
            match scene.intersect(&mut ray) {
                Some(h) => current_hit = h,
                None => break,
            }
            bounce += 1;
        }
        illum
    }
}

<commit_msg>Don't use the specular bounce tracker for now<commit_after>//! Defines the Path integrator which implements path tracing with
//! explicit light sampling

use std::vec::Vec;
use std::iter;
use std::num::Float;
use rand::{Rng, StdRng};

use scene::Scene;
use linalg;
use linalg::Ray;
use geometry::Intersection;
use film::Colorf;
use integrator::Integrator;
use bxdf::BxDFType;
use sampler::{Sampler, Sample};

/// The path integrator implementing Path tracing with explicit light sampling
/// See [Kajiya, The Rendering Equation](http://dl.acm.org/citation.cfm?id=15902)
#[derive(Copy, Debug)]
pub struct Path {
    min_depth: usize,
    max_depth: usize,
}

impl Path {
    /// Create a new path integrator with the min and max length desired for paths
    pub fn new(min_depth: u32, max_depth: u32) -> Path {
        Path { min_depth: min_depth as usize, max_depth: max_depth as usize }
    }
}

impl Integrator for Path {
    fn illumination(&self, scene: &Scene, r: &Ray, hit: &Intersection, sampler: &mut Sampler,
                    rng: &mut StdRng) -> Colorf {
        // TODO: We really need the memory pool now
        let mut l_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut l_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        let mut bsdf_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut bsdf_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        let mut path_samples: Vec<_> = iter::repeat((0.0, 0.0)).take(self.max_depth as usize + 1us).collect();
        let mut path_samples_comp: Vec<_> = iter::repeat(0.0).take(self.max_depth as usize + 1us).collect();
        sampler.get_samples_2d(&mut l_samples[], rng);
        sampler.get_samples_2d(&mut bsdf_samples[], rng);
        sampler.get_samples_2d(&mut path_samples[], rng);
        sampler.get_samples_1d(&mut l_samples_comp[], rng);
        sampler.get_samples_1d(&mut bsdf_samples_comp[], rng);
        sampler.get_samples_1d(&mut path_samples_comp[], rng);

        let mut illum = Colorf::black();
        let mut path_throughput = Colorf::broadcast(1.0);
        // Track if the previous bounce was a specular one
        //let mut specular_bounce = false;
        let mut current_hit = *hit;
        let mut ray = *r;
        let mut bounce = 0us;
        loop {
            // TODO: Sample emissive objects on first bounce and specular bounces
            // when emissive objects are added
            /*
            if bounce == 0 || specular_bounce {
            }
            */
            let bsdf = current_hit.instance.material.bsdf(&current_hit);
            let w_o = -ray.d;
            let light_sample = Sample::new(&l_samples[bounce], l_samples_comp[bounce]);
            let bsdf_sample = Sample::new(&bsdf_samples[bounce], bsdf_samples_comp[bounce]);
            let li = self.sample_one_light(scene, &w_o, &bsdf, &light_sample, &bsdf_sample);
            illum = illum + path_throughput * li;

            // Determine the next direction to take the path by sampling the BSDF
            let path_sample = Sample::new(&path_samples[bounce], path_samples_comp[bounce]);
            let (f, w_i, pdf, sampled_type) = bsdf.sample(&w_o, BxDFType::all(), &path_sample);
            if f.is_black() || pdf == 0.0 {
                break;
            }
            //specular_bounce = sampled_type.contains(&BxDFType::Specular);
            path_throughput = path_throughput * f * Float::abs(linalg::dot(&w_i, &bsdf.n)) / pdf;

            // Check if we're beyond the min depth at which point we start trying to
            // terminate rays using Russian Roulette
            if bounce > self.min_depth {
                let cont_prob = Float::min(0.5, path_throughput.luminance());
                if rng.next_f32() > cont_prob {
                    break;
                }
                // Re-weight the sum terms accordingly with the Russian roulette weight
                path_throughput = path_throughput / cont_prob;
            }
            if bounce == self.max_depth {
                break;
            }

            ray = ray.child(&bsdf.p, &w_i.normalized());
            ray.min_t = 0.001;
            // Find the next vertex on the path
            match scene.intersect(&mut ray) {
                Some(h) => current_hit = h,
                None => break,
            }
            bounce += 1;
        }
        illum
    }
}

<|endoftext|>


<commit_before>//! Contains structures and functions to aid in various TUF data interchange formats.

mod cjson;

use json;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::io::{Read, Write};

use Result;
use error::Error;

/// The format used for data interchange, serialization, and deserialization.
pub trait DataInterchange {
    /// The type of data that is contained in the `signed` portion of metadata.
    type RawData: Serialize + DeserializeOwned;

    /// The data interchange's extension.
    fn extension() -> &'static str;

    /// A function that canonicalizes data to allow for deterministic signatures.
    fn canonicalize(raw_data: &Self::RawData) -> Result<Vec<u8>>;

    /// Deserialize from `RawData`.
    fn deserialize<T>(raw_data: &Self::RawData) -> Result<T>
    where
        T: DeserializeOwned;

    /// Serialize into `RawData`.
    fn serialize<T>(data: &T) -> Result<Self::RawData>
    where
        T: Serialize;

    /// Write a struct to a stream.
    fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
    where
        W: Write,
        T: Serialize;

    /// Read a struct from a stream.
    fn from_reader<R, T>(rdr: R) -> Result<T>
    where
        R: Read,
        T: DeserializeOwned;
}

/// JSON data interchange.
pub struct JsonDataInterchange {}
impl DataInterchange for JsonDataInterchange {
    type RawData = json::Value;

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    ///
    /// assert_eq!(JsonDataInterchange::extension(), "json");
    /// ```
    fn extension() -> &'static str {
        "json"
    }

    fn canonicalize(raw_data: &Self::RawData) -> Result<Vec<u8>> {
        cjson::canonicalize(raw_data).map_err(|e| Error::Opaque(e))
    }

    fn deserialize<T>(raw_data: &Self::RawData) -> Result<T>
    where
        T: DeserializeOwned,
    {
        Ok(json::from_value(raw_data.clone())?)
    }

    fn serialize<T>(data: &T) -> Result<Self::RawData>
    where
        T: Serialize,
    {
        Ok(json::to_value(data)?)
    }

    fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
    where
        W: Write,
        T: Serialize,
    {
        Ok(json::to_writer(writer, value)?)
    }

    fn from_reader<R, T>(rdr: R) -> Result<T>
    where
        R: Read,
        T: DeserializeOwned,
    {
        Ok(json::from_reader(rdr)?)
    }
}
<commit_msg>json interchange tests<commit_after>//! Contains structures and functions to aid in various TUF data interchange formats.

mod cjson;

use json;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::fmt::Debug;
use std::io::{Read, Write};

use Result;
use error::Error;

/// The format used for data interchange, serialization, and deserialization.
pub trait DataInterchange: Debug {
    /// The type of data that is contained in the `signed` portion of metadata.
    type RawData: Serialize + DeserializeOwned;

    /// The data interchange's extension.
    fn extension() -> &'static str;

    /// A function that canonicalizes data to allow for deterministic signatures.
    fn canonicalize(raw_data: &Self::RawData) -> Result<Vec<u8>>;

    /// Deserialize from `RawData`.
    fn deserialize<T>(raw_data: &Self::RawData) -> Result<T>
    where
        T: DeserializeOwned;

    /// Serialize into `RawData`.
    fn serialize<T>(data: &T) -> Result<Self::RawData>
    where
        T: Serialize;

    /// Write a struct to a stream.
    fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
    where
        W: Write,
        T: Serialize;

    /// Read a struct from a stream.
    fn from_reader<R, T>(rdr: R) -> Result<T>
    where
        R: Read,
        T: DeserializeOwned;
}

/// JSON data interchange.
#[derive(Debug)]
pub struct JsonDataInterchange {}
impl DataInterchange for JsonDataInterchange {
    type RawData = json::Value;

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    ///
    /// assert_eq!(JsonDataInterchange::extension(), "json");
    /// ```
    fn extension() -> &'static str {
        "json"
    }

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    /// use std::collections::HashMap;
    ///
    /// let jsn: &[u8] = br#"{"foo": "bar", "baz": "quux"}"#;
    /// let raw = JsonDataInterchange::from_reader(jsn).unwrap();
    /// let out = JsonDataInterchange::canonicalize(&raw).unwrap();
    /// assert_eq!(out, br#"{"baz":"quux","foo":"bar"}"#);
    /// ```
    fn canonicalize(raw_data: &Self::RawData) -> Result<Vec<u8>> {
        cjson::canonicalize(raw_data).map_err(|e| Error::Opaque(e))
    }

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    /// use std::collections::HashMap;
    ///
    /// let jsn: &[u8] = br#"{"foo": "bar", "baz": "quux"}"#;
    /// let raw = JsonDataInterchange::from_reader(jsn).unwrap();
    /// let mut map = HashMap::new();
    /// let _ = map.insert("foo".to_string(), "bar".to_string());
    /// let _ = map.insert("baz".to_string(), "quux".to_string());
    /// let de: HashMap<String, String> = JsonDataInterchange::deserialize(&raw).unwrap();
    /// assert_eq!(de, map);
    /// ```
    fn deserialize<T>(raw_data: &Self::RawData) -> Result<T>
    where
        T: DeserializeOwned,
    {
        Ok(json::from_value(raw_data.clone())?)
    }

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    /// use std::collections::HashMap;
    ///
    /// let arr = vec![1, 2, 3];
    /// let raw = JsonDataInterchange::serialize(&arr).unwrap();
    /// assert!(raw.is_array());
    ///
    /// let mut map = HashMap::new();
    /// let _ = map.insert("abc", 123);
    /// let raw = JsonDataInterchange::serialize(&map).unwrap();
    /// assert!(raw.is_object());
    /// ```
    fn serialize<T>(data: &T) -> Result<Self::RawData>
    where
        T: Serialize,
    {
        Ok(json::to_value(data)?)
    }

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    ///
    /// let arr = vec![1, 2, 3];
    /// let mut buf = Vec::new();
    /// JsonDataInterchange::to_writer(&mut buf, &arr).unwrap();
    /// assert!(&buf == b"[1, 2, 3]" || &buf == b"[1,2,3]");
    /// ```
    fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
    where
        W: Write,
        T: Serialize,
    {
        Ok(json::to_writer(writer, value)?)
    }

    /// ```
    /// use tuf::interchange::{DataInterchange, JsonDataInterchange};
    /// use std::collections::HashMap;
    ///
    /// let jsn: &[u8] = br#"{"foo": "bar", "baz": "quux"}"#;
    /// let _: HashMap<String, String> = JsonDataInterchange::from_reader(jsn).unwrap();
    /// ```
    fn from_reader<R, T>(rdr: R) -> Result<T>
    where
        R: Read,
        T: DeserializeOwned,
    {
        Ok(json::from_reader(rdr)?)
    }
}
<|endoftext|>