<commit_before>/*!
This module just contains any big string literals I don't want cluttering up the rest of the code.
*/

/**
The message output when the user invokes `cargo script` with no further arguments.  We need to do this ourselves because `clap` doesn't provide any way to generate this message manually.
*/
pub const NO_ARGS_MESSAGE: &'static str = "\
The following required arguments were not supplied:
\t'<script>'

USAGE:
\tcargo script [FLAGS OPTIONS] [--] <script> <args>...

For more information try --help";

/*
What follows are the templates used to wrap script input.  The input provided by the user is inserted in place of `%%`.  *Proper* templates of some kind would be nice, but damnit, I'm lazy.
*/

/// The template used for script file inputs.
pub const FILE_TEMPLATE: &'static str = r#"%%"#;

/// The template used for `--expr` input.
pub const EXPR_TEMPLATE: &'static str = r#"
fn main() {
    println!("{}", {%%});
}
"#;

/*
Regarding the loop templates: what I *want* is for the result of the closure to be printed to standard output *only* if it's not `()`.

* TODO: Just use TypeId, dumbass.
* TODO: Merge the `LOOP_*` templates so there isn't duplicated code.  It's icky.
*/

/// The template used for `--loop` input, assuming no `--count` flag is also given.
pub const LOOP_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure({%%});
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        let output = closure(&line_buffer);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str) -> T {
    closure
}
"#;

/// The template used for `--count --loop` input.
pub const LOOP_COUNT_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure({%%});
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    let mut count = 0;
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        count += 1;
        let output = closure(&line_buffer, count);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str, usize) -> T {
    closure
}
"#;

/**
The default manifest used for packages.  `%n` is replaced with the "safe name" of the input, which *should* be safe to use as a file name.
*/
pub const DEFAULT_MANIFEST: &'static str = r#"
[package]
name = "%n"
version = "0.1.0"
authors = ["Anonymous"]

[[bin]]
name = "%n"
path = "%n.rs"
"#;

/**
The name of the package metadata file.
*/
pub const METADATA_FILE: &'static str = "metadata.json";

/**
Extensions to check when trying to find script input by name.
*/
pub const SEARCH_EXTS: &'static [&'static str] = &["crs", "rs"];

/*
These relate to Input::compute_id.
*/

/**
When generating a package's unique ID, how many hex nibbles of the compressed path should be used *at most*?
*/
pub const DEFLATE_PATH_LEN_MAX: usize = 20;

/**
When generating a package's unique ID, how many hex nibbles of the script digest should be used *at most*?
*/
pub const CONTENT_DIGEST_LEN_MAX: usize = 20;

/**
How old can stuff in the cache be before we automatically clear it out?

Measured in milliseconds.
*/
// It's been *one week* since you looked at me,
// cocked your head to the side and said "I'm angry."
pub const MAX_CACHE_AGE_MS: u64 = 1*7*24*60*60*1000;
<commit_msg>Changed templates to (almost) put subst. on their own line.<commit_after>/*!
This module just contains any big string literals I don't want cluttering up the rest of the code.
*/

/**
The message output when the user invokes `cargo script` with no further arguments.  We need to do this ourselves because `clap` doesn't provide any way to generate this message manually.
*/
pub const NO_ARGS_MESSAGE: &'static str = "\
The following required arguments were not supplied:
\t'<script>'

USAGE:
\tcargo script [FLAGS OPTIONS] [--] <script> <args>...

For more information try --help";

/*
What follows are the templates used to wrap script input.  The input provided by the user is inserted in place of `%%`.  *Proper* templates of some kind would be nice, but damnit, I'm lazy.
*/

/// The template used for script file inputs.
pub const FILE_TEMPLATE: &'static str = r#"%%"#;

/// The template used for `--expr` input.
pub const EXPR_TEMPLATE: &'static str = r#"
fn main() {
    println!("{}",
{%%}
    );
}
"#;

/*
Regarding the loop templates: what I *want* is for the result of the closure to be printed to standard output *only* if it's not `()`.

* TODO: Just use TypeId, dumbass.
* TODO: Merge the `LOOP_*` templates so there isn't duplicated code.  It's icky.
*/

/// The template used for `--loop` input, assuming no `--count` flag is also given.
pub const LOOP_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        let output = closure(&line_buffer);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str) -> T {
    closure
}
"#;

/// The template used for `--count --loop` input.
pub const LOOP_COUNT_TEMPLATE: &'static str = r#"
use std::io::prelude::*;

fn main() {
    let mut closure = enforce_closure(
{%%}
    );
    let mut out_buffer: Vec<u8> = vec![];
    let mut line_buffer = String::new();
    let mut stdin = std::io::stdin();
    let mut count = 0;
    loop {
        line_buffer.clear();
        let read_res = stdin.read_line(&mut line_buffer).unwrap_or(0);
        if read_res == 0 { break }
        count += 1;
        let output = closure(&line_buffer, count);

        out_buffer.clear();
        write!(&mut out_buffer, "{:?}", output).unwrap();
        let out_str = String::from_utf8_lossy(&out_buffer);
        if &*out_str != "()" {
            println!("{}", out_str);
        }
    }
}

fn enforce_closure<F, T>(closure: F) -> F
where F: FnMut(&str, usize) -> T {
    closure
}
"#;

/**
The default manifest used for packages.  `%n` is replaced with the "safe name" of the input, which *should* be safe to use as a file name.
*/
pub const DEFAULT_MANIFEST: &'static str = r#"
[package]
name = "%n"
version = "0.1.0"
authors = ["Anonymous"]

[[bin]]
name = "%n"
path = "%n.rs"
"#;

/**
The name of the package metadata file.
*/
pub const METADATA_FILE: &'static str = "metadata.json";

/**
Extensions to check when trying to find script input by name.
*/
pub const SEARCH_EXTS: &'static [&'static str] = &["crs", "rs"];

/*
These relate to Input::compute_id.
*/

/**
When generating a package's unique ID, how many hex nibbles of the compressed path should be used *at most*?
*/
pub const DEFLATE_PATH_LEN_MAX: usize = 20;

/**
When generating a package's unique ID, how many hex nibbles of the script digest should be used *at most*?
*/
pub const CONTENT_DIGEST_LEN_MAX: usize = 20;

/**
How old can stuff in the cache be before we automatically clear it out?

Measured in milliseconds.
*/
// It's been *one week* since you looked at me,
// cocked your head to the side and said "I'm angry."
pub const MAX_CACHE_AGE_MS: u64 = 1*7*24*60*60*1000;
<|endoftext|>


<commit_before>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Cursors — Standard and pixmap cursors

use glib::translate::*;
use glib::types;
use display::Display;
use object::Object;
use pixbuf::Pixbuf;
use ffi;

pub type Type = ffi::GdkCursorType;

pub type Cursor = Object<ffi::GdkCursor>;

impl types::StaticType for Cursor {
    fn static_type() -> types::Type { unsafe { from_glib(ffi::gdk_cursor_get_type()) } }
}

impl Cursor {
    pub fn new(cursor_type: Type) -> Cursor {
        unsafe { from_glib_full(ffi::gdk_cursor_new(cursor_type)) }
    }

    pub fn new_from_pixbuf(display: &Display, pixbuf: &Pixbuf, x: i32, y: i32) -> Cursor {
        unsafe {
            from_glib_full(
                ffi::gdk_cursor_new_from_pixbuf(display.to_glib_none().0,
                    pixbuf.to_glib_none().0, x, y))
        }
    }

    pub fn new_from_name(display: &Display, name: &str) -> Option<Cursor> {
        unsafe {
            from_glib_full(ffi::gdk_cursor_new_from_name(display.to_glib_none().0,
                                                         name.to_glib_none().0))
        }
    }

    pub fn new_for_display(display: &Display, cursor_type: Type) -> Cursor {
        unsafe {
            from_glib_full(ffi::gdk_cursor_new_for_display(display.to_glib_none().0, cursor_type))
        }
    }

    pub fn get_display(&self) -> Display {
        unsafe { from_glib_none(ffi::gdk_cursor_get_display(self.to_glib_none().0)) }
    }

    pub fn get_image(&self) -> Option<Pixbuf> {
        unsafe { from_glib_full(ffi::gdk_cursor_get_image(self.to_glib_none().0)) }
    }

    pub fn get_cursor_type(&self) -> Type {
        unsafe { ffi::gdk_cursor_get_cursor_type(self.to_glib_none().0) }
    }
}
<commit_msg>Add Cursor documentation<commit_after>// Copyright 2013-2015, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Cursors — Standard and pixmap cursors

use glib::translate::*;
use glib::types;
use display::Display;
use object::Object;
use pixbuf::Pixbuf;
use ffi;

pub type Type = ffi::GdkCursorType;

pub type Cursor = Object<ffi::GdkCursor>;

impl types::StaticType for Cursor {
    fn static_type() -> types::Type { unsafe { from_glib(ffi::gdk_cursor_get_type()) } }
}

impl Cursor {
    /// Creates a new cursor from the set of builtin cursors for the default display. See
    /// Cursor::new_for_display().
    ///
    /// To make the cursor invisible, use Type::BlankCursor.
    ///
    /// Warning : Cursor::new() has been deprecated since version 3.16 and should not be used
    /// in newly-written code.
    ///
    /// Use Cursor::new_for_display() instead.
    pub fn new(cursor_type: Type) -> Cursor {
        unsafe { from_glib_full(ffi::gdk_cursor_new(cursor_type)) }
    }

    /// Creates a new cursor from a pixbuf.
    ///
    /// Not all GDK backends support RGBA cursors. If they are not supported, a monochrome
    /// approximation will be displayed. The functions Display::supports_cursor_alpha() and
    /// Display::supports_cursor_color() can be used to determine whether RGBA cursors are
    /// supported; Display::get_default_cursor_size() and Display::get_maximal_cursor_size()
    /// give information about cursor sizes.
    ///
    /// If `x` or `y` are -1, the pixbuf must have options named “x_hot” and “y_hot”, resp.,
    /// containing integer values between 0 and the width resp. height of the pixbuf. (Since:
    /// 3.0)
    ///
    /// On the X backend, support for RGBA cursors requires a sufficently new version of the
    /// X Render extension.
    pub fn new_from_pixbuf(display: &Display, pixbuf: &Pixbuf, x: i32, y: i32) -> Cursor {
        unsafe {
            from_glib_full(
                ffi::gdk_cursor_new_from_pixbuf(display.to_glib_none().0,
                    pixbuf.to_glib_none().0, x, y))
        }
    }

