<commit_before>extern crate test;

use std::mem;
use std::ptr;
use std::cell::Cell;
use std::num::SignedInt;
use std::ops::Index;
use std::ops::IndexMut;
use test::Bencher;

struct Node<T> {
    prev: *mut Node<T>,
    value: T,
    next: *mut Node<T>
}

pub struct DoublyLinkedList<T> {
    current: Cell<*mut Node<T>>,
    first:   *mut Node<T>,
    last:    *mut Node<T>,
    index:   Cell<isize>,
    length:  usize
}

impl<T> DoublyLinkedList<T> {
    pub fn new_empty() -> DoublyLinkedList<T> {
        DoublyLinkedList {
            current: Cell::new(ptr::null_mut()),
            first:   ptr::null_mut(),
            last:    ptr::null_mut(),
            index:   Cell::new(-1),
            length:  0
        }
    }

    pub fn new_singleton(v: T) -> DoublyLinkedList<T> {
        unsafe {
            let node = Node::new_on_heap(v);
            DoublyLinkedList {
                current: Cell::new(node),
                first:   node,
                last:    node,
                index:   Cell::new(0),
                length:  1
            }
        }
    }

    pub fn len(&self) -> usize {
        self.length
    }

    pub fn front_mut(&mut self) -> Option<&mut T> {
        unsafe { self.first.as_mut().map(|n| { &mut n.value }) }
    }

    pub fn front(&self) -> Option<&T> {
        unsafe { self.first.as_ref().map(|n| { &n.value }) }
    }

    pub fn back_mut(&mut self) -> Option<&mut T> {
        unsafe { self.last.as_mut().map(|n| { &mut n.value }) }
    }

    pub fn back(&self) -> Option<&T> {
        unsafe { self.last.as_ref().map(|n| { &n.value }) }
    }

    pub fn push_back(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::new_singleton(val);
            } else {
                (*(self.last)).next = Node::new_on_heap(val);
                (*(*(self.last)).next).prev = self.last;
                self.last = (*(self.last)).next;
                self.length += 1;
            }
        }
    }

    pub fn push_front(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::new_singleton(val);
            } else {
                (*(self.first)).prev = Node::new_on_heap(val);
                (*(*(self.first)).prev).next = self.first;
                self.first = (*(self.first)).prev;
                self.length += 1;
            }
        }
    }

    fn index(&self, i: usize) -> Option<&T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                if self.length / 2 > i {
                    if (self.index.get() - i as isize).abs() > i as isize {
                        self.go_to_from_start(i);
                    } else {
                        self.go_to(i);
                    }
                } else {
                    if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
                        self.go_to_from_end(i);
                    } else {
                        self.go_to(i);
                    }
                }
                Some(&(*self.current.get()).value)
            }
        }
    }

    fn index_mut(&mut self, i: usize) -> Option<&mut T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                if self.length / 2 > i {
                    if (self.index.get() - i as isize).abs() > i as isize {
                        self.go_to_from_start(i);
                    } else {
                        self.go_to(i);
                    }
                } else {
                    if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
                        self.go_to_from_end(i);
                    } else {
                        self.go_to(i);
                    }
                }
                Some(&mut (*self.current.get()).value)
            }
        }
    }

    fn go_to(&self, i: usize) {
        unsafe {
            while (i as isize) > self.index.get() {
                self.current.set((*self.current.get()).next);
                self.index.set(self.index.get() + 1);
            }
            while (i as isize) < self.index.get() {
                self.current.set((*self.current.get()).prev);
                self.index.set(self.index.get() - 1);
            }
        }
    }

    fn go_to_from_start(&self, i: usize) {
        self.current.set(self.first);
        self.index.set(0);
        self.go_to(i);
    }

    fn go_to_from_end(&self, i: usize) {
        self.current.set(self.last);
        self.index.set(self.length as isize - 1);
        self.go_to(i);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read_and_zero(&mut (*self.last).value);
                if self.current.get() == self.last {
                    self.current.set((*self.last).prev);
                    self.index.set(self.index.get() - 1);
                }
                self.length -= 1;
                let old_last = self.last.clone();
                self.last = (*self.last).prev;
                drop(mem::transmute::<_, Box<Node<T>>>(old_last));
                Some(val)
            }
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read_and_zero(&mut (*self.first).value);
                if self.current.get() == self.first {
                    self.current.set((*self.first).next);
                }
                self.length -= 1;
                let old_first = self.first;
                self.first = (*self.first).next;
                drop(mem::transmute::<_, Box<Node<T>>>(old_first));
                Some(val)
            }
        }
    }

    pub fn insert(&mut self, i: usize, val: T) {
        if i > self.length {
            panic!("DoublyLinkedList::insert: index out of range");
        } else {
            if self.length == 0 { *self = DoublyLinkedList::new_singleton(val); }
            else {
                if i == self.length { self.push_back(val); }
                else if i == 0      { self.push_front(val); }
                else { unsafe {
                        self.go_to(i);
                        let new = Node::new_on_heap(val);
                        (*new).next = self.current.get();
                        (*new).prev = (*self.current.get()).prev;
                        (*(*(self.current.get())).prev).next = new;
                        (*self.current.get()).prev = new;
                        self.current.set(new);
                        self.length += 1;
                    }
                }
            }
        }
    }

    pub fn remove(&mut self, i: usize) -> T {
        if i >= self.length {
            panic!("DoublyLinkedList::delete: index out of range");
        } else {
            if (i == 0) { return self.pop_front().unwrap() }
            if i + 1 == self.length { return self.pop_back().unwrap() }
            unsafe {
                self.go_to(i);

                let val = ptr::read_and_zero(&mut (*self.current.get()).value);

                (*(*self.current.get()).next).prev = (*self.current.get()).prev;
                (*(*self.current.get()).prev).next = (*self.current.get()).next;

                let old_node = self.current.get();
                self.current.set((*self.current.get()).next);
                drop(mem::transmute::<_, Box<Node<T>>>(old_node));

                self.length -= 1;

                val
            }
        }
    }
}

impl<T> Index<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index(&self, i: &usize) -> &T {
        self.index(*i).unwrap()
    }
}

impl<T> IndexMut<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index_mut(&mut self, i: &usize) -> &mut T {
        self.index_mut(*i).unwrap()
    }
}

impl<T> Node<T> {
    fn new(v: T) -> Node<T> {
        Node {
            prev: ptr::null_mut(),
            value: v,
            next: ptr::null_mut()
        }
    }

    unsafe fn new_on_heap(v: T) -> *mut Node<T> {
        let node = Box::new(Node::new(v));
        let node: *mut Node<T> = mem::transmute(node);
        node
    }
}

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

    #[test]
    fn test_list() {
        let mut nums = DoublyLinkedList::new_singleton(5i32);
        assert_eq!(5i32, *nums.back().unwrap());
        assert_eq!(nums.len(), 1);
        nums.push_front(7i32);
        assert_eq!(nums.len(), 2);
        assert_eq!(7i32, *nums.front().unwrap());
        nums.push_front(9i32);
        nums.push_front(6i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
        nums.push_back(10i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
  }
}

#[bench]
fn bench_20000_ints(b:  &mut Bencher) {
    b.iter(|| {
        let mut ns: DoublyLinkedList<i64> = DoublyLinkedList::new_empty();
        for x in 0..20 { ns.push_back(x); }
    });
}
<commit_msg>impl Default trait<commit_after>extern crate test;

use std::mem;
use std::ptr;
use std::cell::Cell;
use std::num::SignedInt;
use std::ops::Index;
use std::ops::IndexMut;
use std::default::Default;
use test::Bencher;

struct Node<T> {
    prev: *mut Node<T>,
    value: T,
    next: *mut Node<T>
}

pub struct DoublyLinkedList<T> {
    current: Cell<*mut Node<T>>,
    first:   *mut Node<T>,
    last:    *mut Node<T>,
    index:   Cell<isize>,
    length:  usize
}

impl<T> DoublyLinkedList<T> {
    pub fn new_empty() -> DoublyLinkedList<T> {
        DoublyLinkedList {
            current: Cell::new(ptr::null_mut()),
            first:   ptr::null_mut(),
            last:    ptr::null_mut(),
            index:   Cell::new(-1),
            length:  0
        }
    }

    pub fn new_singleton(v: T) -> DoublyLinkedList<T> {
        unsafe {
            let node = Node::new_on_heap(v);
            DoublyLinkedList {
                current: Cell::new(node),
                first:   node,
                last:    node,
                index:   Cell::new(0),
                length:  1
            }
        }
    }

    pub fn len(&self) -> usize {
        self.length
    }

    pub fn front_mut(&mut self) -> Option<&mut T> {
        unsafe { self.first.as_mut().map(|n| { &mut n.value }) }
    }

    pub fn front(&self) -> Option<&T> {
        unsafe { self.first.as_ref().map(|n| { &n.value }) }
    }

    pub fn back_mut(&mut self) -> Option<&mut T> {
        unsafe { self.last.as_mut().map(|n| { &mut n.value }) }
    }

    pub fn back(&self) -> Option<&T> {
        unsafe { self.last.as_ref().map(|n| { &n.value }) }
    }

    pub fn push_back(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::new_singleton(val);
            } else {
                (*(self.last)).next = Node::new_on_heap(val);
                (*(*(self.last)).next).prev = self.last;
                self.last = (*(self.last)).next;
                self.length += 1;
            }
        }
    }

    pub fn push_front(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::new_singleton(val);
            } else {
                (*(self.first)).prev = Node::new_on_heap(val);
                (*(*(self.first)).prev).next = self.first;
                self.first = (*(self.first)).prev;
                self.length += 1;
            }
        }
    }

    fn index(&self, i: usize) -> Option<&T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                if self.length / 2 > i {
                    if (self.index.get() - i as isize).abs() > i as isize {
                        self.go_to_from_start(i);
                    } else {
                        self.go_to(i);
                    }
                } else {
                    if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
                        self.go_to_from_end(i);
                    } else {
                        self.go_to(i);
                    }
                }
                Some(&(*self.current.get()).value)
            }
        }
    }

    fn index_mut(&mut self, i: usize) -> Option<&mut T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                if self.length / 2 > i {
                    if (self.index.get() - i as isize).abs() > i as isize {
                        self.go_to_from_start(i);
                    } else {
                        self.go_to(i);
                    }
                } else {
                    if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
                        self.go_to_from_end(i);
                    } else {
                        self.go_to(i);
                    }
                }
                Some(&mut (*self.current.get()).value)
            }
        }
    }

    fn go_to(&self, i: usize) {
        unsafe {
            while (i as isize) > self.index.get() {
                self.current.set((*self.current.get()).next);
                self.index.set(self.index.get() + 1);
            }
            while (i as isize) < self.index.get() {
                self.current.set((*self.current.get()).prev);
                self.index.set(self.index.get() - 1);
            }
        }
    }

    fn go_to_from_start(&self, i: usize) {
        self.current.set(self.first);
        self.index.set(0);
        self.go_to(i);
    }

    fn go_to_from_end(&self, i: usize) {
        self.current.set(self.last);
        self.index.set(self.length as isize - 1);
        self.go_to(i);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read_and_zero(&mut (*self.last).value);
                if self.current.get() == self.last {
                    self.current.set((*self.last).prev);
                    self.index.set(self.index.get() - 1);
                }
                self.length -= 1;
                let old_last = self.last.clone();
                self.last = (*self.last).prev;
                drop(mem::transmute::<_, Box<Node<T>>>(old_last));
                Some(val)
            }
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read_and_zero(&mut (*self.first).value);
                if self.current.get() == self.first {
                    self.current.set((*self.first).next);
                }
                self.length -= 1;
                let old_first = self.first;
                self.first = (*self.first).next;
                drop(mem::transmute::<_, Box<Node<T>>>(old_first));
                Some(val)
            }
        }
    }

    pub fn insert(&mut self, i: usize, val: T) {
        if i > self.length {
            panic!("DoublyLinkedList::insert: index out of range");
        } else {
            if self.length == 0 { *self = DoublyLinkedList::new_singleton(val); }
            else {
                if i == self.length { self.push_back(val); }
                else if i == 0      { self.push_front(val); }
                else { unsafe {
                        self.go_to(i);
                        let new = Node::new_on_heap(val);
                        (*new).next = self.current.get();
                        (*new).prev = (*self.current.get()).prev;
                        (*(*(self.current.get())).prev).next = new;
                        (*self.current.get()).prev = new;
                        self.current.set(new);
                        self.length += 1;
                    }
                }
            }
        }
    }

    pub fn remove(&mut self, i: usize) -> T {
        if i >= self.length {
            panic!("DoublyLinkedList::delete: index out of range");
        } else {
            if (i == 0) { return self.pop_front().unwrap() }
            if i + 1 == self.length { return self.pop_back().unwrap() }
            unsafe {
                self.go_to(i);

                let val = ptr::read_and_zero(&mut (*self.current.get()).value);

                (*(*self.current.get()).next).prev = (*self.current.get()).prev;
                (*(*self.current.get()).prev).next = (*self.current.get()).next;

                let old_node = self.current.get();
                self.current.set((*self.current.get()).next);
                drop(mem::transmute::<_, Box<Node<T>>>(old_node));

                self.length -= 1;

                val
            }
        }
    }
}