    /// Creates a new cursor by looking up `name` in the current cursor theme.
    pub fn new_from_name(display: &Display, name: &str) -> Option<Cursor> {
        unsafe {
            from_glib_full(ffi::gdk_cursor_new_from_name(display.to_glib_none().0,
                                                         name.to_glib_none().0))
        }
    }

    /// Creates a new cursor from the set of builtin cursors.
    ///
    /// You can find a list of useful ones here:
    /// https://developer.gnome.org/gdk3/stable/gdk3-Cursors.html#gdk-cursor-new-for-display
    pub fn new_for_display(display: &Display, cursor_type: Type) -> Cursor {
        unsafe {
            from_glib_full(ffi::gdk_cursor_new_for_display(display.to_glib_none().0, cursor_type))
        }
    }

    /// Returns the display on which the Cursor is defined.
    pub fn get_display(&self) -> Display {
        unsafe { from_glib_none(ffi::gdk_cursor_get_display(self.to_glib_none().0)) }
    }

    /// Returns a Pixbuf with the image used to display the cursor.
    ///
    /// Note that depending on the capabilities of the windowing system and on the cursor,
    /// GDK may not be able to obtain the image data. In this case, None is returned.
    pub fn get_image(&self) -> Option<Pixbuf> {
        unsafe { from_glib_full(ffi::gdk_cursor_get_image(self.to_glib_none().0)) }
    }

    /// Returns the cursor type for this cursor.
    pub fn get_cursor_type(&self) -> Type {
        unsafe { ffi::gdk_cursor_get_cursor_type(self.to_glib_none().0) }
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::io::IoError;
use std::fmt;
use libc::dev_t;
use std::iter;
use std::time::Duration;

use libudev_c;
use util;
use enumerator;

use udev::Udev;
use enumerator::DeviceEnumerator;
use iterator::UdevIterator;

pub struct Device<'u> {
    pub udev: &'u Udev,
    dev: libudev_c::udev_device,
}
pub type Devnum = dev_t;
pub enum DeviceType {
    CharDev,
    BlockDev
}

// Crate Private
pub unsafe fn device<'u>(udev: &'u Udev, dev: libudev_c::udev_device) -> Device<'u> {
    Device { udev: udev, dev: dev }
}

impl<'u> Device<'u> {
    pub fn parent(&self) -> Option<Device> {
        match util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(libudev_c::udev_device_get_parent(self.dev))
        }) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn parent_with_subsystem(&self, subsystem: &str) -> Option<Device> {
        match subsystem.with_c_str(|subsystem| util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(
                libudev_c::udev_device_get_parent_with_subsystem_devtype(self.dev, subsystem, ptr::null()))
        })) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn parent_with_subsystem_devtype(&self, subsystem: &str, devtype: &str) -> Option<Device> {
        match subsystem.with_c_str(|subsystem| devtype.with_c_str(|devtype| util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(
                libudev_c::udev_device_get_parent_with_subsystem_devtype(self.dev, subsystem, devtype))
        }))) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn attribute<'s>(&'s self, attr: &str) -> Option<&'s str> {
        attr.with_c_str(|cstr| unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysattr_value(self.dev, cstr))
        })
    }

    pub fn set_attribute(&self, attr: &str, value: &str) -> Result<(), IoError> {
        attr.with_c_str(|attr| value.with_c_str(|value| match unsafe {
            libudev_c::udev_device_set_sysattr_value(self.dev, attr, value)
        } {
            0           => Ok(()),
            n if n < 0  => Err(IoError::from_errno(-n as uint, true)),
            _           => fail!("udev returned an invalid error")
        }))
    }

    pub fn devpath<'s>(&'s self) -> &'s str {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devpath(self.dev)).unwrap()
        }
    }

    pub fn syspath<'s>(&'s self) -> Path {
        unsafe {
            Path::new(util::c_to_str(libudev_c::udev_device_get_syspath(self.dev)).unwrap())
        }
    }

    pub fn sysname<'s>(&'s self) -> &'s str {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysname(self.dev)).unwrap()
        }
    }

    pub fn subsystem<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_subsystem(self.dev))
        }
    }

    pub fn devtype<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devtype(self.dev))
        }
    }

    pub fn sysnum(&self) -> Option<uint> {
        match unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysnum(self.dev))
        } {
            Some(n) => from_str(n),
            None => None
        }
    }

    pub fn devnum(&self) -> Devnum {
        unsafe {
            libudev_c::udev_device_get_devnum(self.dev)
        }
    }

    pub fn driver<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_driver(self.dev))
        }
    }

    pub fn devnode<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devnode(self.dev))
        }
    }

    pub fn iter_devlinks(&self) -> iter::Map<(&Device,&str,Option<&str>),Path,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_devlinks_list_entry(self.dev)
        }).map(|(_, key, _)| Path::new(key))
    }

    pub fn iter_tags(&self) -> iter::Map<(&Device,&str,Option<&str>),&str,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_tags_list_entry(self.dev)
        }).map(|(_, key, _)| key)
    }

    pub fn iter_properties(&self) -> iter::Map<(&Device,&str,Option<&str>),(&str, Option<&str>),UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_properties_list_entry(self.dev)
        }).map(|(_, key, value)| (key, value))
    }

    pub fn iter_attributes(& self) -> iter::Map<(&Device,&str,Option<&str>),&str,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_sysattr_list_entry(self.dev)
        }).map(|(_, key, _)| key)
    }

    pub fn time_since_initialized(&self) -> Option<Duration> {
        let usec = unsafe { libudev_c::udev_device_get_usec_since_initialized(self.dev) };
        if usec == 0 {
            None
        } else {
            // Note: I don't support machines that are online for over 292,471 years. Sorry.
            Some(Duration::microseconds(usec as i64))
        }
    }

    pub fn is_initialized(&self) -> bool {
        unsafe { libudev_c::udev_device_get_is_initialized(self.dev) != 0 }
    }

    pub fn has_tag(&self, tag: &str) -> bool {
        tag.with_c_str(|tag| unsafe {
            libudev_c::udev_device_has_tag(self.dev, tag) != 0
        })
    }

    pub fn children(&self) -> DeviceEnumerator<'u> {
        enumerator::device_enumerator(self.udev, Some(self.dev))
    }
}

#[unsafe_destructor]
impl<'u> Drop for Device<'u> {
    fn drop(&mut self) {
        unsafe { libudev_c::udev_device_unref(self.dev) };
    }
}

impl<'u> fmt::Show for Device<'u> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.syspath().as_str().unwrap())
    }
}

impl DeviceType {
    pub fn to_char(self) -> i8 {
        match self {
            CharDev => 'c' as i8,
            BlockDev => 'b' as i8
        }
    }
}
<commit_msg>Avoid uint<commit_after>use std::ptr;
use std::io::IoError;
use std::fmt;
use libc::dev_t;
use std::iter;
use std::time::Duration;

use libudev_c;
use util;
use enumerator;

use udev::Udev;
use enumerator::DeviceEnumerator;
use iterator::UdevIterator;

pub struct Device<'u> {
    pub udev: &'u Udev,
    dev: libudev_c::udev_device,
}
pub type Devnum = dev_t;
pub enum DeviceType {
    CharDev,
    BlockDev
}

// Crate Private
pub unsafe fn device<'u>(udev: &'u Udev, dev: libudev_c::udev_device) -> Device<'u> {
    Device { udev: udev, dev: dev }
}

impl<'u> Device<'u> {
    pub fn parent(&self) -> Option<Device> {
        match util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(libudev_c::udev_device_get_parent(self.dev))
        }) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn parent_with_subsystem(&self, subsystem: &str) -> Option<Device> {
        match subsystem.with_c_str(|subsystem| util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(
                libudev_c::udev_device_get_parent_with_subsystem_devtype(self.dev, subsystem, ptr::null()))
        })) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn parent_with_subsystem_devtype(&self, subsystem: &str, devtype: &str) -> Option<Device> {
        match subsystem.with_c_str(|subsystem| devtype.with_c_str(|devtype| util::check_errno(|| unsafe {
            libudev_c::udev_device_ref(
                libudev_c::udev_device_get_parent_with_subsystem_devtype(self.dev, subsystem, devtype))
        }))) {
            Ok(Some(dev)) => Some(unsafe { device(self.udev, dev) }),
            _ => None
        }
    }

    pub fn attribute<'s>(&'s self, attr: &str) -> Option<&'s str> {
        attr.with_c_str(|cstr| unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysattr_value(self.dev, cstr))
        })
    }

    pub fn set_attribute(&self, attr: &str, value: &str) -> Result<(), IoError> {
        attr.with_c_str(|attr| value.with_c_str(|value| match unsafe {
            libudev_c::udev_device_set_sysattr_value(self.dev, attr, value)
        } {
            0           => Ok(()),
            n if n < 0  => Err(IoError::from_errno(-n as uint, true)),
            _           => fail!("udev returned an invalid error")
        }))
    }

    pub fn devpath<'s>(&'s self) -> &'s str {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devpath(self.dev)).unwrap()
        }
    }

    pub fn syspath<'s>(&'s self) -> Path {
        unsafe {
            Path::new(util::c_to_str(libudev_c::udev_device_get_syspath(self.dev)).unwrap())
        }
    }

    pub fn sysname<'s>(&'s self) -> &'s str {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysname(self.dev)).unwrap()
        }
    }

    pub fn subsystem<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_subsystem(self.dev))
        }
    }

    pub fn devtype<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devtype(self.dev))
        }
    }

    pub fn sysnum(&self) -> Option<u64> {
        match unsafe {
            util::c_to_str(libudev_c::udev_device_get_sysnum(self.dev))
        } {
            Some(n) => from_str(n),
            None => None
        }
    }

    pub fn devnum(&self) -> Devnum {
        unsafe {
            libudev_c::udev_device_get_devnum(self.dev)
        }
    }

    pub fn driver<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_driver(self.dev))
        }
    }

    pub fn devnode<'s>(&'s self) -> Option<&'s str> {
        unsafe {
            util::c_to_str(libudev_c::udev_device_get_devnode(self.dev))
        }
    }

    pub fn iter_devlinks(&self) -> iter::Map<(&Device,&str,Option<&str>),Path,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_devlinks_list_entry(self.dev)
        }).map(|(_, key, _)| Path::new(key))
    }

    pub fn iter_tags(&self) -> iter::Map<(&Device,&str,Option<&str>),&str,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_tags_list_entry(self.dev)
        }).map(|(_, key, _)| key)
    }

    pub fn iter_properties(&self) -> iter::Map<(&Device,&str,Option<&str>),(&str, Option<&str>),UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_properties_list_entry(self.dev)
        }).map(|(_, key, value)| (key, value))
    }

    pub fn iter_attributes(& self) -> iter::Map<(&Device,&str,Option<&str>),&str,UdevIterator<Device>> {
        UdevIterator::new(self, unsafe {
            libudev_c::udev_device_get_sysattr_list_entry(self.dev)
        }).map(|(_, key, _)| key)
    }

    pub fn time_since_initialized(&self) -> Option<Duration> {
        let usec = unsafe { libudev_c::udev_device_get_usec_since_initialized(self.dev) };
        if usec == 0 {
            None
        } else {
            // Note: I don't support machines that are online for over 292,471 years. Sorry.
            Some(Duration::microseconds(usec as i64))
        }
    }

    pub fn is_initialized(&self) -> bool {
        unsafe { libudev_c::udev_device_get_is_initialized(self.dev) != 0 }
    }

    pub fn has_tag(&self, tag: &str) -> bool {
        tag.with_c_str(|tag| unsafe {
            libudev_c::udev_device_has_tag(self.dev, tag) != 0
        })
    }

    pub fn children(&self) -> DeviceEnumerator<'u> {
        enumerator::device_enumerator(self.udev, Some(self.dev))
    }
}