impl<T> Index<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index(&self, i: &usize) -> &T {
        self.index(*i).unwrap()
    }
}

impl<T> IndexMut<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index_mut(&mut self, i: &usize) -> &mut T {
        self.index_mut(*i).unwrap()
    }
}

impl<T> Default for DoublyLinkedList<T> {
    fn default() -> DoublyLinkedList<T> {
        DoublyLinkedList::new_empty()
    }
}

impl<T> Node<T> {
    fn new(v: T) -> Node<T> {
        Node {
            prev: ptr::null_mut(),
            value: v,
            next: ptr::null_mut()
        }
    }

    unsafe fn new_on_heap(v: T) -> *mut Node<T> {
        let node = Box::new(Node::new(v));
        let node: *mut Node<T> = mem::transmute(node);
        node
    }
}

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

    #[test]
    fn test_list() {
        let mut nums = DoublyLinkedList::new_singleton(5i32);
        assert_eq!(5i32, *nums.back().unwrap());
        assert_eq!(nums.len(), 1);
        nums.push_front(7i32);
        assert_eq!(nums.len(), 2);
        assert_eq!(7i32, *nums.front().unwrap());
        nums.push_front(9i32);
        nums.push_front(6i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
        nums.push_back(10i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
  }
}

#[bench]
fn bench_20000_ints(b:  &mut Bencher) {
    b.iter(|| {
        let mut ns: DoublyLinkedList<i64> = DoublyLinkedList::new_empty();
        for x in 0..20 { ns.push_back(x); }
    });
}
<|endoftext|>


<commit_before>//! D-Bus bindings for Rust
//!
//! [D-Bus](http://dbus.freedesktop.org/) is a message bus, and is mainly used in Linux
//! for communication between processes. It is present by default on almost every
//! Linux distribution out there, and runs in two instances - one per session, and one
//! system-wide.
//!
//! See the examples directory for some examples to get you started.

// #![warn(missing_docs)]

extern crate libc;

pub use ffi::DBusBusType as BusType;
pub use ffi::DBusNameFlag as NameFlag;
pub use ffi::DBusRequestNameReply as RequestNameReply;
pub use ffi::DBusReleaseNameReply as ReleaseNameReply;
pub use ffi::DBusMessageType as MessageType;
pub use ffi::DBusWatchEvent as WatchEvent;

pub use message::{Message, MessageItem, FromMessageItem, OwnedFd, ArrayError, ConnPath};
pub use connection::{Connection, ConnectionItems, ConnectionItem};
pub use prop::PropHandler;
pub use prop::Props;
pub use watch::Watch;

/// A TypeSig describes the type of a MessageItem.
pub type TypeSig<'a> = std::borrow::Cow<'a, str>;

use std::ffi::{CString, CStr};
use std::ptr;
use std::os::raw::c_char;

#[allow(missing_docs)]
mod ffi;
mod message;
mod prop;
mod objpath;
mod watch;
mod connection;

mod strings;
pub use strings::{Signature, Path, Interface, Member, ErrorName, BusName};

pub mod arg;

/// Contains functionality for the "server" of a D-Bus object. A remote application can
/// introspect this object and call methods on it.
/// Deprecated - use the `tree` module instead.
pub mod obj {
    pub use objpath::{ObjectPath, Interface, Property, Signal, Argument};
    pub use objpath::{Method, MethodHandler, MethodResult};
    pub use objpath::{PropertyROHandler, PropertyRWHandler, PropertyWOHandler, PropertyGetResult, PropertySetResult};
}

pub mod tree;

static INITDBUS: std::sync::Once = std::sync::ONCE_INIT;

fn init_dbus() {
    INITDBUS.call_once(|| {
        if unsafe { ffi::dbus_threads_init_default() } == 0 {
            panic!("Out of memory when trying to initialize D-Bus library!");
        }
    });
}

/// D-Bus Error wrapper
pub struct Error {
    e: ffi::DBusError,
}

unsafe impl Send for Error {}

fn c_str_to_slice(c: & *const c_char) -> Option<&str> {
    if *c == ptr::null() { None }
    else { std::str::from_utf8( unsafe { CStr::from_ptr(*c).to_bytes() }).ok() }
}

fn to_c_str(n: &str) -> CString { CString::new(n.as_bytes()).unwrap() }

impl Error {

    /// Create a new custom D-Bus Error.
    pub fn new_custom(name: &str, message: &str) -> Error {
        let n = to_c_str(name);
        let m = to_c_str(&message.replace("%","%%"));
        let mut e = Error::empty();

        unsafe { ffi::dbus_set_error(e.get_mut(), n.as_ptr(), m.as_ptr()) };
        e
    }

    fn empty() -> Error {
        init_dbus();
        let mut e = ffi::DBusError {
            name: ptr::null(),
            message: ptr::null(),
            dummy: 0,
            padding1: ptr::null()
        };
        unsafe { ffi::dbus_error_init(&mut e); }
        Error{ e: e }
    }

    /// Error name/type, e g 'org.freedesktop.DBus.Error.Failed'
    pub fn name(&self) -> Option<&str> {
        c_str_to_slice(&self.e.name)
    }

    /// Custom message, e g 'Could not find a matching object path'
    pub fn message(&self) -> Option<&str> {
        c_str_to_slice(&self.e.message)
    }

    fn get_mut(&mut self) -> &mut ffi::DBusError { &mut self.e }
}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ffi::dbus_error_free(&mut self.e); }
    }
}

impl std::fmt::Debug for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "D-Bus error: {} ({})", self.message().unwrap_or(""),
            self.name().unwrap_or(""))
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str { "D-Bus error" }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(),std::fmt::Error> {
        if let Some(x) = self.message() {
             write!(f, "{:?}", x.to_string())
        } else { Ok(()) }
    }
}

impl From<arg::TypeMismatchError> for Error {
    fn from(t: arg::TypeMismatchError) -> Error {
        Error::new_custom("org.freedesktop.DBus.Error.Failed", &format!("{}", t))
    }
}

#[cfg(test)]
mod test {
    use super::{Connection, Message, BusType, MessageItem, ConnectionItem, NameFlag,
        RequestNameReply, ReleaseNameReply};

    #[test]
    fn connection() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let n = c.unique_name();
        assert!(n.starts_with(":1."));
        println!("Connected to DBus, unique name: {}", n);
    }

    #[test]
    fn invalid_message() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let m = Message::new_method_call("foo.bar", "/", "foo.bar", "FooBar").unwrap();
        let e = c.send_with_reply_and_block(m, 2000).err().unwrap();
        assert!(e.name().unwrap() == "org.freedesktop.DBus.Error.ServiceUnknown");
    }

    #[test]
    fn message_listnames() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let m = Message::method_call(&"org.freedesktop.DBus".into(), &"/".into(),
            &"org.freedesktop.DBus".into(), &"ListNames".into());
        let r = c.send_with_reply_and_block(m, 2000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
    }

    #[test]
    fn message_namehasowner() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let mut m = Message::new_method_call("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameHasOwner").unwrap();
        m.append_items(&[MessageItem::Str("org.freedesktop.DBus".to_string())]);
        let r = c.send_with_reply_and_block(m, 2000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
        assert_eq!(reply, vec!(MessageItem::Bool(true)));
    }

    #[test]
    fn object_path() {
        use  std::sync::mpsc;
        let (tx, rx) = mpsc::channel();
        let thread = ::std::thread::spawn(move || {
            let c = Connection::get_private(BusType::Session).unwrap();
            c.register_object_path("/hello").unwrap();
            // println!("Waiting...");
            tx.send(c.unique_name()).unwrap();
            for n in c.iter(1000) {
                // println!("Found message... ({})", n);
                match n {
                    ConnectionItem::MethodCall(ref m) => {
                        let reply = Message::new_method_return(m).unwrap();
                        c.send(reply).unwrap();
                        break;
                    }
                    _ => {}
                }
            }
            c.unregister_object_path("/hello");
        });

        let c = Connection::get_private(BusType::Session).unwrap();
        let n = rx.recv().unwrap();
        let m = Message::new_method_call(&n, "/hello", "com.example.hello", "Hello").unwrap();
        println!("Sending...");
        let r = c.send_with_reply_and_block(m, 8000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
        thread.join().unwrap();

    }

    #[test]
    fn register_name() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let n = format!("com.example.hello.test.register_name");
        assert_eq!(c.register_name(&n, NameFlag::ReplaceExisting as u32).unwrap(), RequestNameReply::PrimaryOwner);
        assert_eq!(c.release_name(&n).unwrap(), ReleaseNameReply::Released);
    }

    #[test]
    fn signal() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let iface = "com.example.signaltest";
        let mstr = format!("interface='{}',member='ThisIsASignal'", iface);
        c.add_match(&mstr).unwrap();
        let m = Message::new_signal("/mysignal", iface, "ThisIsASignal").unwrap();
        let uname = c.unique_name();
        c.send(m).unwrap();
        for n in c.iter(1000) {
            match n {
                ConnectionItem::Signal(s) => {
                    let (_, p, i, m) = s.headers();
                    match (&*p.unwrap(), &*i.unwrap(), &*m.unwrap()) {
                        ("/mysignal", "com.example.signaltest", "ThisIsASignal") => {
                            assert_eq!(&*s.sender().unwrap(), &*uname);
                            break;
                        },
                        (_, _, _) => println!("Other signal: {:?}", s.headers()),
                    }
                }
                _ => {},
            }
        }
        c.remove_match(&mstr).unwrap();
    }

    #[test]
    fn watch() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let mut d = c.watch_fds();
        assert!(d.len() > 0);
        println!("Fds to watch: {:?}", d);
        for n in c.iter(1000) {
            match n {
                ConnectionItem::WatchFd(w) => {
                    assert!(w.readable() || w.writable());
                    assert!(d.contains(&w));
                    d.retain(|x| *x != w);
                    if d.len() == 0 { break };
                }
                _ => {},
            }
        }
    }
}
<commit_msg>Impl From<MethodErr> for Error<commit_after>//! D-Bus bindings for Rust
//!
//! [D-Bus](http://dbus.freedesktop.org/) is a message bus, and is mainly used in Linux
//! for communication between processes. It is present by default on almost every
//! Linux distribution out there, and runs in two instances - one per session, and one
//! system-wide.
//!
//! See the examples directory for some examples to get you started.

// #![warn(missing_docs)]

extern crate libc;

pub use ffi::DBusBusType as BusType;
pub use ffi::DBusNameFlag as NameFlag;
pub use ffi::DBusRequestNameReply as RequestNameReply;
pub use ffi::DBusReleaseNameReply as ReleaseNameReply;
pub use ffi::DBusMessageType as MessageType;
pub use ffi::DBusWatchEvent as WatchEvent;

pub use message::{Message, MessageItem, FromMessageItem, OwnedFd, ArrayError, ConnPath};
pub use connection::{Connection, ConnectionItems, ConnectionItem};
pub use prop::PropHandler;
pub use prop::Props;
pub use watch::Watch;

/// A TypeSig describes the type of a MessageItem.
pub type TypeSig<'a> = std::borrow::Cow<'a, str>;

use std::ffi::{CString, CStr};
use std::ptr;
use std::os::raw::c_char;

#[allow(missing_docs)]
mod ffi;
mod message;
mod prop;
mod objpath;
mod watch;
mod connection;

mod strings;
pub use strings::{Signature, Path, Interface, Member, ErrorName, BusName};

pub mod arg;

/// Contains functionality for the "server" of a D-Bus object. A remote application can
/// introspect this object and call methods on it.
/// Deprecated - use the `tree` module instead.
pub mod obj {
    pub use objpath::{ObjectPath, Interface, Property, Signal, Argument};
    pub use objpath::{Method, MethodHandler, MethodResult};
    pub use objpath::{PropertyROHandler, PropertyRWHandler, PropertyWOHandler, PropertyGetResult, PropertySetResult};
}

pub mod tree;

static INITDBUS: std::sync::Once = std::sync::ONCE_INIT;

fn init_dbus() {
    INITDBUS.call_once(|| {
        if unsafe { ffi::dbus_threads_init_default() } == 0 {
            panic!("Out of memory when trying to initialize D-Bus library!");
        }
    });
}

/// D-Bus Error wrapper
pub struct Error {
    e: ffi::DBusError,
}

unsafe impl Send for Error {}

fn c_str_to_slice(c: & *const c_char) -> Option<&str> {
    if *c == ptr::null() { None }
    else { std::str::from_utf8( unsafe { CStr::from_ptr(*c).to_bytes() }).ok() }
}

fn to_c_str(n: &str) -> CString { CString::new(n.as_bytes()).unwrap() }

impl Error {

    /// Create a new custom D-Bus Error.
    pub fn new_custom(name: &str, message: &str) -> Error {
        let n = to_c_str(name);
        let m = to_c_str(&message.replace("%","%%"));
        let mut e = Error::empty();

        unsafe { ffi::dbus_set_error(e.get_mut(), n.as_ptr(), m.as_ptr()) };
        e
    }

    fn empty() -> Error {
        init_dbus();
        let mut e = ffi::DBusError {
            name: ptr::null(),
            message: ptr::null(),
            dummy: 0,
            padding1: ptr::null()
        };
        unsafe { ffi::dbus_error_init(&mut e); }
        Error{ e: e }
    }

    /// Error name/type, e g 'org.freedesktop.DBus.Error.Failed'
    pub fn name(&self) -> Option<&str> {
        c_str_to_slice(&self.e.name)
    }

    /// Custom message, e g 'Could not find a matching object path'
    pub fn message(&self) -> Option<&str> {
        c_str_to_slice(&self.e.message)
    }

    fn get_mut(&mut self) -> &mut ffi::DBusError { &mut self.e }
}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ffi::dbus_error_free(&mut self.e); }
    }
}

impl std::fmt::Debug for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "D-Bus error: {} ({})", self.message().unwrap_or(""),
            self.name().unwrap_or(""))
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str { "D-Bus error" }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(),std::fmt::Error> {
        if let Some(x) = self.message() {
             write!(f, "{:?}", x.to_string())
        } else { Ok(()) }
    }
}

impl From<arg::TypeMismatchError> for Error {
    fn from(t: arg::TypeMismatchError) -> Error {
        Error::new_custom("org.freedesktop.DBus.Error.Failed", &format!("{}", t))
    }
}

impl From<tree::MethodErr> for Error {
    fn from(t: tree::MethodErr) -> Error {
        Error::new_custom(t.errorname(), t.description())
    }
}

#[cfg(test)]
mod test {
    use super::{Connection, Message, BusType, MessageItem, ConnectionItem, NameFlag,
        RequestNameReply, ReleaseNameReply};

    #[test]
    fn connection() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let n = c.unique_name();
        assert!(n.starts_with(":1."));
        println!("Connected to DBus, unique name: {}", n);
    }

    #[test]
    fn invalid_message() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let m = Message::new_method_call("foo.bar", "/", "foo.bar", "FooBar").unwrap();
        let e = c.send_with_reply_and_block(m, 2000).err().unwrap();
        assert!(e.name().unwrap() == "org.freedesktop.DBus.Error.ServiceUnknown");
    }

    #[test]
    fn message_listnames() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let m = Message::method_call(&"org.freedesktop.DBus".into(), &"/".into(),
            &"org.freedesktop.DBus".into(), &"ListNames".into());
        let r = c.send_with_reply_and_block(m, 2000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
    }

    #[test]
    fn message_namehasowner() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let mut m = Message::new_method_call("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameHasOwner").unwrap();
        m.append_items(&[MessageItem::Str("org.freedesktop.DBus".to_string())]);
        let r = c.send_with_reply_and_block(m, 2000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
        assert_eq!(reply, vec!(MessageItem::Bool(true)));
    }

    #[test]
    fn object_path() {
        use  std::sync::mpsc;
        let (tx, rx) = mpsc::channel();
        let thread = ::std::thread::spawn(move || {
            let c = Connection::get_private(BusType::Session).unwrap();
            c.register_object_path("/hello").unwrap();
            // println!("Waiting...");
            tx.send(c.unique_name()).unwrap();
            for n in c.iter(1000) {
                // println!("Found message... ({})", n);
                match n {
                    ConnectionItem::MethodCall(ref m) => {
                        let reply = Message::new_method_return(m).unwrap();
                        c.send(reply).unwrap();
                        break;
                    }
                    _ => {}
                }
            }
            c.unregister_object_path("/hello");
        });

        let c = Connection::get_private(BusType::Session).unwrap();
        let n = rx.recv().unwrap();
        let m = Message::new_method_call(&n, "/hello", "com.example.hello", "Hello").unwrap();
        println!("Sending...");
        let r = c.send_with_reply_and_block(m, 8000).unwrap();
        let reply = r.get_items();
        println!("{:?}", reply);
        thread.join().unwrap();

    }

    #[test]
    fn register_name() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let n = format!("com.example.hello.test.register_name");
        assert_eq!(c.register_name(&n, NameFlag::ReplaceExisting as u32).unwrap(), RequestNameReply::PrimaryOwner);
        assert_eq!(c.release_name(&n).unwrap(), ReleaseNameReply::Released);
    }

    #[test]
    fn signal() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let iface = "com.example.signaltest";
        let mstr = format!("interface='{}',member='ThisIsASignal'", iface);
        c.add_match(&mstr).unwrap();
        let m = Message::new_signal("/mysignal", iface, "ThisIsASignal").unwrap();
        let uname = c.unique_name();
        c.send(m).unwrap();
        for n in c.iter(1000) {
            match n {
                ConnectionItem::Signal(s) => {
                    let (_, p, i, m) = s.headers();
                    match (&*p.unwrap(), &*i.unwrap(), &*m.unwrap()) {
                        ("/mysignal", "com.example.signaltest", "ThisIsASignal") => {
                            assert_eq!(&*s.sender().unwrap(), &*uname);
                            break;
                        },
                        (_, _, _) => println!("Other signal: {:?}", s.headers()),
                    }
                }
                _ => {},
            }
        }
        c.remove_match(&mstr).unwrap();
    }

    #[test]
    fn watch() {
        let c = Connection::get_private(BusType::Session).unwrap();
        let mut d = c.watch_fds();
        assert!(d.len() > 0);
        println!("Fds to watch: {:?}", d);
        for n in c.iter(1000) {
            match n {
                ConnectionItem::WatchFd(w) => {
                    assert!(w.readable() || w.writable());
                    assert!(d.contains(&w));
                    d.retain(|x| *x != w);
                    if d.len() == 0 { break };
                }
                _ => {},
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate libc;
// export it for now

use libc::{c_int, c_char, c_void};
use std::ffi::CString;
use std::ptr;

pub mod ffi;
pub use ffi::{IPaddress, _TCPsocket, _SDLNet_SocketSet, _SDLNet_GenericSocket};

pub struct TCPsocket {
    opaquePtr: *mut _TCPsocket,
}
pub struct SocketSet {
    opaquePtr: *mut _SDLNet_SocketSet,
}

pub fn init() -> () { unsafe { ffi::SDLNet_Init(); } }
pub fn quit() -> () { unsafe { ffi::SDLNet_Quit(); } }
pub fn get_error() -> String {
    unsafe {
        let raw = &ffi::SDLNet_GetError();
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

pub fn become_host(port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    let mut result = 0;
    unsafe {
        result = ffi::SDLNet_ResolveHost(&mut address, ptr::null() , port)
    }
    if (result == 0){
        Some(address)
    } else {
        None
    }
}

pub fn resolve_host(host: &str, port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0 };
    let mut result = 0;
    unsafe {
        result = ffi::SDLNet_ResolveHost(&mut address, CString::from_slice(host.as_bytes()).as_ptr(), port)
    }
    if (result == 0) {
        Some(address)
    } else {
        None
    }
}

pub fn resolve_ip(mut address: IPaddress) -> String {
    unsafe {
        let raw = &ffi::SDLNet_ResolveIP(&mut address);
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

pub fn tcp_open() -> Option<TCPsocket> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    unsafe {
        let socket = ffi::SDLNet_TCP_Open(&mut address);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaquePtr: socket })
        } else {
            None
        }
    }
}

pub fn tcp_close<'a>(sock: &'a TCPsocket) -> () {
    unsafe {
        ffi::SDLNet_TCP_Close(sock.opaquePtr)
    }
}

pub fn tcp_accept<'a>(server: &'a TCPsocket) -> TCPsocket {
    unsafe {
        TCPsocket { opaquePtr: ffi::SDLNet_TCP_Accept(server.opaquePtr) }
    }
}