#[unsafe_destructor]
impl<'u> Drop for Device<'u> {
    fn drop(&mut self) {
        unsafe { libudev_c::udev_device_unref(self.dev) };
    }
}

impl<'u> fmt::Show for Device<'u> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.syspath().as_str().unwrap())
    }
}

impl DeviceType {
    pub fn to_char(self) -> i8 {
        match self {
            CharDev => 'c' as i8,
            BlockDev => 'b' as i8
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Result, Write};

use itertools::Itertools;

use crate::document::Document;
use crate::inline_table::DEFAULT_INLINE_KEY_DECOR;
use crate::key::Key;
use crate::repr::{DecorDisplay, Formatted, Repr};
use crate::table::{DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_TABLE_DECOR};
use crate::value::DEFAULT_VALUE_DECOR;
use crate::{Array, InlineTable, Item, Table, Value};

impl<'d, D: Display> Display for DecorDisplay<'d, D> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}{}{}",
            self.decor.prefix().unwrap_or(self.default.0),
            self.inner,
            self.decor.suffix().unwrap_or(self.default.1)
        )
    }
}

impl Display for Repr {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        self.as_raw().fmt(f)
    }
}

impl<T> Display for Formatted<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "{}", self.decor.display(&self.repr, DEFAULT_VALUE_DECOR))
    }
}

impl Display for Key {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        // HACK: For now, leaving off decor since we don't know the defaults to use in this context
        self.repr().fmt(f)
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match *self {
            Value::String(ref repr) => write!(f, "{}", repr),
            Value::Integer(ref repr) => write!(f, "{}", repr),
            Value::Float(ref repr) => write!(f, "{}", repr),
            Value::Boolean(ref repr) => write!(f, "{}", repr),
            Value::OffsetDateTime(ref repr) => write!(f, "{}", repr),
            Value::LocalDateTime(ref repr) => write!(f, "{}", repr),
            Value::LocalDate(ref repr) => write!(f, "{}", repr),
            Value::LocalTime(ref repr) => write!(f, "{}", repr),
            Value::Array(ref array) => write!(f, "{}", array),
            Value::InlineTable(ref table) => write!(f, "{}", table),
        }
    }
}

impl Display for Array {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}[",
            self.decor.prefix().unwrap_or(DEFAULT_VALUE_DECOR.0)
        )?;
        join(f, self.iter(), ",")?;
        if self.trailing_comma {
            write!(f, ",")?;
        }
        write!(f, "{}", self.trailing)?;
        write!(
            f,
            "]{}",
            self.decor.suffix().unwrap_or(DEFAULT_VALUE_DECOR.1)
        )
    }
}

impl Display for InlineTable {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}{{",
            self.decor.prefix().unwrap_or(DEFAULT_VALUE_DECOR.0)
        )?;
        write!(f, "{}", self.preamble)?;

        let children = self.get_values();
        for (i, (key_path, value)) in children.into_iter().enumerate() {
            let key = key_path_display(&key_path, DEFAULT_INLINE_KEY_DECOR);
            if i > 0 {
                write!(f, ",")?;
            }
            write!(f, "{}={}", key, value)?;
        }

        write!(
            f,
            "}}{}",
            self.decor.suffix().unwrap_or(DEFAULT_VALUE_DECOR.1)
        )
    }
}

impl Table {
    fn visit_nested_tables<'t, F>(
        &'t self,
        path: &mut Vec<&'t Key>,
        is_array_of_tables: bool,
        callback: &mut F,
    ) -> Result
    where
        F: FnMut(&'t Table, &Vec<&'t Key>, bool) -> Result,
    {
        callback(self, path, is_array_of_tables)?;

        for kv in self.items.values() {
            match kv.value {
                Item::Table(ref t) if !t.is_dotted() => {
                    path.push(&kv.key);
                    t.visit_nested_tables(path, false, callback)?;
                    path.pop();
                }
                Item::ArrayOfTables(ref a) => {
                    for t in a.iter() {
                        path.push(&kv.key);
                        t.visit_nested_tables(path, true, callback)?;
                        path.pop();
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }
}

fn visit_table(
    f: &mut dyn Write,
    table: &Table,
    path: &[&Key],
    is_array_of_tables: bool,
) -> Result {
    let children = table.get_values();

    if path.is_empty() {
        // don't print header for the root node
    } else if is_array_of_tables {
        write!(
            f,
            "{}[[",
            table.decor.prefix().unwrap_or(DEFAULT_TABLE_DECOR.0)
        )?;
        write!(
            f,
            "{}",
            path.iter()
                .map(|k| k.decor.display(k, DEFAULT_KEY_PATH_DECOR))
                .join(".")
        )?;
        writeln!(
            f,
            "]]{}",
            table.decor.suffix().unwrap_or(DEFAULT_TABLE_DECOR.1)
        )?;
    } else if !(table.implicit && children.is_empty()) {
        write!(
            f,
            "{}[",
            table.decor.prefix().unwrap_or(DEFAULT_TABLE_DECOR.0)
        )?;
        write!(
            f,
            "{}",
            path.iter()
                .map(|k| k.decor.display(k, DEFAULT_KEY_PATH_DECOR))
                .join(".")
        )?;
        writeln!(
            f,
            "]{}",
            table.decor.suffix().unwrap_or(DEFAULT_TABLE_DECOR.1)
        )?;
    }
    // print table body
    for (key_path, value) in children {
        let key = key_path_display(&key_path, DEFAULT_KEY_DECOR);
        writeln!(f, "{}={}", key, value)?;
    }
    Ok(())
}

fn key_path_display(key_path: &[&Key], default: (&'static str, &'static str)) -> impl Display {
    key_path
        .iter()
        .enumerate()
        .map(|(ki, k)| {
            let prefix = if ki == 0 {
                default.0
            } else {
                DEFAULT_KEY_PATH_DECOR.0
            };
            let suffix = if ki + 1 == key_path.len() {
                default.1
            } else {
                DEFAULT_KEY_PATH_DECOR.1
            };
            k.decor.display(k, (prefix, suffix))
        })
        .join(".")
}

impl Display for Table {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        let mut path = Vec::new();

        self.visit_nested_tables(&mut path, false, &mut |t, path, is_array| {
            visit_table(f, t, path, is_array)
        })?;
        Ok(())
    }
}

impl Display for Document {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        let mut path = Vec::new();
        let mut last_position = 0;
        let mut tables = Vec::new();
        self.as_table()
            .visit_nested_tables(&mut path, false, &mut |t, p, is_array| {
                if let Some(pos) = t.position {
                    last_position = pos;
                }
                tables.push((last_position, t, p.clone(), is_array));
                Ok(())
            })
            .unwrap();

        tables.sort_by_key(|&(id, _, _, _)| id);
        for (_, table, path, is_array) in tables {
            visit_table(f, table, &path, is_array)?;
        }
        self.trailing.fmt(f)
    }
}

fn join<D, I>(f: &mut Formatter<'_>, iter: I, sep: &str) -> Result
where
    D: Display,
    I: Iterator<Item = D>,
{
    for (i, v) in iter.enumerate() {
        if i > 0 {
            write!(f, "{}", sep)?;
        }
        write!(f, "{}", v)?;
    }
    Ok(())
}
<commit_msg>refactor: Consolidate on join implementations (#161)<commit_after>use std::fmt::{Display, Formatter, Result, Write};

use itertools::Itertools;

use crate::document::Document;
use crate::inline_table::DEFAULT_INLINE_KEY_DECOR;
use crate::key::Key;
use crate::repr::{DecorDisplay, Formatted, Repr};
use crate::table::{DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_TABLE_DECOR};
use crate::value::DEFAULT_VALUE_DECOR;
use crate::{Array, InlineTable, Item, Table, Value};

impl<'d, D: Display> Display for DecorDisplay<'d, D> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}{}{}",
            self.decor.prefix().unwrap_or(self.default.0),
            self.inner,
            self.decor.suffix().unwrap_or(self.default.1)
        )
    }
}

impl Display for Repr {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        self.as_raw().fmt(f)
    }
}

impl<T> Display for Formatted<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "{}", self.decor.display(&self.repr, DEFAULT_VALUE_DECOR))
    }
}

impl Display for Key {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        // HACK: For now, leaving off decor since we don't know the defaults to use in this context
        self.repr().fmt(f)
    }
}

impl Display for Value {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match *self {
            Value::String(ref repr) => write!(f, "{}", repr),
            Value::Integer(ref repr) => write!(f, "{}", repr),
            Value::Float(ref repr) => write!(f, "{}", repr),
            Value::Boolean(ref repr) => write!(f, "{}", repr),
            Value::OffsetDateTime(ref repr) => write!(f, "{}", repr),
            Value::LocalDateTime(ref repr) => write!(f, "{}", repr),
            Value::LocalDate(ref repr) => write!(f, "{}", repr),
            Value::LocalTime(ref repr) => write!(f, "{}", repr),
            Value::Array(ref array) => write!(f, "{}", array),
            Value::InlineTable(ref table) => write!(f, "{}", table),
        }
    }
}