pub fn tcp_get_peer_address<'a>(sock: &'a TCPsocket) -> Box<*mut IPaddress> {
    unsafe {
        Box::new(ffi::SDLNet_TCP_GetPeerAddress(sock.opaquePtr))
    }
}

pub fn tcp_send<'a>(sock: &'a TCPsocket, data: &[u8]) -> () {
    unsafe {
        ffi::SDLNet_TCP_Send(sock.opaquePtr, data.as_ptr() as *const c_void, data.len() as i32);
    }
}

pub fn tcp_recv<'a>(sock: &'a TCPsocket, maxlen: i32) -> Vec<u8> {
    let mut data: Vec<u8> = Vec::with_capacity(maxlen as usize);
    unsafe {
        let read_ammnt = ffi::SDLNet_TCP_Recv(sock.opaquePtr, data.as_mut_ptr() as *mut c_void, data.len() as i32);
        data.set_len(read_ammnt as usize);
    }
    data
}

pub fn alloc_socket_set(maxsockets: i32) -> SocketSet {
    unsafe {
        SocketSet { opaquePtr: ffi::SDLNet_AllocSocketSet(maxsockets) }
    }
}

pub fn free_socket_set<'a>(set: &'a SocketSet) -> () {
    unsafe {
        ffi::SDLNet_FreeSocketSet(set.opaquePtr);
    }
}

pub fn add_socket<'a>(set: &'a SocketSet, sock: &'a TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_AddSocket(set.opaquePtr, sock.opaquePtr)
    }
}

// Maybe should take in the box here as it may get deleted.... not sure
pub fn del_socket<'a>(set: &'a SocketSet, sock: &'a TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_DelSocket(set.opaquePtr, sock.opaquePtr)
    }
}

pub fn check_sockets<'b>(set: &'b SocketSet, timeout: u32) -> i32 {
    unsafe {
        ffi::SDLNet_CheckSockets(set.opaquePtr, timeout)
    }
}

pub fn socket_ready<'c>(sock: &'c TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_SocketReady(sock.opaquePtr as *mut c_void)
    }
}
<commit_msg>Removed some lifetimes.<commit_after>extern crate libc;
// export it for now

use libc::{c_int, c_char, c_void};
use std::ffi::CString;
use std::ptr;

pub mod ffi;
pub use ffi::{IPaddress, _TCPsocket, _SDLNet_SocketSet, _SDLNet_GenericSocket};

pub struct TCPsocket {
    opaquePtr: *mut _TCPsocket,
}
pub struct SocketSet {
    opaquePtr: *mut _SDLNet_SocketSet,
}

pub fn init() -> () { unsafe { ffi::SDLNet_Init(); } }
pub fn quit() -> () { unsafe { ffi::SDLNet_Quit(); } }
pub fn get_error() -> String {
    unsafe {
        let raw = &ffi::SDLNet_GetError();
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

pub fn become_host(port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    let mut result = 0;
    unsafe {
        result = ffi::SDLNet_ResolveHost(&mut address, ptr::null() , port)
    }
    if (result == 0){
        Some(address)
    } else {
        None
    }
}

pub fn resolve_host(host: &str, port: u16) -> Option<ffi::IPaddress> {
    let mut address = ffi::IPaddress { host: 0, port: 0 };
    let mut result = 0;
    unsafe {
        result = ffi::SDLNet_ResolveHost(&mut address, CString::from_slice(host.as_bytes()).as_ptr(), port)
    }
    if (result == 0) {
        Some(address)
    } else {
        None
    }
}

pub fn resolve_ip(mut address: IPaddress) -> String {
    unsafe {
        let raw = &ffi::SDLNet_ResolveIP(&mut address);
        std::str::from_utf8(std::ffi::c_str_to_bytes(raw)).unwrap().to_string()
    }
}

pub fn tcp_open() -> Option<TCPsocket> {
    let mut address = ffi::IPaddress { host: 0, port: 0};
    unsafe {
        let socket = ffi::SDLNet_TCP_Open(&mut address);
        if socket as *const _TCPsocket != ptr::null() {
            Some(TCPsocket { opaquePtr: socket })
        } else {
            None
        }
    }
}

pub fn tcp_close(sock: &TCPsocket) -> () {
    unsafe {
        ffi::SDLNet_TCP_Close(sock.opaquePtr)
    }
}

pub fn tcp_accept<'a>(server: &'a TCPsocket) -> TCPsocket {
    unsafe {
        TCPsocket { opaquePtr: ffi::SDLNet_TCP_Accept(server.opaquePtr) }
    }
}

pub fn tcp_get_peer_address<'a>(sock: &'a TCPsocket) -> Box<*mut IPaddress> {
    unsafe {
        Box::new(ffi::SDLNet_TCP_GetPeerAddress(sock.opaquePtr))
    }
}

pub fn tcp_send<'a>(sock: &'a TCPsocket, data: &[u8]) -> () {
    unsafe {
        ffi::SDLNet_TCP_Send(sock.opaquePtr, data.as_ptr() as *const c_void, data.len() as i32);
    }
}

pub fn tcp_recv<'a>(sock: &'a TCPsocket, maxlen: i32) -> Vec<u8> {
    let mut data: Vec<u8> = Vec::with_capacity(maxlen as usize);
    unsafe {
        let read_ammnt = ffi::SDLNet_TCP_Recv(sock.opaquePtr, data.as_mut_ptr() as *mut c_void, data.len() as i32);
        data.set_len(read_ammnt as usize);
    }
    data
}

pub fn alloc_socket_set(maxsockets: i32) -> SocketSet {
    unsafe {
        SocketSet { opaquePtr: ffi::SDLNet_AllocSocketSet(maxsockets) }
    }
}

pub fn free_socket_set(set: &SocketSet) -> () {
    unsafe {
        ffi::SDLNet_FreeSocketSet(set.opaquePtr);
    }
}

pub fn add_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_AddSocket(set.opaquePtr, sock.opaquePtr)
    }
}

// Maybe should take in the box here as it may get deleted.... not sure
pub fn del_socket(set: &SocketSet, sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_DelSocket(set.opaquePtr, sock.opaquePtr)
    }
}

pub fn check_sockets(set: &SocketSet, timeout: u32) -> i32 {
    unsafe {
        ffi::SDLNet_CheckSockets(set.opaquePtr, timeout)
    }
}

pub fn socket_ready(sock: &TCPsocket) -> i32 {
    unsafe {
        ffi::SDLNet_SocketReady(sock.opaquePtr as *mut c_void)
    }
}
<|endoftext|>


<commit_before>//! A collection of types and traits useful for high performance envelope detection over a signal.
//!
//! The primary types of interest are:
//!
//! - [**EnvelopeDetector**](./struct.EnvelopeDetector).
//! - [**Rms**](./rms.struct.Rms).
//! - [**Peak**](./peak.struct.Peak).

#![deny(missing_copy_implementations)]
#![deny(missing_docs)]

extern crate sample;

pub use mode::Mode;
pub use peak::Peak;
pub use rms::Rms;
pub use sample::{Frame, Sample};

pub mod mode;
pub mod peak;
pub mod rms;

/// Iteratively extracts the amplitude envelope from an audio signal based on three parameters:
///
/// - Attack time.
/// - Release time.
/// - Detection mode (Either Peak or RMS).
///
/// Supports processing any `sample::Frame`
#[derive(Copy, Clone, Debug)]
pub struct EnvelopeDetector<F, M>
    where F: Frame,
          M: Mode<F>,
{
    attack_gain: f32,
    release_gain: f32,
    last_env_frame: F,
    mode: M,
}

/// An `EnvelopeDetector` that tracks the signal envelope using RMS.
pub type RmsEnvelopeDetector<F> = EnvelopeDetector<F, Rms<F>>;
/// An `EnvelopeDetector` that tracks the full wave `Peak` envelope of a signal.
pub type PeakEnvelopeDetector<F> = EnvelopeDetector<F, Peak<peak::FullWave>>;

fn calc_gain(n_frames: f32) -> f32 {
    ::std::f32::consts::E.powf(-1.0 / n_frames)
}

impl<F> EnvelopeDetector<F, Rms<F>>
    where F: Frame,
{

    /// Construct a new **Rms** **EnvelopeDetector**.
    pub fn rms(rms_window_frames: usize, attack_frames: f32, release_frames: f32) -> Self {
        let rms = Rms::new(rms_window_frames);
        Self::new(rms, attack_frames, release_frames)
    }

    /// Set the duration of the **Rms** window in frames.
    pub fn set_window_frames(&mut self, n_window_frames: usize) {
        self.mode.set_window_frames(n_window_frames);
    }

}

impl<F> EnvelopeDetector<F, Peak<peak::FullWave>>
    where F: Frame,
{

    /// Construct a new **Mono** **Peak** **EnvelopeDetector**.
    pub fn peak(attack_frames: f32, release_frames: f32) -> Self {
        let peak = Peak::full_wave();
        Self::new(peak, attack_frames, release_frames)
    }

}

impl<F, M> EnvelopeDetector<F, M>
    where F: Frame,
          M: Mode<F>,
{

    fn new(mode: M, attack_frames: f32, release_frames: f32) -> Self {
        EnvelopeDetector {
            mode: mode,
            last_env_frame: F::equilibrium(),
            attack_gain: calc_gain(attack_frames),
            release_gain: calc_gain(release_frames),
        }
    }

    /// Set the **EnvelopeDetector**'s attack time as a number of frames.
    pub fn set_attack_frames(&mut self, frames: f32) {
        self.attack_gain = calc_gain(frames);
    }

    /// Set the **EnvelopeDetector**'s release time as a number of frames.
    pub fn set_release_frames(&mut self, frames: f32) {
        self.attack_gain = calc_gain(frames);
    }

    /// Given the next input signal frame, detect and return the next envelope frame.
    pub fn next(&mut self, frame: F) -> F {
        let EnvelopeDetector {
            attack_gain, release_gain, ref mut mode, ref mut last_env_frame,
        } = *self;

        let mode_frame = mode.next_frame(frame);
        let new_env_frame = last_env_frame.zip_map(mode_frame, |l, m| {
            let gain = if l < m { attack_gain } else { release_gain };
            let diff = l.add_amp(-m.to_signed_sample());
            m.add_amp(diff.mul_amp(gain.to_sample()).to_sample())
        });
        *last_env_frame = new_env_frame;
        new_env_frame
    }

}
<commit_msg>Add next_avg method for returning the average envelope across each channel in the next envelope frame<commit_after>//! A collection of types and traits useful for high performance envelope detection over a signal.
//!
//! The primary types of interest are:
//!
//! - [**EnvelopeDetector**](./struct.EnvelopeDetector).
//! - [**Rms**](./rms.struct.Rms).
//! - [**Peak**](./peak.struct.Peak).

#![deny(missing_copy_implementations)]
#![deny(missing_docs)]

extern crate sample;

pub use mode::Mode;
pub use peak::Peak;
pub use rms::Rms;
pub use sample::{Frame, Sample};

pub mod mode;
pub mod peak;
pub mod rms;

/// Iteratively extracts the amplitude envelope from an audio signal based on three parameters:
///
/// - Attack time.
/// - Release time.
/// - Detection mode (Either Peak or RMS).
///
/// Supports processing any `sample::Frame`
#[derive(Copy, Clone, Debug)]
pub struct EnvelopeDetector<F, M>
    where F: Frame,
          M: Mode<F>,
{
    attack_gain: f32,
    release_gain: f32,
    last_env_frame: F,
    mode: M,
}

/// An `EnvelopeDetector` that tracks the signal envelope using RMS.
pub type RmsEnvelopeDetector<F> = EnvelopeDetector<F, Rms<F>>;
/// An `EnvelopeDetector` that tracks the full wave `Peak` envelope of a signal.
pub type PeakEnvelopeDetector<F> = EnvelopeDetector<F, Peak<peak::FullWave>>;

fn calc_gain(n_frames: f32) -> f32 {
    ::std::f32::consts::E.powf(-1.0 / n_frames)
}

impl<F> EnvelopeDetector<F, Rms<F>>
    where F: Frame,
{

    /// Construct a new **Rms** **EnvelopeDetector**.
    pub fn rms(rms_window_frames: usize, attack_frames: f32, release_frames: f32) -> Self {
        let rms = Rms::new(rms_window_frames);
        Self::new(rms, attack_frames, release_frames)
    }

    /// Set the duration of the **Rms** window in frames.
    pub fn set_window_frames(&mut self, n_window_frames: usize) {
        self.mode.set_window_frames(n_window_frames);
    }

}

impl<F> EnvelopeDetector<F, Peak<peak::FullWave>>
    where F: Frame,
{

    /// Construct a new **Mono** **Peak** **EnvelopeDetector**.
    pub fn peak(attack_frames: f32, release_frames: f32) -> Self {
        let peak = Peak::full_wave();
        Self::new(peak, attack_frames, release_frames)
    }

}

impl<F, M> EnvelopeDetector<F, M>
    where F: Frame,
          M: Mode<F>,
{

    fn new(mode: M, attack_frames: f32, release_frames: f32) -> Self {
        EnvelopeDetector {
            mode: mode,
            last_env_frame: F::equilibrium(),
            attack_gain: calc_gain(attack_frames),
            release_gain: calc_gain(release_frames),
        }
    }

    /// Set the **EnvelopeDetector**'s attack time as a number of frames.
    pub fn set_attack_frames(&mut self, frames: f32) {
        self.attack_gain = calc_gain(frames);
    }

    /// Set the **EnvelopeDetector**'s release time as a number of frames.
    pub fn set_release_frames(&mut self, frames: f32) {
        self.attack_gain = calc_gain(frames);
    }

    /// Given the next input signal frame, detect and return the next envelope frame.
    pub fn next(&mut self, frame: F) -> F {
        let EnvelopeDetector {
            attack_gain, release_gain, ref mut mode, ref mut last_env_frame,
        } = *self;

        let mode_frame = mode.next_frame(frame);
        let new_env_frame = last_env_frame.zip_map(mode_frame, |l, m| {
            let gain = if l < m { attack_gain } else { release_gain };
            let diff = l.add_amp(-m.to_signed_sample());
            m.add_amp(diff.mul_amp(gain.to_sample()).to_sample())
        });
        *last_env_frame = new_env_frame;
        new_env_frame
    }

    /// Given the next input signal frame, detect and return the next envelope average across each
    /// channel for the frame.
    ///
    /// The returned value will take the form of the signal's equivalent floating point sample
    /// format.
    pub fn next_avg(&mut self, frame: F) -> <F::Sample as Sample>::Float {
        let next_frame = self.next(frame);
        let equilibrium: F::Sample = Sample::equilibrium();
        let sum = next_frame.channels().fold(equilibrium, |sum, s| sum.add_amp(s.to_sample()));
        sum.to_float_sample() / (F::n_channels() as f32).to_sample()
    }

}
<|endoftext|>


<commit_before>#![feature(core)]
#![feature(io)]
#![feature(path)]
#![feature(test)]

extern crate core;
extern crate hyper;
extern crate mime;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
extern crate url;

use core::ops::DerefMut;
use hyper::Url;
use hyper::client::Body;
use hyper::header::{ Accept, Authorization, ContentType, UserAgent, qitem };
use hyper::method::Method;
use mime::{ Attr, Mime, Value };
use mime::TopLevel::Application;
use mime::SubLevel::Json;
use rustc_serialize::{ Decoder, Decodable, json };
use std::collections::HashMap;
use std::fs::{ self, File };
use std::io::prelude::*;
use std::io::{ Cursor, Error };
use std::path::Path;
use std::result;

pub type Result<T> = result::Result<T, Error>;

pub struct Client {
  host: String,
  token: Option<String>
}

#[derive(RustcDecodable)]
struct Status {
  ok: bool
}

#[derive(RustcDecodable)]
struct Following {
  following: bool
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct User {
  pub id: u32,
  pub login: String,
  pub avatar: String,
  pub email: Option<String>,
  pub name: Option<String>,
}

#[derive(RustcDecodable)]
struct Users {
  users: Vec<User>
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Crate {
  pub name: String,
  pub description: Option<String>,
  pub max_version: String
}

// RustcDecodable be derived because the key used in json is `crate`,
// a reserved word
struct CrateReq {
  krate: Crate
}

impl Decodable for CrateReq {
  fn decode<D: Decoder>(d: &mut D) -> result::Result<CrateReq, D::Error> {
    d.read_struct("CrateReq", 1usize, |_d| {
      Ok(CrateReq {
        krate: try!(_d.read_struct_field("crate", 0usize, |_d| Decodable::decode(_d)))
      })
    })
  }
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Download {
  pub date: String,
  pub downloads: u32
}

#[derive(RustcDecodable)]
struct VersionDownloads {
  version_downloads: Vec<Download>
}

#[derive(RustcDecodable)]
struct ExtraDownloads {
  extra_downloads: Vec<Download>
}

#[derive(RustcDecodable)]
struct MetaDownloads {
  meta: ExtraDownloads
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Dependency {
  pub crate_id: String,
  pub default_features: bool,
  pub features: String,
  pub kind: String,
  pub optional: bool,
  pub req: String
}

#[derive(RustcDecodable)]
struct Dependencies {
  dependencies: Vec<Dependency>
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Version {
  // crate: String,
  pub created_at: String,
  pub dl_path: String,
  pub downloads: u32,
  pub num: String,
  pub updated_at: String,
  pub yanked: bool
}

#[derive(RustcDecodable)]
struct VersionReq {
  version: Version
}

#[derive(RustcDecodable)]
struct Versions {
  versions: Vec<Version>
}

#[derive(RustcDecodable)]
struct Meta {
  names: Vec<String>
}

#[derive(RustcDecodable)]
struct Authors {
  meta: Meta
}

#[derive(RustcEncodable)]
pub struct NewCrate {
  pub name: String,
  pub vers: String,
  pub deps: Vec<NewCrateDependency>,
  pub features: HashMap<String, Vec<String>>,
  pub authors: Vec<String>,
  pub description: Option<String>,
  pub documentation: Option<String>,
  pub homepage: Option<String>,
  pub readme: Option<String>,
  pub keywords: Vec<String>,
  pub license: Option<String>,
  pub license_file: Option<String>,
  pub repository: Option<String>,
}

#[derive(RustcEncodable)]
pub struct NewCrateDependency {
  pub optional: bool,
  pub default_features: bool,
  pub name: String,
  pub features: Vec<String>,
  pub version_req: String,
  pub target: Option<String>,
  pub kind: String,
}

#[derive(RustcEncodable)]
pub struct OwnersReq<'a> {
  users: &'a [&'a str]
}

#[derive(RustcDecodable)]
struct Crates {
  crates: Vec<Crate>
}

struct Bod<'a> {
 read: &'a mut Box<&'a mut Read>,
 size: u64
}

impl Client {
  pub fn new() -> Client {
    Client::host("https://crates.io")
  }