impl Display for Array {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}[",
            self.decor.prefix().unwrap_or(DEFAULT_VALUE_DECOR.0)
        )?;
        write!(f, "{}", self.iter().join(","))?;
        if self.trailing_comma {
            write!(f, ",")?;
        }
        write!(f, "{}", self.trailing)?;
        write!(
            f,
            "]{}",
            self.decor.suffix().unwrap_or(DEFAULT_VALUE_DECOR.1)
        )
    }
}

impl Display for InlineTable {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(
            f,
            "{}{{",
            self.decor.prefix().unwrap_or(DEFAULT_VALUE_DECOR.0)
        )?;
        write!(f, "{}", self.preamble)?;

        let children = self.get_values();
        for (i, (key_path, value)) in children.into_iter().enumerate() {
            let key = key_path_display(&key_path, DEFAULT_INLINE_KEY_DECOR);
            if i > 0 {
                write!(f, ",")?;
            }
            write!(f, "{}={}", key, value)?;
        }

        write!(
            f,
            "}}{}",
            self.decor.suffix().unwrap_or(DEFAULT_VALUE_DECOR.1)
        )
    }
}

impl Table {
    fn visit_nested_tables<'t, F>(
        &'t self,
        path: &mut Vec<&'t Key>,
        is_array_of_tables: bool,
        callback: &mut F,
    ) -> Result
    where
        F: FnMut(&'t Table, &Vec<&'t Key>, bool) -> Result,
    {
        callback(self, path, is_array_of_tables)?;

        for kv in self.items.values() {
            match kv.value {
                Item::Table(ref t) if !t.is_dotted() => {
                    path.push(&kv.key);
                    t.visit_nested_tables(path, false, callback)?;
                    path.pop();
                }
                Item::ArrayOfTables(ref a) => {
                    for t in a.iter() {
                        path.push(&kv.key);
                        t.visit_nested_tables(path, true, callback)?;
                        path.pop();
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }
}

fn visit_table(
    f: &mut dyn Write,
    table: &Table,
    path: &[&Key],
    is_array_of_tables: bool,
) -> Result {
    let children = table.get_values();

    if path.is_empty() {
        // don't print header for the root node
    } else if is_array_of_tables {
        write!(
            f,
            "{}[[",
            table.decor.prefix().unwrap_or(DEFAULT_TABLE_DECOR.0)
        )?;
        write!(
            f,
            "{}",
            path.iter()
                .map(|k| k.decor.display(k, DEFAULT_KEY_PATH_DECOR))
                .join(".")
        )?;
        writeln!(
            f,
            "]]{}",
            table.decor.suffix().unwrap_or(DEFAULT_TABLE_DECOR.1)
        )?;
    } else if !(table.implicit && children.is_empty()) {
        write!(
            f,
            "{}[",
            table.decor.prefix().unwrap_or(DEFAULT_TABLE_DECOR.0)
        )?;
        write!(
            f,
            "{}",
            path.iter()
                .map(|k| k.decor.display(k, DEFAULT_KEY_PATH_DECOR))
                .join(".")
        )?;
        writeln!(
            f,
            "]{}",
            table.decor.suffix().unwrap_or(DEFAULT_TABLE_DECOR.1)
        )?;
    }
    // print table body
    for (key_path, value) in children {
        let key = key_path_display(&key_path, DEFAULT_KEY_DECOR);
        writeln!(f, "{}={}", key, value)?;
    }
    Ok(())
}

fn key_path_display(key_path: &[&Key], default: (&'static str, &'static str)) -> impl Display {
    key_path
        .iter()
        .enumerate()
        .map(|(ki, k)| {
            let prefix = if ki == 0 {
                default.0
            } else {
                DEFAULT_KEY_PATH_DECOR.0
            };
            let suffix = if ki + 1 == key_path.len() {
                default.1
            } else {
                DEFAULT_KEY_PATH_DECOR.1
            };
            k.decor.display(k, (prefix, suffix))
        })
        .join(".")
}

impl Display for Table {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        let mut path = Vec::new();

        self.visit_nested_tables(&mut path, false, &mut |t, path, is_array| {
            visit_table(f, t, path, is_array)
        })?;
        Ok(())
    }
}

impl Display for Document {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        let mut path = Vec::new();
        let mut last_position = 0;
        let mut tables = Vec::new();
        self.as_table()
            .visit_nested_tables(&mut path, false, &mut |t, p, is_array| {
                if let Some(pos) = t.position {
                    last_position = pos;
                }
                tables.push((last_position, t, p.clone(), is_array));
                Ok(())
            })
            .unwrap();

        tables.sort_by_key(|&(id, _, _, _)| id);
        for (_, table, path, is_array) in tables {
            visit_table(f, table, &path, is_array)?;
        }
        self.trailing.fmt(f)
    }
}
<|endoftext|>


<commit_before>//! Define the various error kinds specific to deterministic secret sharing.

#![allow(unknown_lints, missing_docs)]

use std::collections::HashSet;

#[cfg(feature = "dss")]
use dss::ss1;

/// Minimum allowed number of shares (n)
pub(crate) static MIN_SHARES: u8 = 2;
/// Minimum allowed threshold (k)
pub(crate) static MIN_THRESHOLD: u8 = 2;
/// Maximum allowed number of shares (k,n)
pub(crate) static MAX_SHARES: u8 = 255;
/// SSS Shares should be structured as k-n-data hence 3 parts
pub(crate) static SSS_SHARE_PARTS_COUNT: usize = 3;

/// Create the Error, ErrorKind, ResultExt, and Result types
error_chain! {
    errors {
        ThresholdTooBig(k: u8, n: u8) {
            description("Threshold k must be smaller than or equal to n")
            display("Threshold k must be smaller than or equal to n, got: k = {}, n = {}.", k, n)
        }

        ThresholdTooSmall(k: u8) {
            description("Threshold k must be bigger than or equal to 2")
            display("Threshold k must be bigger than or equal to 2, got: k = {}", k)
        }

        SecretTooBig(len: usize, max: usize) {
            description("The secret is too long")
            display("The secret is too long, maximum allowed size = {} bytes, got {} bytes", max, len)
        }

        InvalidShareCountMax(nb_shares: u8, max: u8) {
            description("Number of shares is too big")
            display("Number of shares must be smaller than or equal {}, got: {} shares.", max, nb_shares)
        }

        InvalidShareCountMin(nb_shares: u8, min: u8) {
            description("Number of shares is too small")
            display("Number of shares must be larger than or equal {}, got: {} shares.", min, nb_shares)
        }

        EmptySecret {
            description("The secret cannot be empty")
            display("The secret cannot be empty")
        }

        EmptyShares {
            description("No shares provided")
            display("No shares were provided.")
        }

        IncompatibleSets(sets: Vec<HashSet<u8>>) {
            description("The shares are incompatible with each other.")
            display("The shares are incompatible with each other.")
        }

        MissingShares(provided: usize, required: u8) {
            description("The number of shares provided is insufficient to recover the secret.")
            display("{} shares are required to recover the secret, found only {}.", required, provided)
        }

        InvalidSignature(share_id: u8, signature: String) {
            description("The signature of this share is not valid.")
        }

        MissingSignature(share_id: u8) {
            description("Signature is missing while shares are required to be signed.")
        }

        SecretDeserializationError {
            description("An issue was encountered deserializing the secret. \
                         Updating to the latest version of RustySecrets might help fix this.")
        }

        ShareParsingError(reason: String) {
            description("This share is incorrectly formatted.")
            display("This share is incorrectly formatted. Reason: {}", reason)
        }

        ShareParsingErrorEmptyShare(share_id: u8) {
            description("This share is empty.")
            display("Found empty share for share identifier ({})", share_id)
        }

        ShareParsingInvalidShareId(share_id: u8) {
            description("Invalid share identifier.")
            display("Found invalid share identifier ({})", share_id)
        }

        ShareParsingInvalidShareThreshold(k: u8, id: u8) {
            description("Threshold k must be bigger than or equal to 2")
            display("Threshold k must be bigger than or equal to 2. Got k = {} for share identifier {}.", k, id)
        }

        InvalidSS1Parameters(r: usize, s: usize) {
            description("Invalid parameters for the SS1 sharing scheme")
            display("Invalid parameters for the SS1 sharing scheme: r = {}, s = {}.", r, s)
        }

        InvalidSplitParametersZero(k: u8, n: u8) {
            description("Parameters k and n must be greater than zero")
            display("Parameters k and n must be greater than zero.")
        }

        #[cfg(feature = "dss")]
        MismatchingShares(got: ss1::Share, expected: ss1::Share) {
            description("Share mismatch during verification of secret recovery")
            display("Share mismatch during verification of secret recovery.")
        }

        CannotGenerateRandomNumbers {
            description("Cannot generate random numbers")
            display("Cannot generate random numbers.")
        }

        DuplicateShareId(share_id: u8) {
            description("This share number has already been used by a previous share.")
            display("This share number ({}) has already been used by a previous share.", share_id)
        }

        InconsistentSecretLengths(id: u8, slen_: usize, ids: Vec<u8>, slen: usize) {
            description("The shares are incompatible with each other because they do not all have the same secret length.")
            display("The share identifier {} had secret length {}, while the secret length {} was found for share identifier(s): {:?}.", id, slen_, slen, ids)
        }

        InconsistentShares {
            description("The shares are inconsistent")
            display("The shares are inconsistent")
        }

        InconsistentThresholds(id: u8, k_: u8, ids: Vec<u8>, k: u8) {
            description("The shares are incompatible with each other because they do not all have the same threshold.")
            display("The share identifier {} had k = {}, while k = {} was found for share identifier(s): {:?}.", id, k_, k, ids)
        }

    }

    foreign_links {
        Io(::std::io::Error);
        IntegerParsingError(::std::num::ParseIntError);
    }
}
<commit_msg>Adds `no_more_than_five` formatter<commit_after>//! Define the various error kinds specific to deterministic secret sharing.

#![allow(unknown_lints, missing_docs)]

use std::collections::HashSet;
use std::fmt;

#[cfg(feature = "dss")]
use dss::ss1;

/// Minimum allowed number of shares (n)
pub(crate) static MIN_SHARES: u8 = 2;
/// Minimum allowed threshold (k)
pub(crate) static MIN_THRESHOLD: u8 = 2;
/// Maximum allowed number of shares (k,n)
pub(crate) static MAX_SHARES: u8 = 255;
/// SSS Shares should be structured as k-n-data hence 3 parts
pub(crate) static SSS_SHARE_PARTS_COUNT: usize = 3;

/// Create the Error, ErrorKind, ResultExt, and Result types
error_chain! {
    errors {
        ThresholdTooBig(k: u8, n: u8) {
            description("Threshold k must be smaller than or equal to n")
            display("Threshold k must be smaller than or equal to n, got: k = {}, n = {}.", k, n)
        }

        ThresholdTooSmall(k: u8) {
            description("Threshold k must be bigger than or equal to 2")
            display("Threshold k must be bigger than or equal to 2, got: k = {}", k)
        }

        SecretTooBig(len: usize, max: usize) {
            description("The secret is too long")
            display("The secret is too long, maximum allowed size = {} bytes, got {} bytes", max, len)
        }

        InvalidShareCountMax(nb_shares: u8, max: u8) {
            description("Number of shares is too big")
            display("Number of shares must be smaller than or equal {}, got: {} shares.", max, nb_shares)
        }

        InvalidShareCountMin(nb_shares: u8, min: u8) {
            description("Number of shares is too small")
            display("Number of shares must be larger than or equal {}, got: {} shares.", min, nb_shares)
        }

        EmptySecret {
            description("The secret cannot be empty")
            display("The secret cannot be empty")
        }

        EmptyShares {
            description("No shares provided")
            display("No shares were provided.")
        }

        IncompatibleSets(sets: Vec<HashSet<u8>>) {
            description("The shares are incompatible with each other.")
            display("The shares are incompatible with each other.")
        }

        MissingShares(provided: usize, required: u8) {
            description("The number of shares provided is insufficient to recover the secret.")
            display("{} shares are required to recover the secret, found only {}.", required, provided)
        }

        InvalidSignature(share_id: u8, signature: String) {
            description("The signature of this share is not valid.")
        }

        MissingSignature(share_id: u8) {
            description("Signature is missing while shares are required to be signed.")
        }

        SecretDeserializationError {
            description("An issue was encountered deserializing the secret. \
                         Updating to the latest version of RustySecrets might help fix this.")
        }

        ShareParsingError(reason: String) {
            description("This share is incorrectly formatted.")
            display("This share is incorrectly formatted. Reason: {}", reason)
        }

        ShareParsingErrorEmptyShare(share_id: u8) {
            description("This share is empty.")
            display("Found empty share for share identifier ({})", share_id)
        }

        ShareParsingInvalidShareId(share_id: u8) {
            description("Invalid share identifier.")
            display("Found invalid share identifier ({})", share_id)
        }

        ShareParsingInvalidShareThreshold(k: u8, id: u8) {
            description("Threshold k must be bigger than or equal to 2")
            display("Threshold k must be bigger than or equal to 2. Got k = {} for share identifier {}.", k, id)
        }

        InvalidSS1Parameters(r: usize, s: usize) {
            description("Invalid parameters for the SS1 sharing scheme")
            display("Invalid parameters for the SS1 sharing scheme: r = {}, s = {}.", r, s)
        }

        InvalidSplitParametersZero(k: u8, n: u8) {
            description("Parameters k and n must be greater than zero")
            display("Parameters k and n must be greater than zero.")
        }

        #[cfg(feature = "dss")]
        MismatchingShares(got: ss1::Share, expected: ss1::Share) {
            description("Share mismatch during verification of secret recovery")
            display("Share mismatch during verification of secret recovery.")
        }

        CannotGenerateRandomNumbers {
            description("Cannot generate random numbers")
            display("Cannot generate random numbers.")
        }

        DuplicateShareId(share_id: u8) {
            description("This share number has already been used by a previous share.")
            display("This share number ({}) has already been used by a previous share.", share_id)
        }

        InconsistentSecretLengths(id: u8, slen_: usize, ids: Vec<u8>, slen: usize) {
            description("The shares are incompatible with each other because they do not all have the same secret length.")
            display("The share identifier {} had secret length {}, while the secret length {} was found for share identifier(s): {}.", id, slen_, slen, no_more_than_five(ids))
        }

        InconsistentShares {
            description("The shares are inconsistent")
            display("The shares are inconsistent")
        }

        InconsistentThresholds(id: u8, k_: u8, ids: Vec<u8>, k: u8) {
            description("The shares are incompatible with each other because they do not all have the same threshold.")
            display("The share identifier {} had k = {}, while k = {} was found for share identifier(s): {}.", id, k_, k, no_more_than_five(ids))
        }

    }

    foreign_links {
        Io(::std::io::Error);
        IntegerParsingError(::std::num::ParseIntError);
    }
}

/// Takes a `Vec<T>` and formats it like the normal `fmt::Debug` implementation, unless it has more
//than five elements, in which case the rest are replaced by ellipsis.
fn no_more_than_five<T: fmt::Debug + fmt::Display>(vec: &Vec<T>) -> String {
    let len = vec.len();
    if len > 5 {
        let mut string = String::from("[");
        for item in vec.iter().take(5) {
            string += &format!("{}, ", item);
        }
        string.push_str("...]");
        string
    } else {
        format!("{:?}", vec)
    }
}
<|endoftext|>


<commit_before>use hyper;
use std::convert::From;
use rustc_serialize::json;
use std::num::ParseIntError;

#[derive(Debug)]
// TODO FIXME
/// Errors that can occur in this crate
pub enum HueError {
    /// Error that occurs when the response from the bridge is malformed
    MalformedResponse,
    /// An error that occured in the bridge
    BridgeError{
        /// The URI the error happened on
        address: String,
        /// The `BridgeError`
        error: BridgeError
    },
    /// A `json::EncoderError`
    EncoderError(json::EncoderError),
    /// A `json::DecoderError`
    DecoderError(json::DecoderError),
    /// A `json::ParserError`
    ParserError(json::ParserError),
    /// A `hyper::Error`
    HyperError(hyper::Error),
    /// An `std::num::ParseIntError`
    ParseIntError(ParseIntError)
}

/// All errors defined in [http://www.developers.meethue.com/documentation/error-messages]
#[repr(u16)]
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone)]
pub enum BridgeError{
    // Generic Errors
    UnauthorizedUser = 1,
    BodyContainsInvalidJSON = 2,
    ResourceNotAvailable = 3,
    MethodNotAvailableForResource = 4,
    MissingParametersInBody = 5,
    ParameterNotAvailable = 6,
    InvalidValueForParameter = 7,
    ParameterIsNotModifiable = 8,
    TooManyItemsInList = 11,
    ProtalConnectionRequired = 12,
    InternalError = 901,