  pub fn host(addr: &str) -> Client {
    Client {
      host: addr.to_string(),
      token: None
    }
  }

  pub fn token(self, auth: &str) -> Client {
    Client {
      host: self.host,
      token: Some(auth.to_string())
    }
  }

  // todo: sort (downloads|name), by letter/keyword/user_id/following
  pub fn find(&mut self, query: &str) -> Result<Vec<Crate>> {
    let body = try!(self.get(format!("/crates?q={}&sort={}", query, "name")));
    Ok(json::decode::<Crates>(&body).unwrap().crates)
  }

  pub fn named(&mut self, name: &str) -> Result<Crate> {
    let body = try!(self.get(format!("/crates/{}", name)));
    Ok(json::decode::<CrateReq>(&body).unwrap().krate)
  }

  // todo: publish -- https://github.com/rust-lang/crates.io/blob/dabd8778c1a515ea7572c59096da76e562afe2e2/src/lib.rs#L76
  pub fn publish(&mut self, krate: &NewCrate, tarball: &Path) -> Result<()> {
    let json = json::encode(krate).unwrap();
    let stat = try!(fs::metadata(tarball));
    let header = {
      let mut w = Vec::new();
      w.extend([
        (json.len() >>  0) as u8,
        (json.len() >>  8) as u8,
        (json.len() >> 16) as u8,
        (json.len() >> 24) as u8,
      ].iter().cloned());
      w.extend(json.as_bytes().iter().cloned());
      w.extend([
        (stat.len() >>  0) as u8,
        (stat.len() >>  8) as u8,
        (stat.len() >> 16) as u8,
        (stat.len() >> 24) as u8,
      ].iter().cloned());
      w
    };
    let size = stat.len() as usize + header.len();
    let tarball = try!(File::open(tarball));
    let mut body = Cursor::new(header).chain(tarball);
    let _ = try!(self.put("/crates/new".to_string(), Some(Bod { read: &mut Box::new(&mut body), size: size as u64 })));
    Ok(())
  }

  pub fn version(&mut self, name: &str, version: &str) -> Result<Version> {
    let body = try!(self.get(format!("/crates/{}/{}", name, version)));
    Ok(json::decode::<VersionReq>(&body).unwrap().version)
  }

  // todo: version download -- https://github.com/rust-lang/crates.io/blob/dabd8778c1a515ea7572c59096da76e562afe2e2/src/lib.rs#L78

  pub fn dependencies(&mut self, name: &str, version: &str) -> Result<Vec<Dependency>> {
    let body = try!(self.get(format!("/crates/{}/{}/dependencies", name, version)));
    Ok(json::decode::<Dependencies>(&body).unwrap().dependencies)
  }

  pub fn downloads(&mut self, name: &str, version: &str) -> Result<Vec<Download>> {
    let body = try!(self.get(format!("/crates/{}/{}/downloads", name, version)));
    Ok(json::decode::<VersionDownloads>(&body).unwrap().version_downloads)
  }

  pub fn authors(&mut self, name: &str, version: &str) -> Result<Vec<String>> {
    let body = try!(self.get(format!("/crates/{}/{}/authors", name, version)));
    Ok(json::decode::<Authors>(&body).unwrap().meta.names)
  }

  pub fn all_downloads(&mut self, name: &str) -> Result<Vec<Download>> {
    let body = try!(self.get(format!("/crates/{}/downloads", name)));
    Ok(json::decode::<MetaDownloads>(&body).unwrap().meta.extra_downloads)
  }

  pub fn versions(&mut self, name: &str) -> Result<Vec<Version>> {
    let body = try!(self.get(format!("/crates/{}/versions", name)));
    let versions: Vec<Version> = json::decode::<Versions>(&body).unwrap().versions;
    Ok(versions)
  }

  pub fn follow(&mut self, krate: &str) -> Result<()> {
    let body = try!(self.put(format!("/crates/{}/follow", krate), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn unfollow(&mut self, krate: &str) -> Result<()> {
    let body = try!(self.delete(format!("/crates/{}/follow", krate), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn following(&mut self, krate: &str) -> Result<bool> {
    let body = try!(self.get(format!("/crates/{}/following", krate)));
    Ok(json::decode::<Following>(&body).unwrap().following)
  }

  pub fn owners(&mut self, krate: &str) -> Result<Vec<User>> {
    let body = try!(self.get(format!("/crates/{}/owners", krate)));
    Ok(json::decode::<Users>(&body).unwrap().users)
  }

  pub fn add_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
    let data = json::encode(&OwnersReq { users: owners }).unwrap();
    let mut bytes = data.as_bytes();
    let body = try!(self.put(format!("/crates/{}/owners", krate),
                             Some(Bod { read: &mut Box::new(&mut bytes), size: bytes.len() as u64 })));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn remove_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
    let data = json::encode(&OwnersReq { users: owners }).unwrap();
    let mut bytes = data.as_bytes();
    let body = try!(self.delete(format!("/crates/{}/owners", krate),
                                Some(Bod { read: &mut Box::new(&mut bytes), size: bytes.len() as u64 })));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn yank(&mut self, krate: &str, version: &str) -> Result<()> {
    let body = try!(self.delete(format!("/crates/{}/{}/yank", krate, version), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn unyank(&mut self, krate: &str, version: &str) -> Result<()> {
    let body = try!(self.put(format!("/crates/{}/{}/unyank", krate, version), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn reverse_dependencies(&mut self, krate: &str) -> Result<Vec<Dependency>> {
    let body = try!(self.get(format!("/crates/{}/reverse_dependencies", krate)));
    Ok(json::decode::<Dependencies>(&body).unwrap().dependencies)
  }

  fn get(&mut self, path: String) -> Result<String> {
    self.req(Method::Get, path, None)
  }

  fn delete(&mut self, path: String, body: Option<Bod>) -> Result<String> {
    self.req(Method::Delete, path, body)
  }

  fn put(&mut self, path: String, body: Option<Bod>) -> Result<String> {
    self.req(Method::Put, path, body)
  }

  fn req(&mut self, method: Method, path: String, body: Option<Bod>) -> Result<String> {
    let uri = Url::parse(&format!("{}/api/v1{}", self.host, path)).ok().expect("invalid url");
    let mut client = hyper::Client::new();
    let content_type: Mime = Mime(Application, Json, vec![(Attr::Charset, Value::Utf8)]);
    let bound = client.request(method, uri)
      .header(UserAgent("cargopants/0.1.0".to_string()))
      .header(Accept(vec![qitem(content_type.clone())]))
      .header(ContentType(content_type));
    let authenticated = match self.token.clone() {
      Some(auth) => bound.header(Authorization(auth)),
               _ => bound
    };
    let embodied = match body {
      Some(Bod { read: r, size: l }) => {
        let reader: &mut Read  = *r.deref_mut();
        authenticated.body(Body::SizedBody(reader, l))
      },
      _  => authenticated
    };
    let mut res = match embodied.send() {
      Ok(r)    => r,
      Err(err) => panic!("failed request: {:?}", err)
    };
    let mut body = String::new();
    res.read_to_string(&mut body).map(|_| body)
  }
}

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

  #[test]
  fn it_parses_crate_req() {

  }

  #[bench]
  fn it_benches(b: &mut Bencher) {

  }
}
<commit_msg>better body<commit_after>#![feature(core)]
#![feature(io)]
#![feature(path)]
#![feature(test)]

extern crate core;
extern crate hyper;
extern crate mime;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
extern crate url;

use core::ops::DerefMut;
use hyper::Url;
use hyper::client;
use hyper::header::{ Accept, Authorization, ContentType, UserAgent, qitem };
use hyper::method::Method;
use mime::{ Attr, Mime, Value };
use mime::TopLevel::Application;
use mime::SubLevel::Json;
use rustc_serialize::{ Decoder, Decodable, json };
use std::collections::HashMap;
use std::fs::{ self, File };
use std::io::prelude::*;
use std::io::{ Cursor, Error };
use std::path::Path;
use std::result;

pub type Result<T> = result::Result<T, Error>;

pub struct Client {
  host: String,
  token: Option<String>
}

#[derive(RustcDecodable)]
struct Status {
  ok: bool
}

#[derive(RustcDecodable)]
struct Following {
  following: bool
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct User {
  pub id: u32,
  pub login: String,
  pub avatar: String,
  pub email: Option<String>,
  pub name: Option<String>,
}

#[derive(RustcDecodable)]
struct Users {
  users: Vec<User>
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Crate {
  pub name: String,
  pub description: Option<String>,
  pub max_version: String
}

// RustcDecodable be derived because the key used in json is `crate`,
// a reserved word
struct CrateReq {
  krate: Crate
}

impl Decodable for CrateReq {
  fn decode<D: Decoder>(d: &mut D) -> result::Result<CrateReq, D::Error> {
    d.read_struct("CrateReq", 1usize, |_d| {
      Ok(CrateReq {
        krate: try!(_d.read_struct_field("crate", 0usize, |_d| Decodable::decode(_d)))
      })
    })
  }
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Download {
  pub date: String,
  pub downloads: u32
}

#[derive(RustcDecodable)]
struct VersionDownloads {
  version_downloads: Vec<Download>
}

#[derive(RustcDecodable)]
struct ExtraDownloads {
  extra_downloads: Vec<Download>
}

#[derive(RustcDecodable)]
struct MetaDownloads {
  meta: ExtraDownloads
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Dependency {
  pub crate_id: String,
  pub default_features: bool,
  pub features: String,
  pub kind: String,
  pub optional: bool,
  pub req: String
}

#[derive(RustcDecodable)]
struct Dependencies {
  dependencies: Vec<Dependency>
}

#[derive(RustcDecodable)]
#[derive(Debug)]
pub struct Version {
  // crate: String,
  pub created_at: String,
  pub dl_path: String,
  pub downloads: u32,
  pub num: String,
  pub updated_at: String,
  pub yanked: bool
}

#[derive(RustcDecodable)]
struct VersionReq {
  version: Version
}

#[derive(RustcDecodable)]
struct Versions {
  versions: Vec<Version>
}

#[derive(RustcDecodable)]
struct Meta {
  names: Vec<String>
}

#[derive(RustcDecodable)]
struct Authors {
  meta: Meta
}

#[derive(RustcEncodable)]
pub struct NewCrate {
  pub name: String,
  pub vers: String,
  pub deps: Vec<NewCrateDependency>,
  pub features: HashMap<String, Vec<String>>,
  pub authors: Vec<String>,
  pub description: Option<String>,
  pub documentation: Option<String>,
  pub homepage: Option<String>,
  pub readme: Option<String>,
  pub keywords: Vec<String>,
  pub license: Option<String>,
  pub license_file: Option<String>,
  pub repository: Option<String>,
}

#[derive(RustcEncodable)]
pub struct NewCrateDependency {
  pub optional: bool,
  pub default_features: bool,
  pub name: String,
  pub features: Vec<String>,
  pub version_req: String,
  pub target: Option<String>,
  pub kind: String,
}

#[derive(RustcEncodable)]
pub struct OwnersReq<'a> {
  users: &'a [&'a str]
}

#[derive(RustcDecodable)]
struct Crates {
  crates: Vec<Crate>
}

struct Body<'a> {
 read: &'a mut Box<&'a mut Read>,
 size: u64
}

impl<'a> Body<'a> {
  pub fn new(read: &'a mut Box<&'a mut Read>, size: u64) -> Body<'a> {
    Body { read: read, size: size }
  }
}

impl Client {
  pub fn new() -> Client {
    Client::host("https://crates.io")
  }

  pub fn host(addr: &str) -> Client {
    Client {
      host: addr.to_string(),
      token: None
    }
  }

  pub fn token(self, auth: &str) -> Client {
    Client {
      host: self.host,
      token: Some(auth.to_string())
    }
  }

  // todo: sort (downloads|name), by letter/keyword/user_id/following
  pub fn find(&mut self, query: &str) -> Result<Vec<Crate>> {
    let body = try!(self.get(format!("/crates?q={}&sort={}", query, "name")));
    Ok(json::decode::<Crates>(&body).unwrap().crates)
  }

  pub fn named(&mut self, name: &str) -> Result<Crate> {
    let body = try!(self.get(format!("/crates/{}", name)));
    Ok(json::decode::<CrateReq>(&body).unwrap().krate)
  }

  // todo: publish -- https://github.com/rust-lang/crates.io/blob/dabd8778c1a515ea7572c59096da76e562afe2e2/src/lib.rs#L76
  pub fn publish(&mut self, krate: &NewCrate, tarball: &Path) -> Result<()> {
    let json = json::encode(krate).unwrap();
    let stat = try!(fs::metadata(tarball));
    let header = {
      let mut w = Vec::new();
      w.extend([
        (json.len() >>  0) as u8,
        (json.len() >>  8) as u8,
        (json.len() >> 16) as u8,
        (json.len() >> 24) as u8,
      ].iter().cloned());
      w.extend(json.as_bytes().iter().cloned());
      w.extend([
        (stat.len() >>  0) as u8,
        (stat.len() >>  8) as u8,
        (stat.len() >> 16) as u8,
        (stat.len() >> 24) as u8,
      ].iter().cloned());
      w
    };
    let size = stat.len() as usize + header.len();
    let tarball = try!(File::open(tarball));
    let mut body = Cursor::new(header).chain(tarball);
    let _ = try!(self.put("/crates/new".to_string(), Some(Body::new(&mut Box::new(&mut body), size as u64))));
    Ok(())
  }

  pub fn version(&mut self, name: &str, version: &str) -> Result<Version> {
    let body = try!(self.get(format!("/crates/{}/{}", name, version)));
    Ok(json::decode::<VersionReq>(&body).unwrap().version)
  }

  // todo: version download -- https://github.com/rust-lang/crates.io/blob/dabd8778c1a515ea7572c59096da76e562afe2e2/src/lib.rs#L78

  pub fn dependencies(&mut self, name: &str, version: &str) -> Result<Vec<Dependency>> {
    let body = try!(self.get(format!("/crates/{}/{}/dependencies", name, version)));
    Ok(json::decode::<Dependencies>(&body).unwrap().dependencies)
  }

  pub fn downloads(&mut self, name: &str, version: &str) -> Result<Vec<Download>> {
    let body = try!(self.get(format!("/crates/{}/{}/downloads", name, version)));
    Ok(json::decode::<VersionDownloads>(&body).unwrap().version_downloads)
  }

  pub fn authors(&mut self, name: &str, version: &str) -> Result<Vec<String>> {
    let body = try!(self.get(format!("/crates/{}/{}/authors", name, version)));
    Ok(json::decode::<Authors>(&body).unwrap().meta.names)
  }

  pub fn all_downloads(&mut self, name: &str) -> Result<Vec<Download>> {
    let body = try!(self.get(format!("/crates/{}/downloads", name)));
    Ok(json::decode::<MetaDownloads>(&body).unwrap().meta.extra_downloads)
  }

  pub fn versions(&mut self, name: &str) -> Result<Vec<Version>> {
    let body = try!(self.get(format!("/crates/{}/versions", name)));
    let versions: Vec<Version> = json::decode::<Versions>(&body).unwrap().versions;
    Ok(versions)
  }

  pub fn follow(&mut self, krate: &str) -> Result<()> {
    let body = try!(self.put(format!("/crates/{}/follow", krate), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn unfollow(&mut self, krate: &str) -> Result<()> {
    let body = try!(self.delete(format!("/crates/{}/follow", krate), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn following(&mut self, krate: &str) -> Result<bool> {
    let body = try!(self.get(format!("/crates/{}/following", krate)));
    Ok(json::decode::<Following>(&body).unwrap().following)
  }

  pub fn owners(&mut self, krate: &str) -> Result<Vec<User>> {
    let body = try!(self.get(format!("/crates/{}/owners", krate)));
    Ok(json::decode::<Users>(&body).unwrap().users)
  }

  pub fn add_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
    let data = json::encode(&OwnersReq { users: owners }).unwrap();
    let mut bytes = data.as_bytes();
    let body = try!(self.put(format!("/crates/{}/owners", krate),
                             Some(Body::new(&mut Box::new(&mut bytes), bytes.len() as u64))));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn remove_owners(&mut self, krate: &str, owners: &[&str]) -> Result<()> {
    let data = json::encode(&OwnersReq { users: owners }).unwrap();
    let mut bytes = data.as_bytes();
    let body = try!(self.delete(format!("/crates/{}/owners", krate),
                                Some(Body::new(&mut Box::new(&mut bytes), bytes.len() as u64))));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn yank(&mut self, krate: &str, version: &str) -> Result<()> {
    let body = try!(self.delete(format!("/crates/{}/{}/yank", krate, version), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn unyank(&mut self, krate: &str, version: &str) -> Result<()> {
    let body = try!(self.put(format!("/crates/{}/{}/unyank", krate, version), None));
    assert!(json::decode::<Status>(&body).unwrap().ok);
    Ok(())
  }

  pub fn reverse_dependencies(&mut self, krate: &str) -> Result<Vec<Dependency>> {
    let body = try!(self.get(format!("/crates/{}/reverse_dependencies", krate)));
    Ok(json::decode::<Dependencies>(&body).unwrap().dependencies)
  }

  fn get(&mut self, path: String) -> Result<String> {
    self.req(Method::Get, path, None)
  }

  fn delete(&mut self, path: String, body: Option<Body>) -> Result<String> {
    self.req(Method::Delete, path, body)
  }

  fn put(&mut self, path: String, body: Option<Body>) -> Result<String> {
    self.req(Method::Put, path, body)
  }

  fn req(&mut self, method: Method, path: String, body: Option<Body>) -> Result<String> {
    let uri = Url::parse(&format!("{}/api/v1{}", self.host, path)).ok().expect("invalid url");
    let mut client = hyper::Client::new();
    let content_type: Mime = Mime(Application, Json, vec![(Attr::Charset, Value::Utf8)]);
    let bound = client.request(method, uri)
      .header(UserAgent("cargopants/0.1.0".to_string()))
      .header(Accept(vec![qitem(content_type.clone())]))
      .header(ContentType(content_type));
    let authenticated = match self.token.clone() {
      Some(auth) => bound.header(Authorization(auth)),
               _ => bound
    };
    let embodied = match body {
      Some(Body { read: r, size: l }) => {
        let reader: &mut Read  = *r.deref_mut();
        authenticated.body(client::Body::SizedBody(reader, l))
      },
      _  => authenticated
    };
    let mut res = match embodied.send() {
      Ok(r)    => r,
      Err(err) => panic!("failed request: {:?}", err)
    };
    let mut body = String::new();
    res.read_to_string(&mut body).map(|_| body)
  }
}

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

  #[test]
  fn it_parses_crate_req() {

  }

  #[bench]
  fn it_benches(b: &mut Bencher) {

  }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
//! Fern is a runtime-configurable rust logging library.
//!
//! Current features:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - output to any combination of:
//!   - log files
//!   - stdout or stderr
//!   - your own custom implementation
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console.
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them.
//! - Acts as a backend to the `log` crate - use `trace!()` through `error!()` to log to the global
//!   fern logger.
//!   - Note that fern can also have loggers separate from the global system. You can always set
//!     your main logger as the global logger, then use other fern loggers manually.
//!
//! Although mostly stabilized, fern is still in development. The library is subject to
//! change in non-backwards-compatible ways before the API is completely stabilized.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Upgrade note for fern `0.2.*`
//! ====
//!
//! As of fern 0.2.0, fern depends on the `log` crate to provide the frontend logging macros and
//! logging levels - you will need to depend on and use both the `fern` and `log` crates.
//!
//!
//! Adding fern as a dependency
//! ===========================
//!
//! In order to use fern, the first thing you'll need to add both the `fern` crate and the `log`
//! crate to the dependencies in your project's `Cargo.toml` file:
//!
//! ```toml
//! # ...
//!
//! [dependencies]
//! # ...
//! log = "0.2.*"
//! fern = "0.2.*"
//!
//! # ...
//! ```
//!
//! After this, you'll need to declare the `log` and `fern` at the top of your main.rs or lib.rs
//! file:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//! # fn main() {}
//! ```
//!
//! Examples
//! ========
//!
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```ignore
//! # // as a workaround for https://github.com/rust-lang/cargo/issues/1474, this test is copied
//! # // into `tests/doc_test_copy.rs` and tested there. Any changes to this doc code block should
//! # // be duplicated there.
//! extern crate fern;
//! extern crate log;
//! extern crate time;
//!
//! let logger_config = fern::DispatchConfig {
//!     format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
//!         // This is a fairly simple format, though it's possible to do more complicated ones.
//!         // This closure can contain any code, as long as it produces a String message.
//!         format!("[{}][{}] {}", time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(), level, msg)
//!     }),
//!     output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
//!     level: log::LogLevelFilter::Trace,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the logging level.
//!
//! Side note: `time::now().strftime("%Y-%m-%d][%H:%M:%S")` is a usage of the `time` library to
//! format the current date/time into a readable string. This particular format will produce a
//! string akin to `2015-01-20][12:55:04`
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2015-01-20][12:55:04][INFO] A message logged at the Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! messages to stdout (the console), and the file "output.log".
//!
//! `level:` is a `log::LogLevelFilter` which describes the minimum level that should be allowed
//! to pass through this logger. Setting this to `LogLevelFilter::Trace` allows all messages to be
//! logged, as `Trace` is the lowest logging level.
//!
//! After creating your logging config, you can pass it to `init_global_logger` to set it as the
//! logger used with logging macros in the `log` crate. This function can only be called once, as
//! the log crate may only be set up once.
//!
//! Note that this function also accepts a `LogLevelFilter`. This is so that you can set a global
//! minimum log level separate from the logger configuration. If you don't have any reason for
//! anything else, just set this to `log::LogLevelFilter::Trace`.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! # let logger_config = fern::DispatchConfig {
//! #     format: Box::new(|msg: &str, _level: &log::LogLevel, _location: &log::LogLocation| {
//! #         format!("{}", msg)
//! #     }),
//! #     output: vec![],
//! #     level: log::LogLevelFilter::Trace,
//! # };
//! if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
//!     panic!("Failed to initialize global logger: {}", e);
//! }
//! ```
//!
//! This uses the `if let Err(e) =` syntax to catch any errors that happen when initializing
//! the logger.
//!
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above
//! tutorial paired with the fern docs should be enough to get you started on configuring a logger
//! for your project.
//!
//! #### Logging
//!
//! With the `log` crate, outputting messages is fairly simple. As long as you are using the log
//! crate with `#[macro_use]`, and you have initialized the global logger as shown above, you can
//! use the log macros to log messages.
//!
//! ```rust
//! // You need to have #[macro_use] to use log macros
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//!
//! # fn main() {
//! # /*
//! fern::init_global_logger(...);
//! # */
//! # fern::init_global_logger(fern::OutputConfig::null(), log::LogLevelFilter::Trace);
//!
//! trace!("Trace message");
//! debug!("Debug message");
//! info!("Info message");
//! warn!("Warning message");
//! error!("Error message");
//! # }
//! ```

extern crate log;

pub use errors::{LogError, InitError};
pub use api::Logger;
pub use config::{DispatchConfig, OutputConfig, IntoLog, init_global_logger};
pub use loggers::NullLogger;

mod api;
mod config;
mod loggers;
mod errors;
<commit_msg>Add html_root_url doc attribute<commit_after>#![deny(missing_docs)]
#![doc(html_root_url = "http://dabo.guru/rust/fern/")]
//! Fern is a runtime-configurable rust logging library.
//!
//! Current features:
//!
//! - Multiple loggers. You can create as many loggers as you need, and configure them separately.
//! - Configurable output format via closures.
//! - Multiple outputs per logger - output to any combination of:
//!   - log files
//!   - stdout or stderr
//!   - your own custom implementation
//! - Each output can have a Level configured, so you can output all log messages to a log file,
//!   and only have warnings and above show up in the console.
//! - You can also define your own custom logging endpoints - have messages end up where you need
//!   them.
//! - Acts as a backend to the `log` crate - use `trace!()` through `error!()` to log to the global
//!   fern logger.
//!   - Note that fern can also have loggers separate from the global system. You can always set
//!     your main logger as the global logger, then use other fern loggers manually.
//!
//! Although mostly stabilized, fern is still in development. The library is subject to
//! change in non-backwards-compatible ways before the API is completely stabilized.
//!
//! This library can only be used while complying to the license terms in the `LICENSE` file.
//!
//! Upgrade note for fern `0.2.*`
//! ====
//!
//! As of fern 0.2.0, fern depends on the `log` crate to provide the frontend logging macros and
//! logging levels - you will need to depend on and use both the `fern` and `log` crates.
//!
//!
//! Adding fern as a dependency
//! ===========================
//!
//! In order to use fern, the first thing you'll need to add both the `fern` crate and the `log`
//! crate to the dependencies in your project's `Cargo.toml` file:
//!
//! ```toml
//! # ...
//!
//! [dependencies]
//! # ...
//! log = "0.2.*"
//! fern = "0.2.*"
//!
//! # ...
//! ```
//!
//! After this, you'll need to declare the `log` and `fern` at the top of your main.rs or lib.rs
//! file:
//!
//! ```
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//! # fn main() {}
//! ```
//!
//! Examples
//! ========
//!
//!
//! Usually, the first thing you want to do is create a logger. In fern, you can do this by first
//! creating a LoggerConfig struct, and then calling `.into_logger()` to turn it into a logger.
//!
//! Here's a logger that simply logs all messages to stdout, and an output.log file, formatting
//! each message with the current date, time, and logging level.
//!
//! ```ignore
//! # // as a workaround for https://github.com/rust-lang/cargo/issues/1474, this test is copied
//! # // into `tests/doc_test_copy.rs` and tested there. Any changes to this doc code block should
//! # // be duplicated there.
//! extern crate fern;
//! extern crate log;
//! extern crate time;
//!
//! let logger_config = fern::DispatchConfig {
//!     format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
//!         // This is a fairly simple format, though it's possible to do more complicated ones.
//!         // This closure can contain any code, as long as it produces a String message.
//!         format!("[{}][{}] {}", time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(), level, msg)
//!     }),
//!     output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
//!     level: log::LogLevelFilter::Trace,
//! };
//! ```
//!
//! In the above example, here's what each part does.
//!
//! `format:` is a closure which all messages will be run through. In this example, use a
//! format!() macro to format the messages using the logging level.
//!
//! Side note: `time::now().strftime("%Y-%m-%d][%H:%M:%S")` is a usage of the `time` library to
//! format the current date/time into a readable string. This particular format will produce a
//! string akin to `2015-01-20][12:55:04`
//!
//! With this formatting, the final output of the logger will look something like:
//!
//! ```text
//! [2015-01-20][12:55:04][INFO] A message logged at the Info logging level.
//! ```
//!
//! `output:` is a Vec<> of other configurations to send the messages to. In this example, we send
//! messages to stdout (the console), and the file "output.log".
//!
//! `level:` is a `log::LogLevelFilter` which describes the minimum level that should be allowed
//! to pass through this logger. Setting this to `LogLevelFilter::Trace` allows all messages to be
//! logged, as `Trace` is the lowest logging level.
//!
//! After creating your logging config, you can pass it to `init_global_logger` to set it as the
//! logger used with logging macros in the `log` crate. This function can only be called once, as
//! the log crate may only be set up once.
//!
//! Note that this function also accepts a `LogLevelFilter`. This is so that you can set a global
//! minimum log level separate from the logger configuration. If you don't have any reason for
//! anything else, just set this to `log::LogLevelFilter::Trace`.
//!
//! ```rust
//! # extern crate fern;
//! # extern crate log;
//! # let logger_config = fern::DispatchConfig {
//! #     format: Box::new(|msg: &str, _level: &log::LogLevel, _location: &log::LogLocation| {
//! #         format!("{}", msg)
//! #     }),
//! #     output: vec![],
//! #     level: log::LogLevelFilter::Trace,
//! # };
//! if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
//!     panic!("Failed to initialize global logger: {}", e);
//! }
//! ```
//!
//! This uses the `if let Err(e) =` syntax to catch any errors that happen when initializing
//! the logger.
//!
//!
//! Eventually, this section will contain a few more examples as well. For now though, the above
//! tutorial paired with the fern docs should be enough to get you started on configuring a logger
//! for your project.
//!
//! #### Logging
//!
//! With the `log` crate, outputting messages is fairly simple. As long as you are using the log
//! crate with `#[macro_use]`, and you have initialized the global logger as shown above, you can
//! use the log macros to log messages.
//!
//! ```rust
//! // You need to have #[macro_use] to use log macros
//! #[macro_use]
//! extern crate log;
//! extern crate fern;
//!
//! # fn main() {
//! # /*
//! fern::init_global_logger(...);
//! # */
//! # fern::init_global_logger(fern::OutputConfig::null(), log::LogLevelFilter::Trace);
//!
//! trace!("Trace message");
//! debug!("Debug message");
//! info!("Info message");
//! warn!("Warning message");
//! error!("Error message");
//! # }
//! ```

extern crate log;

pub use errors::{LogError, InitError};
pub use api::Logger;
pub use config::{DispatchConfig, OutputConfig, IntoLog, init_global_logger};
pub use loggers::NullLogger;

mod api;
mod config;
mod loggers;
mod errors;
<|endoftext|>


<commit_before>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
#![warn(missing_docs)]

extern crate serde;
#[cfg(test)]
extern crate bincode;

pub mod grid;
pub mod engine;
pub mod traits;
mod utils;

mod examples;
<commit_msg>Notes about lib in outline.<commit_after>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
#![warn(missing_docs)]

//! Library for building cellular automata.
//!
//! Cellular automata made by supplying some cell to
//! grid and "engine". Grid stores all cells, chooses
//! how to iterate them, how to split itself etc.
//! Engine runs grid evolution in some way and passes
//! updates to so-called consumers.
//!
//! Consumers are interface parts to outer world.
//! They can be GUI, Web or simple file writers.

extern crate serde;
#[cfg(test)]
extern crate bincode;

pub mod grid;
pub mod engine;
pub mod traits;
mod utils;

mod examples;
<|endoftext|>