    // Command Specific Errors
    LinkButtonNotPressed = 101,
    DHCPCannotBeDisabled = 110,
    InvalidUpdateState = 111,
    // TODO add the rest of the command specific errors
    Other
}

use std::mem::transmute;

impl From<::hue::Error> for HueError {
    fn from(::hue::Error{address, code,..}: ::hue::Error) -> Self {
        HueError::BridgeError{
            address: address,
            error: unsafe{transmute(code)}
        }
    }
}

impl From<json::EncoderError> for HueError {
    fn from(err: json::EncoderError) -> HueError {
        HueError::EncoderError(err)
    }
}

impl From<json::DecoderError> for HueError {
    fn from(err: json::DecoderError) -> HueError {
        HueError::DecoderError(err)
    }
}

impl From<json::ParserError> for HueError {
    fn from(err: json::ParserError) -> HueError {
        HueError::ParserError(err)
    }
}

impl From<hyper::error::Error> for HueError {
    fn from(err: hyper::error::Error) -> HueError {
        HueError::HyperError(err)
    }
}

impl From<ParseIntError> for HueError {
    fn from(err: ParseIntError) -> HueError {
        HueError::ParseIntError(err)
    }
}
<commit_msg>Complete `BridgeError`<commit_after>use hyper;
use std::convert::From;
use rustc_serialize::json;
use std::num::ParseIntError;

#[derive(Debug)]
// TODO FIXME
/// Errors that can occur in this crate
pub enum HueError {
    /// Error that occurs when the response from the bridge is malformed
    MalformedResponse,
    /// An error that occured in the bridge
    BridgeError{
        /// The URI the error happened on
        address: String,
        /// The `BridgeError`
        error: BridgeError
    },
    /// A `json::EncoderError`
    EncoderError(json::EncoderError),
    /// A `json::DecoderError`
    DecoderError(json::DecoderError),
    /// A `json::ParserError`
    ParserError(json::ParserError),
    /// A `hyper::Error`
    HyperError(hyper::Error),
    /// An `std::num::ParseIntError`
    ParseIntError(ParseIntError)
}

macro_rules! error_enum {
    (
        $(#[$meta:meta])*
        pub enum $name:ident{
            $($err:ident = $n:expr),+;
            $other:ident
        }
    ) => (
        $(#[$meta])*
        pub enum $name{
            $($err = $n,)+
            $other
        }
        impl From<u16> for $name{
            fn from(n: u16) -> Self{
                match n {
                    $($n => $name::$err,)+
                    _ => $name::$other
                }
            }
        }
    );
}

error_enum!{
    /// All errors defined in http://www.developers.meethue.com/documentation/error-messages
    #[repr(u16)]
    #[allow(missing_docs)]
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub enum BridgeError{
        // Generic Errors
        UnauthorizedUser = 1,
        BodyContainsInvalidJson = 2,
        ResourceNotAvailable = 3,
        MethodNotAvailableForResource = 4,
        MissingParametersInBody = 5,
        ParameterNotAvailable = 6,
        InvalidValueForParameter = 7,
        ParameterIsNotModifiable = 8,
        TooManyItemsInList = 11,
        ProtalConnectionRequired = 12,
        InternalError = 901,

        // Command Specific Errors
        LinkButtonNotPressed = 101,
        DHCPCannotBeDisabled = 110,
        InvalidUpdateState = 111,
        DeviceIsSetToOff = 201,
        GroupCouldNotBeCreatedGroupFull = 301,
        DeviceCouldNotBeAddedGroupFull = 302,
        DeviceIsUnreachable = 304,
        UpdateOrDeleteGroupOfThisTypeNotAllowed = 305,
        LightAlreadyUsed = 306,
        SceneCouldNotBeCreated = 401,
        SceneCouldNotBeCreatedBufferFull = 402,
        SceneCouldNotBeRemoved = 403,
        NotAllowedToCreateSensorType = 501,
        SensorListIsFull = 502,
        RuleEngineFull = 601,
        ConditionError = 607,
        ActionError = 608,
        UnableToActivae = 609,
        ScheduleListIsFull = 701,
        ScheduleTimezoneNotValid = 702,
        ScheduleCannotSetTimeAndLocalTime = 703,
        CannotCreateSchedule = 704,
        CannotEnableScheduleTimeInPast = 705,
        CommandError = 706,
        SourceModelInvalid = 801,
        SourceFactoryNew = 802,
        InvalidState = 803;
        Other
    }
}

#[test]
fn bride_errors() {
    use self::BridgeError::*;

    assert_eq!(BridgeError::from(101), LinkButtonNotPressed);
    assert_eq!(BridgeError::from(0), Other);
    assert_eq!(BridgeError::from(51234), Other);
    assert_eq!(BridgeError::from(4), MethodNotAvailableForResource);
    assert_eq!(SceneCouldNotBeRemoved as u16, 403);
    assert_eq!(InternalError as u16, 901);
}

impl From<::hue::Error> for HueError {
    fn from(::hue::Error{address, code,..}: ::hue::Error) -> Self {
        HueError::BridgeError{
            address: address,
            error: From::from(code)
        }
    }
}

impl From<json::EncoderError> for HueError {
    fn from(err: json::EncoderError) -> HueError {
        HueError::EncoderError(err)
    }
}

impl From<json::DecoderError> for HueError {
    fn from(err: json::DecoderError) -> HueError {
        HueError::DecoderError(err)
    }
}

impl From<json::ParserError> for HueError {
    fn from(err: json::ParserError) -> HueError {
        HueError::ParserError(err)
    }
}

impl From<hyper::error::Error> for HueError {
    fn from(err: hyper::error::Error) -> HueError {
        HueError::HyperError(err)
    }
}

impl From<ParseIntError> for HueError {
    fn from(err: ParseIntError) -> HueError {
        HueError::ParseIntError(err)
    }
}
<|endoftext|>


<commit_before>

//use std::dynamic_lib::DynamicLibrary;
//const SYSTEM_C_LIBRARY: &'static str = "libc.so.6";
//unsafe impl Sync for DynamicLibrary { }
//unsafe impl Send for DynamicLibrary { }

use std::sync::RwLock;
use std::hash::{Hasher, SipHasher};
use std::collections::hash_set::HashSet;
use std::collections::hash_state::DefaultState;
lazy_static! {
    pub static ref DELAY_FDS: RwLock<HashSet<c_int, DefaultState<SipHasher>>>
                                                = RwLock::new(Default::default());
    pub static ref ERR_FDS: RwLock<HashSet<c_int, DefaultState<SipHasher>>>
                                                = RwLock::new(Default::default());
    //static ref LIBC: RwLock<DynamicLibrary> = RwLock::new(DynamicLibrary::open(Some(Path::new(SYSTEM_C_LIBRARY))).unwrap());
}

macro_rules! get_libc_func(
    ($destination_t:ty, $funcname:expr) =>
        (
            {
                use std::dynamic_lib::DynamicLibrary;
                use std::mem::transmute;
                use std::path::Path;

                const SYSTEM_C_LIBRARY: &'static str = "libc.so.6";

                unsafe {
                    let libc_dl = match DynamicLibrary::open(Some(Path::new(SYSTEM_C_LIBRARY))) {
                        Ok(libc) => libc,
                        Err(error) => panic!("Couldn't open libc: '{}'", error),
                    };

                    match libc_dl.symbol::<c_void>($funcname) {
                        Ok(open_func) => transmute::<* mut c_void, $destination_t>(open_func),
                        Err(error) => panic!("Couldn't find '{}': '{}'", $funcname, error),
                }
            }
        })
);

pub use libc::{c_char, c_int, c_void, off_t, size_t,mode_t};
pub use libc::types::os::arch::posix88::ssize_t;

pub type OpenFunc = extern "C" fn(* const c_char, c_int, mode_t) -> c_int;
pub type ReadFunc = extern "C" fn(fd: c_int, buf: * mut c_void, nbytes: c_int) -> ssize_t;
pub type WriteFunc = ReadFunc;
pub type MmapFunc = extern "C" fn(addr: *mut c_void, length_: size_t, prot: c_int,
                   flags: c_int, fd: c_int, offset: off_t) -> *mut c_void;
pub type CloseFunc = extern "C" fn(fd: c_int) -> c_int;
pub type SeekFunc = extern "C" fn(c_int, off_t, c_int) -> off_t;
pub type Dup2Func = extern "C" fn(c_int, c_int) -> c_int;

macro_rules! get_delay_amount_ms(
        ($funcname: expr) =>
    ({
        const DEFAULT_DELAY_AMOUNT_MS: u32 = 200;
        let err_prefix = "LIBFAULTINJ_DELAY_".to_string();
        let env_name = err_prefix + &String::from($funcname).to_uppercase() + "_MS";

        match std::env::var(env_name) {
            Ok(p) => match p.parse::<u32>() {
                Ok(i) => i,
                Err(_) => DEFAULT_DELAY_AMOUNT_MS,
            },
            Err(_) => DEFAULT_DELAY_AMOUNT_MS,
        }
    })
);

macro_rules! checkErrno(
    ($funcname: expr) =>
    ({
        use errno::Errno;
        use std::string::String;

        let err_prefix = "LIBFAULTINJ_ERROR_".to_string();
        let env_name = err_prefix + &String::from($funcname).to_uppercase() + "_ERRNO";

        match std::env::var(env_name) {
            Ok(p) => match p.parse::<i32>() {
                Ok(i) => Some(Errno(i)),
                Err(_) => None,
            },
            Err(_) => None,
        }
    })
);

macro_rules! returnError(
        ($fd: expr, $funcname:expr, $err:expr) =>
    ({
        use rand::Rng;
        use errno::set_errno;

        const LIKELIHOOD_CERTAIN_PCT: f32 = 100f32;

        if ERR_FDS.read().unwrap().contains(&$fd) {
            let err_thresh = match std::env::var("LIBFAULTINJ_ERROR_LIKELIHOOD_PCT") {
                Ok(p) => match p.parse::<f32>() {
                    Ok(i) => i,
                    Err(_) => LIKELIHOOD_CERTAIN_PCT,
                },
                Err(_) => LIKELIHOOD_CERTAIN_PCT,
            };
            let mut rng = rand::thread_rng();
            let rand_val = rng.gen_range::<f32>(0., LIKELIHOOD_CERTAIN_PCT);

            if  rand_val < (err_thresh) {
                let errno = checkErrno!($funcname);

                if errno.is_some() {
                    set_errno(errno.unwrap());
                    return $err;
                }

            };
        }
    })
);

macro_rules! injectFaults(
        ($fd: expr, $funcname:expr, $err:expr) =>
        ({
            use std::thread;

            let delay_match = DELAY_FDS.read().unwrap().contains(&$fd);

            if delay_match {
                thread::sleep_ms(get_delay_amount_ms!($funcname));
            }

            returnError!($fd, $funcname, $err);
        }));

/**
 * @return true if $filename is located within the path specified by
 *      std::env::var($env_name), false otherwise.
 */
macro_rules! matchesPath(
        ($filename: expr, $env_name: expr) =>
    (
    {
        use std::path::Path;

        match std::env::var($env_name) {
            Ok(p) => {
                let filename_path = Path::new(&$filename);
                let delay_path_match = (filename_path.relative_from(Path::new(&p))) != None;
                let filename_match = filename_path == Path::new(&p);

                delay_path_match || filename_match
            }
            Err(_) => false
        }
    }));

macro_rules! do_open(
    ($filename_:expr, $flags:expr, $mode:expr) =>
    ({
        let filename: String = unsafe {
            std::ffi::CStr::from_ptr($filename_).to_string_lossy().into_owned()
        };
        let open_func = get_libc_func!(OpenFunc, "open");
        let fd: c_int = open_func($filename_, $flags, $mode);

        if matchesPath!(filename, "LIBFAULTINJ_ERROR_PATH") {
            ERR_FDS.write().unwrap().insert(fd);
        }

        if matchesPath!(filename, "LIBFAULTINJ_DELAY_PATH") {
            DELAY_FDS.write().unwrap().insert(fd);
        }

        const INVALID_FD: c_int = -1;
        returnError!(fd, "open", INVALID_FD);

        fd
    })
    );

pub fn remove_fd_if_present(fd: c_int) {
    let mut err_fds = ERR_FDS.write().unwrap();
    if err_fds.contains(&fd) {
        err_fds.remove(&fd);
    }

    let mut delay_fds = DELAY_FDS.write().unwrap();
    if delay_fds.contains(&fd) {
        delay_fds.remove(&fd);
    }

}

pub fn add_fd_if_old_present(oldfd: c_int, newfd: c_int) {
    let mut err_fds = ERR_FDS.write().unwrap();
    if err_fds.contains(&oldfd) {
        err_fds.insert(newfd);
    }

    let mut delay_fds = DELAY_FDS.write().unwrap();
    if delay_fds.contains(&oldfd) {
        delay_fds.insert(newfd);
    }

}
<commit_msg>More test cases<commit_after>

//use std::dynamic_lib::DynamicLibrary;
//const SYSTEM_C_LIBRARY: &'static str = "libc.so.6";
//unsafe impl Sync for DynamicLibrary { }
//unsafe impl Send for DynamicLibrary { }

use std::sync::RwLock;
use std::hash::{Hasher, SipHasher};
use std::collections::hash_set::HashSet;
use std::collections::hash_state::DefaultState;
lazy_static! {
    pub static ref DELAY_FDS: RwLock<HashSet<c_int, DefaultState<SipHasher>>>
                                                = RwLock::new(Default::default());
    pub static ref ERR_FDS: RwLock<HashSet<c_int, DefaultState<SipHasher>>>
                                                = RwLock::new(Default::default());
    //static ref LIBC: RwLock<DynamicLibrary> = RwLock::new(DynamicLibrary::open(Some(Path::new(SYSTEM_C_LIBRARY))).unwrap());
}

macro_rules! get_libc_func(
    ($destination_t:ty, $funcname:expr) =>
        (
            {
                use std::dynamic_lib::DynamicLibrary;
                use std::mem::transmute;
                use std::path::Path;

                const SYSTEM_C_LIBRARY: &'static str = "libc.so.6";

                unsafe {
                    let libc_dl = match DynamicLibrary::open(Some(Path::new(SYSTEM_C_LIBRARY))) {
                        Ok(libc) => libc,
                        Err(error) => panic!("Couldn't open libc: '{}'", error),
                    };

                    match libc_dl.symbol::<c_void>($funcname) {
                        Ok(open_func) => transmute::<* mut c_void, $destination_t>(open_func),
                        Err(error) => panic!("Couldn't find '{}': '{}'", $funcname, error),
                }
            }
        })
);

pub use libc::{c_char, c_int, c_void, off_t, size_t,mode_t};
pub use libc::types::os::arch::posix88::ssize_t;

pub type OpenFunc = extern "C" fn(* const c_char, c_int, mode_t) -> c_int;
pub type ReadFunc = extern "C" fn(fd: c_int, buf: * mut c_void, nbytes: c_int) -> ssize_t;
pub type WriteFunc = ReadFunc;
pub type MmapFunc = extern "C" fn(addr: *mut c_void, length_: size_t, prot: c_int,
                   flags: c_int, fd: c_int, offset: off_t) -> *mut c_void;
pub type CloseFunc = extern "C" fn(fd: c_int) -> c_int;
pub type SeekFunc = extern "C" fn(c_int, off_t, c_int) -> off_t;
pub type Dup2Func = extern "C" fn(c_int, c_int) -> c_int;

macro_rules! get_delay_amount_ms(
        ($funcname: expr) =>
    ({
        use std::env;

        const DEFAULT_DELAY_AMOUNT_MS: u32 = 200;
        let err_prefix = "LIBFAULTINJ_DELAY_".to_string();
        let env_name = err_prefix + &String::from($funcname).to_uppercase() + "_MS";

        match env::var(env_name) {
            Ok(p) => match p.parse::<u32>() {
                Ok(i) => i,
                Err(_) => DEFAULT_DELAY_AMOUNT_MS,
            },
            Err(_) => DEFAULT_DELAY_AMOUNT_MS,
        }
    })
);

macro_rules! checkErrno(
    ($funcname: expr) =>
    ({
        use errno::Errno;
        use std::string::String;
        use std::env;

        let err_prefix = "LIBFAULTINJ_ERROR_".to_string();
        let env_name = err_prefix + &String::from($funcname).to_uppercase() + "_ERRNO";

        match env::var(env_name) {
            Ok(p) => match p.parse::<i32>() {
                Ok(i) => Some(Errno(i)),
                Err(_) => None,
            },
            Err(_) => None,
        }
    })
);

macro_rules! returnError(
        ($fd: expr, $funcname:expr, $err:expr) =>
    ({
        use rand::Rng;
        use errno::set_errno;

        const LIKELIHOOD_CERTAIN_PCT: f32 = 100f32;

        if ERR_FDS.read().unwrap().contains(&$fd) {
            let err_thresh = match std::env::var("LIBFAULTINJ_ERROR_LIKELIHOOD_PCT") {
                Ok(p) => match p.parse::<f32>() {
                    Ok(i) => i,
                    Err(_) => LIKELIHOOD_CERTAIN_PCT,
                },
                Err(_) => LIKELIHOOD_CERTAIN_PCT,
            };
            let mut rng = rand::thread_rng();
            let rand_val = rng.gen_range::<f32>(0., LIKELIHOOD_CERTAIN_PCT);

            if  rand_val < (err_thresh) {
                let errno = checkErrno!($funcname);

                if errno.is_some() {
                    set_errno(errno.unwrap());
                    return $err;
                }

            };
        }
    })
);

macro_rules! injectFaults(
        ($fd: expr, $funcname:expr, $err:expr) =>
        ({
            use std::thread;

            let delay_match = DELAY_FDS.read().unwrap().contains(&$fd);

            if delay_match {
                thread::sleep_ms(get_delay_amount_ms!($funcname));
            }

            returnError!($fd, $funcname, $err);
        }));

/**
 * @return true if $filename is located within the path specified by
 *      std::env::var($env_name), false otherwise.
 */
macro_rules! matchesPath(
        ($filename: expr, $env_name: expr) =>
    (
    {
        use std::path::Path;
        use std::env;

        match env::var($env_name) {
            Ok(p) => {
                let filename_path = Path::new(&$filename);
                let delay_path_match = (filename_path.relative_from(Path::new(&p))) != None;
                let filename_match = filename_path == Path::new(&p);

                delay_path_match || filename_match
            }
            Err(_) => false
        }
    }));

macro_rules! do_open(
    ($filename_:expr, $flags:expr, $mode:expr) =>
    ({
        let filename: String = unsafe {
            std::ffi::CStr::from_ptr($filename_).to_string_lossy().into_owned()
        };
        let open_func = get_libc_func!(OpenFunc, "open");
        let fd: c_int = open_func($filename_, $flags, $mode);

        if matchesPath!(filename, "LIBFAULTINJ_ERROR_PATH") {
            ERR_FDS.write().unwrap().insert(fd);
        }

        if matchesPath!(filename, "LIBFAULTINJ_DELAY_PATH") {
            DELAY_FDS.write().unwrap().insert(fd);
        }

        const INVALID_FD: c_int = -1;
        returnError!(fd, "open", INVALID_FD);

        fd
    })
    );

pub fn remove_fd_if_present(fd: c_int) {
    let mut err_fds = ERR_FDS.write().unwrap();
    if err_fds.contains(&fd) {
        err_fds.remove(&fd);
    }

    let mut delay_fds = DELAY_FDS.write().unwrap();
    if delay_fds.contains(&fd) {
        delay_fds.remove(&fd);
    }

}

pub fn add_fd_if_old_present(oldfd: c_int, newfd: c_int) {
    let mut err_fds = ERR_FDS.write().unwrap();
    if err_fds.contains(&oldfd) {
        err_fds.insert(newfd);
    }

    let mut delay_fds = DELAY_FDS.write().unwrap();
    if delay_fds.contains(&oldfd) {
        delay_fds.insert(newfd);
    }

}

#[cfg(test)]
mod test {
    use std::env;
    use std::path::Path;

    #[test]
    fn test_delay() {

        assert_eq!(get_delay_amount_ms!("open"), 200);

        assert_eq!(get_delay_amount_ms!("read"), 200);

        env::set_var("LIBFAULTINJ_DELAY_READ_MS", "99bogus");
        assert_eq!(get_delay_amount_ms!("read"), 200);

        env::set_var("LIBFAULTINJ_DELAY_READ_MS", "99");
        assert_eq!(get_delay_amount_ms!("read"), 99);
    }

    #[test]
    fn test_path() {
        let base = ".";
        let base_path = Path::new(&base);
        assert!(!matchesPath!(base, "LIBFAULTINJ_ERROR_PATH"));

        env::set_var("LIBFAULTINJ_ERROR_PATH", ".");
        assert!(matchesPath!(base, "LIBFAULTINJ_ERROR_PATH"));

        let foo_path = base_path.join("foo");
        assert!(matchesPath!(foo_path, "LIBFAULTINJ_ERROR_PATH"));

        let bar_path = base_path.join("bar");
        env::set_var("LIBFAULTINJ_ERROR_PATH", bar_path.to_str().unwrap());

        assert!(!matchesPath!(foo_path, "LIBFAULTINJ_ERROR_PATH"));

        let bar_x_path = bar_path.join("x");
        assert!(matchesPath!(bar_x_path, "LIBFAULTINJ_ERROR_PATH"));

        let bard_path = base_path.join("bard");
        assert!(!matchesPath!(bard_path, "LIBFAULTINJ_ERROR_PATH"));

        let bard_x_path = bard_path.join("x");
        assert!(!matchesPath!(bard_x_path, "LIBFAULTINJ_ERROR_PATH"));
    }
}
<|endoftext|>


<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/. */

extern crate mio;

use service::ServiceID;

pub enum EventData {
    AdapterStart { name: String },
    ServiceStart { id: ServiceID },
    ServiceStop { id: ServiceID }
}

impl EventData {
    pub fn description(&self) -> String {
        #![allow(match_same_arms)]
        let description = match *self {
            EventData::AdapterStart { ref name } => name,
            EventData::ServiceStart { ref id } => id,
            EventData::ServiceStop { ref id } => id
        };

        description.to_string()
    }
}

pub type EventSender = mio::Sender<EventData>;

describe! event_data {
    it "AdapterStart should return its name as a description" {
        let data = EventData::AdapterStart { name: "name".to_owned() };
        assert_eq!(data.description(), "name");
    }

    it "ServiceStart should return its ID as a description" {
        let data = EventData::ServiceStart { id: "id".to_owned() };
        assert_eq!(data.description(), "id");
    }

    // TODO Factorize this test with the one above once there's a way to loop over a random emum.
    // https://github.com/rust-lang/rfcs/issues/284
    it "ServiceStop should return its ID as a description" {
        let data = EventData::ServiceStop { id: "id".to_owned() };
        assert_eq!(data.description(), "id");
    }
}
<commit_msg>Make code compliant with clippy's new rules<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/. */

extern crate mio;

use service::ServiceID;

pub enum EventData {
    AdapterStart { name: String },
    ServiceStart { id: ServiceID },
    ServiceStop { id: ServiceID }
}

impl EventData {
    pub fn description(&self) -> String {
        let description = match *self {
            EventData::AdapterStart { ref name } => name,
            EventData::ServiceStart { ref id }
            | EventData::ServiceStop { ref id } => id,
        };

        description.to_string()
    }
}

pub type EventSender = mio::Sender<EventData>;

describe! event_data {
    it "AdapterStart should return its name as a description" {
        let data = EventData::AdapterStart { name: "name".to_owned() };
        assert_eq!(data.description(), "name");
    }

    it "ServiceStart should return its ID as a description" {
        let data = EventData::ServiceStart { id: "id".to_owned() };
        assert_eq!(data.description(), "id");
    }

    // TODO Factorize this test with the one above once there's a way to loop over a random emum.
    // https://github.com/rust-lang/rfcs/issues/284
    it "ServiceStop should return its ID as a description" {
        let data = EventData::ServiceStop { id: "id".to_owned() };
        assert_eq!(data.description(), "id");
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(non_snake_case)]

use from_json;
use serialize;
use std::collections::HashMap;

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Document {
    pub bones: Option<Vec<Bone>>,
    pub slots: Option<Vec<Slot>>,
    pub skins: Option<HashMap<String, HashMap<String, HashMap<String, Attachment>>>>,
    pub animations: Option<HashMap<String, Animation>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Bone {
    pub name: String,
    pub parent: Option<String>,
    pub length: Option<f64>,
    pub x: Option<f64>,
    pub y: Option<f64>,
    pub scaleX: Option<f64>,
    pub scaleY: Option<f64>,
    pub rotation: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Slot {
    pub name: String,
    pub bone: String,
    pub color: Option<String>,
    pub attachment: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Attachment {
    pub name: Option<String>,
    #[from_json_name = "type"]
    pub type_: Option<AttachmentType>,
    pub x: Option<f64>,
    pub y: Option<f64>,
    pub scaleX: Option<f64>,
    pub scaleY: Option<f64>,
    pub rotation: Option<f64>,
    pub width: Option<f64>,
    pub height: Option<f64>,
    pub fps: Option<f64>,
    pub mode: Option<f64>,
    //vertices: Option<Vec<??>>     // TODO: ?
}

#[deriving(Show, Clone)]
pub enum AttachmentType {
    Region,
    RegionSequence,
    BoundingBox,
}

impl from_json::FromJson for AttachmentType {
    fn from_json(input: &serialize::json::Json) -> Result<AttachmentType, from_json::FromJsonError> {
        use from_json::FromJson;

        let string: String = try!(FromJson::from_json(input));

        match string.as_slice() {
            "region" => Ok(Region),
            "regionsequence" => Ok(RegionSequence),
            "boundingbox" => Ok(BoundingBox),
            _ => Err(from_json::ExpectError("AttachmentType", input.clone()))
        }
    }
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Event {
    pub name: String,
    #[from_json_name = "int"]
    pub int_: Option<int>,
    #[from_json_name = "float"]
    pub float_: Option<f64>,
    pub string: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Animation {
    pub bones: Option<HashMap<String, BoneTimeline>>,
    pub slots: Option<HashMap<String, SlotTimeline>>,
    pub events: Option<Vec<EventKeyframe>>,
    pub draworder: Option<Vec<DrawOrderTimeline>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneTimeline {
    pub translate: Option<Vec<BoneTranslateTimeline>>,
    pub rotate: Option<Vec<BoneRotateTimeline>>,
    pub scale: Option<Vec<BoneScaleTimeline>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneTranslateTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub x: Option<f64>,
    pub y: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneRotateTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub angle: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneScaleTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub x: Option<f64>,
    pub y: Option<f64>,
}

#[deriving(Show, Clone)]
pub enum TimelineCurve {
    CurveBezier(Vec<f64>),
    CurvePredefined(String),
}

impl from_json::FromJson for TimelineCurve {
    fn from_json(input: &serialize::json::Json) -> Result<TimelineCurve, from_json::FromJsonError> {
        use from_json::FromJson;

        if input.is_list() {
            Ok(CurveBezier(try!(FromJson::from_json(input))))
        } else {
            Ok(CurvePredefined(try!(FromJson::from_json(input))))
        }
    }
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotTimeline {
    pub attachment: Option<SlotAttachmentTimeline>,
    pub color: Option<SlotColorTimeline>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotAttachmentTimeline {
    pub time: f64,
    pub name: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotColorTimeline {
    pub time: f64,
    pub color: Option<String>,
    pub curve: Option<TimelineCurve>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct EventKeyframe {
    time: f64,
    name: String,
    #[from_json_name = "int"]
    int_: Option<int>,
    #[from_json_name = "float"]
    float_: Option<f64>,
    #[from_json_name = "string"]
    string_: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct DrawOrderTimeline {
    time: f64,
    offsets: Option<Vec<DrawOrderTimelineOffset>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct DrawOrderTimelineOffset {
    slot: String,
    offset: int,
}
<commit_msg>Fix spine format<commit_after>#![allow(dead_code)]
#![allow(non_snake_case)]

use from_json;
use serialize;
use std::collections::HashMap;

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Document {
    pub bones: Option<Vec<Bone>>,
    pub slots: Option<Vec<Slot>>,
    pub skins: Option<HashMap<String, HashMap<String, HashMap<String, Attachment>>>>,
    pub animations: Option<HashMap<String, Animation>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Bone {
    pub name: String,
    pub parent: Option<String>,
    pub length: Option<f64>,
    pub x: Option<f64>,
    pub y: Option<f64>,
    pub scaleX: Option<f64>,
    pub scaleY: Option<f64>,
    pub rotation: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Slot {
    pub name: String,
    pub bone: String,
    pub color: Option<String>,
    pub attachment: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Attachment {
    pub name: Option<String>,
    #[from_json_name = "type"]
    pub type_: Option<AttachmentType>,
    pub x: Option<f64>,
    pub y: Option<f64>,
    pub scaleX: Option<f64>,
    pub scaleY: Option<f64>,
    pub rotation: Option<f64>,
    pub width: Option<f64>,
    pub height: Option<f64>,
    pub fps: Option<f64>,
    pub mode: Option<f64>,
    //vertices: Option<Vec<??>>     // TODO: ?
}

#[deriving(Show, Clone)]
pub enum AttachmentType {
    Region,
    RegionSequence,
    BoundingBox,
}

impl from_json::FromJson for AttachmentType {
    fn from_json(input: &serialize::json::Json) -> Result<AttachmentType, from_json::FromJsonError> {
        use from_json::FromJson;

        let string: String = try!(FromJson::from_json(input));

        match string.as_slice() {
            "region" => Ok(Region),
            "regionsequence" => Ok(RegionSequence),
            "boundingbox" => Ok(BoundingBox),
            _ => Err(from_json::ExpectError("AttachmentType", input.clone()))
        }
    }
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Event {
    pub name: String,
    #[from_json_name = "int"]
    pub int_: Option<int>,
    #[from_json_name = "float"]
    pub float_: Option<f64>,
    pub string: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct Animation {
    pub bones: Option<HashMap<String, BoneTimeline>>,
    pub slots: Option<HashMap<String, SlotTimeline>>,
    pub events: Option<Vec<EventKeyframe>>,
    pub draworder: Option<Vec<DrawOrderTimeline>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneTimeline {
    pub translate: Option<Vec<BoneTranslateTimeline>>,
    pub rotate: Option<Vec<BoneRotateTimeline>>,
    pub scale: Option<Vec<BoneScaleTimeline>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneTranslateTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub x: Option<f64>,
    pub y: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneRotateTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub angle: Option<f64>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct BoneScaleTimeline {
    pub time: f64,
    pub curve: Option<TimelineCurve>,
    pub x: Option<f64>,
    pub y: Option<f64>,
}

#[deriving(Show, Clone)]
pub enum TimelineCurve {
    CurveBezier(Vec<f64>),
    CurvePredefined(String),
}

impl from_json::FromJson for TimelineCurve {
    fn from_json(input: &serialize::json::Json) -> Result<TimelineCurve, from_json::FromJsonError> {
        use from_json::FromJson;

        if input.is_list() {
            Ok(CurveBezier(try!(FromJson::from_json(input))))
        } else {
            Ok(CurvePredefined(try!(FromJson::from_json(input))))
        }
    }
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotTimeline {
    pub attachment: Option<Vec<SlotAttachmentTimeline>>,
    pub color: Option<Vec<SlotColorTimeline>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotAttachmentTimeline {
    pub time: f64,
    pub name: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct SlotColorTimeline {
    pub time: f64,
    pub color: Option<String>,
    pub curve: Option<TimelineCurve>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct EventKeyframe {
    time: f64,
    name: String,
    #[from_json_name = "int"]
    int_: Option<int>,
    #[from_json_name = "float"]
    float_: Option<f64>,
    #[from_json_name = "string"]
    string_: Option<String>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct DrawOrderTimeline {
    time: f64,
    offsets: Option<Vec<DrawOrderTimelineOffset>>,
}

#[deriving(Show, Clone)]
#[from_json_struct]
pub struct DrawOrderTimelineOffset {
    slot: String,
    offset: int,
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cell::RefCell;

/// Format all iterator elements lazily, separated by `sep`.
///
/// See [`.format()`](trait.Itertools.html#method.format) for more information.
pub struct Format<'a, I, F> {
    sep: &'a str,
    /// Format uses interior mutability because Display::fmt takes &self.
    inner: RefCell<(I, F)>,
}

pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    Format{sep: separator, inner: RefCell::new((iter, f))}
}

impl<'a, I, F> fmt::Display for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut cb = &mut |disp: &fmt::Display| write!(fmt, "{}", disp);
        // the extra *&mut is a workaround for Rust 1.0
        let (ref mut iter, ref mut format)  = *&mut *self.inner.borrow_mut();

        if let Some(fst) = iter.next() {
            try!(format(fst, cb));
            for elt in iter {
                if self.sep.len() > 0 {
                    try!(cb(&self.sep));
                }
                try!(format(elt, cb));
            }
        }
        Ok(())
    }
}

impl<'a, I, F> fmt::Debug for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

<commit_msg>format: Retract the Debug impl, it might be used for debug later<commit_after>use std::fmt;
use std::cell::RefCell;

/// Format all iterator elements lazily, separated by `sep`.
///
/// See [`.format()`](trait.Itertools.html#method.format) for more information.
pub struct Format<'a, I, F> {
    sep: &'a str,
    /// Format uses interior mutability because Display::fmt takes &self.
    inner: RefCell<(I, F)>,
}

pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    Format{sep: separator, inner: RefCell::new((iter, f))}
}

impl<'a, I, F> fmt::Display for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut cb = &mut |disp: &fmt::Display| write!(fmt, "{}", disp);
        // the extra *&mut is a workaround for Rust 1.0
        let (ref mut iter, ref mut format)  = *&mut *self.inner.borrow_mut();

        if let Some(fst) = iter.next() {
            try!(format(fst, cb));
            for elt in iter {
                if self.sep.len() > 0 {
                    try!(cb(&self.sep));
                }
                try!(format(elt, cb));
            }
        }
        Ok(())
    }
}

/*
impl<'a, I, F> fmt::Debug for Format<'a, I, F>
    where I: Iterator,
          F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

*/
<|endoftext|>