<commit_before>#![feature(libc)]

#![allow(dead_code)]
#![allow(non_camel_case_types)]

extern crate libc;
use libc::{c_int, size_t, c_void};
use std::mem;

/**
 * Abstraction of libnl core functionality
 */
#[link(name="nl-3")]
extern "C" {
	// Exposed socket functions
	fn nl_socket_alloc() -> *const nl_sock;
	fn nl_socket_free(socket: *const nl_sock);
	fn nl_socket_get_fd(socket: *const nl_sock) -> i32;
	fn nl_socket_set_buffer_size(socket: *const nl_sock, rxbuf: c_int, txbuf: c_int) -> i32;

	fn nl_socket_set_local_port(socket: *const nl_sock, port: u32);
	fn nl_socket_get_local_port(socket: *const nl_sock) -> u32;

	fn nl_connect(socket: *const nl_sock, protocol: u32) -> i32;
	fn nl_close(socket: *const nl_sock);

	fn nl_socket_set_cb(socket: *const nl_sock, cb: *const nl_cb);
	fn nl_socket_get_cb(socket: *const nl_sock) -> nl_cb;

	// Exposed socket transceiver
	fn nl_send_simple(socket: *const nl_sock, msg_type: c_int, flags: c_int, buf: *const u8, size: c_int) -> i32;

	// Exposed msg functions
	fn nlmsg_alloc() -> *const nl_msg;
	fn nlmsg_free(msg: *const nl_msg);
	fn nlmsg_append(msg: *const nl_msg, data: *const c_void, len: size_t, pad: c_int) -> i32;
    fn nlmsg_put(msg: *const nl_msg, pid: u32, seq: u32, mtype: c_int, payload: c_int, flags: c_int) -> *const nlmsghdr;
    fn nlmsg_datalen(nlh: *const nlmsghdr) -> i32;

}

// exposed structures - these are wrapped
#[repr(C)]
struct nl_sock;
#[repr(C)]
struct nl_msg;
#[repr(C)]
struct nl_cb;
#[repr(C)]
struct nlmsghdr;

// RSNL datatypes wrapping the libnl data structures
pub struct socket {
	ptr: *const nl_sock
}

/* library version of nlmsghdr
 * the name is altered to differentiate
 * between the native libnl and rsnl
 */
pub struct rsnl_msghdr {
	nlmsg_len: u32,
	nlmsg_type: u16,
	nlmsg_flags: u16,
	nlmsg_seq: u32,
	nlmsg_pid: u32
}

pub struct msg {
	ptr: *const nl_msg,
    hdr: Option<*const nlmsghdr>,
}

pub enum NetlinkProtocol {
	route,
	unused,
	usersock,
	firewall,
	sock_diag,
	nflog,
	xfrm,
	selinux,
	iscsi,
	audit,
	fib_lookup,
	connector,
	netfilter,
	ip6_fw,
	dnrtmsg,
	kobject_uevent,
	DMEVENTS,
	scsitransport,
	ecryptfs,
	rdma,
	crypto,
	zu= 30
}

impl socket {
	pub fn new() -> socket {
		unsafe {
			let nlptr = nl_socket_alloc();
			socket {
				ptr: nlptr
			}
		}
	}

	pub fn free(&self) {
		unsafe {
			nl_socket_free(self.ptr)
		}
	}

	pub fn set_buffer_size(&self, rxbuf: c_int, txbuf: c_int) -> i32 {
		unsafe {
			nl_socket_set_buffer_size(self.ptr, rxbuf, txbuf)
		}
	}

	pub fn connect(&self, protocol: NetlinkProtocol) -> i32 {
		unsafe { nl_connect(self.ptr, protocol as u32) }
	}

	pub fn close(&self) {
		unsafe{ nl_close(self.ptr) }
	}

	pub fn get_fd(&self) -> i32 {
		unsafe { nl_socket_get_fd(self.ptr) }
	}

	pub fn get_local_port(&self) -> u32 {
		unsafe { nl_socket_get_local_port(self.ptr) }
	}

	pub fn set_local_port(&self, port: u32) {
		unsafe { nl_socket_set_local_port(self.ptr, port) }
	}

	pub fn send_simple(&self, msg_type: c_int, flags: c_int, buf: *const u8, size: c_int) -> i32 {
		unsafe { nl_send_simple(self.ptr, msg_type, flags, buf, size) as i32 }
	}
}

impl msg {

	pub fn new() -> msg {
        unsafe {
            let nlmsg = nlmsg_alloc();
            msg {
                ptr: nlmsg,
                hdr: None
            }
        }
	}

	pub fn free(&self) {
		unsafe{ nlmsg_free(self.ptr); }
	}

    pub fn append<T>(&self, data: &T, len: u32, pad: i32) -> i32 {
        unsafe {
            let vptr: *const c_void = mem::transmute(data);
            nlmsg_append(self.ptr, vptr, len as size_t, pad as c_int) as i32
        }
    }

    pub fn put(&mut self, pid: u32, seq: u32, mtype: i32, payload: i32, flags: i32) -> bool {
        unsafe {
            let hdr = nlmsg_put(self.ptr, pid, seq, mtype as c_int, payload as c_int, flags as c_int);

            match hdr as i32 {
                0x0 => false,
                _ => {
                    self.hdr = Some(hdr);
                    true
                }
            }
        }
    }

    pub fn data_len(&self) -> i32 {

        match self.hdr {
            None => 0,
            Some(hdr) => {
                unsafe { nlmsg_datalen(hdr) }
            }
        }
    }
}
<commit_msg>Remove rsnl_msghdr<commit_after>#![feature(libc)]

#![allow(dead_code)]
#![allow(non_camel_case_types)]

extern crate libc;
use libc::{c_int, size_t, c_void};
use std::mem;

/**
 * Abstraction of libnl core functionality
 */
#[link(name="nl-3")]
extern "C" {
	// Exposed socket functions
	fn nl_socket_alloc() -> *const nl_sock;
	fn nl_socket_free(socket: *const nl_sock);
	fn nl_socket_get_fd(socket: *const nl_sock) -> i32;
	fn nl_socket_set_buffer_size(socket: *const nl_sock, rxbuf: c_int, txbuf: c_int) -> i32;

	fn nl_socket_set_local_port(socket: *const nl_sock, port: u32);
	fn nl_socket_get_local_port(socket: *const nl_sock) -> u32;

	fn nl_connect(socket: *const nl_sock, protocol: u32) -> i32;
	fn nl_close(socket: *const nl_sock);

	fn nl_socket_set_cb(socket: *const nl_sock, cb: *const nl_cb);
	fn nl_socket_get_cb(socket: *const nl_sock) -> nl_cb;

	// Exposed socket transceiver
	fn nl_send_simple(socket: *const nl_sock, msg_type: c_int, flags: c_int, buf: *const u8, size: c_int) -> i32;

	// Exposed msg functions
	fn nlmsg_alloc() -> *const nl_msg;
	fn nlmsg_free(msg: *const nl_msg);
	fn nlmsg_append(msg: *const nl_msg, data: *const c_void, len: size_t, pad: c_int) -> i32;
    fn nlmsg_put(msg: *const nl_msg, pid: u32, seq: u32, mtype: c_int, payload: c_int, flags: c_int) -> *const nlmsghdr;
    fn nlmsg_datalen(nlh: *const nlmsghdr) -> i32;

}

// exposed structures - these are wrapped
#[repr(C)]
struct nl_sock;
#[repr(C)]
struct nl_msg;
#[repr(C)]
struct nl_cb;
#[repr(C)]
struct nlmsghdr;

// RSNL datatypes wrapping the libnl data structures
pub struct socket {
	ptr: *const nl_sock
}

pub struct msg {
	ptr: *const nl_msg,
    hdr: Option<*const nlmsghdr>,
}

pub enum NetlinkProtocol {
	route,
	unused,
	usersock,
	firewall,
	sock_diag,
	nflog,
	xfrm,
	selinux,
	iscsi,
	audit,
	fib_lookup,
	connector,
	netfilter,
	ip6_fw,
	dnrtmsg,
	kobject_uevent,
	DMEVENTS,
	scsitransport,
	ecryptfs,
	rdma,
	crypto,
	zu= 30
}

impl socket {
	pub fn new() -> socket {
		unsafe {
			let nlptr = nl_socket_alloc();
			socket {
				ptr: nlptr
			}
		}
	}

	pub fn free(&self) {
		unsafe {
			nl_socket_free(self.ptr)
		}
	}

	pub fn set_buffer_size(&self, rxbuf: c_int, txbuf: c_int) -> i32 {
		unsafe {
			nl_socket_set_buffer_size(self.ptr, rxbuf, txbuf)
		}
	}

	pub fn connect(&self, protocol: NetlinkProtocol) -> i32 {
		unsafe { nl_connect(self.ptr, protocol as u32) }
	}

	pub fn close(&self) {
		unsafe{ nl_close(self.ptr) }
	}

	pub fn get_fd(&self) -> i32 {
		unsafe { nl_socket_get_fd(self.ptr) }
	}

	pub fn get_local_port(&self) -> u32 {
		unsafe { nl_socket_get_local_port(self.ptr) }
	}

	pub fn set_local_port(&self, port: u32) {
		unsafe { nl_socket_set_local_port(self.ptr, port) }
	}

	pub fn send_simple(&self, msg_type: c_int, flags: c_int, buf: *const u8, size: c_int) -> i32 {
		unsafe { nl_send_simple(self.ptr, msg_type, flags, buf, size) as i32 }
	}
}

impl msg {

	pub fn new() -> msg {
        unsafe {
            let nlmsg = nlmsg_alloc();
            msg {
                ptr: nlmsg,
                hdr: None
            }
        }
	}

	pub fn free(&self) {
		unsafe{ nlmsg_free(self.ptr); }
	}

    pub fn append<T>(&self, data: &T, len: u32, pad: i32) -> i32 {
        unsafe {
            let vptr: *const c_void = mem::transmute(data);
            nlmsg_append(self.ptr, vptr, len as size_t, pad as c_int) as i32
        }
    }

    pub fn put(&mut self, pid: u32, seq: u32, mtype: i32, payload: i32, flags: i32) -> bool {
        unsafe {
            let hdr = nlmsg_put(self.ptr, pid, seq, mtype as c_int, payload as c_int, flags as c_int);

            match hdr as i32 {
                0x0 => false,
                _ => {
                    self.hdr = Some(hdr);
                    true
                }
            }
        }
    }

    pub fn data_len(&self) -> i32 {

        match self.hdr {
            None => 0,
            Some(hdr) => {
                unsafe { nlmsg_datalen(hdr) }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! It can be useful to not have to worry about missing keys in a map.
//! If a key is requested that doesn't have a value a default value is simply returned.
//! This is exactly what this library provides.
//!
//! ## Examples

//! ### Counter
//! A clear use case of this is when counting the unique elements in a list.
//! Here you want to add one to the existing value in the map for that key.
//! This is a problem for the first addition when there's no value for the key yet.
//! With this library you can specify when creating the map that the default value should be zero.
//!

//! ```rust
//! # use defaultmap::*;
//! let nums = [1, 4, 3, 3, 4, 2, 4];
//! let mut counts:  DefaultHashMap<i32, i32> = DefaultHashMap::new(0);
//! // DefaultHashMap::default() is equivalent.
//!
//! for num in nums.into_iter() {
//!     counts[*num] += 1;
//! }
//!
//! println!("{:?}", counts);
//! // DefaultHashMap { map: {1: 1, 3: 2, 2: 1, 4: 3}, default: 0 }
//!
//! # assert_eq!(1, counts[1]);
//! # assert_eq!(1, counts[2]);
//! # assert_eq!(2, counts[3]);
//! # assert_eq!(3, counts[4]);
//! ```
//!

//! ### Synonym lists
//!
//! Another way the default map can be used is using a map filled with other collections, such as a
//! `Vec`, a `HashMap` or even another default map.
//! Next follows some code to create a map where we start with tuples of synonyms and we end with a
//! map that contains the list of synonyms for each word.
//!
//! ```rust
//! # use defaultmap::*;
//!
//! let synonym_tuples = [
//!     ("nice", "sweet"),
//!     ("sweet", "candy"),
//!     ("nice", "entertaining"),
//!     ("nice", "good"),
//!     ("entertaining", "absorbing"),
//! ];
//!
//! let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::new(vec![]);
//! // DefaultHashMap::default() is equivalent.
//!
//! for &(l, r) in synonym_tuples.into_iter() {
//!     synonym_map[l].push(r);
//!     synonym_map[r].push(l);
//! }
//!
//! assert_eq!(synonym_map["good"], vec!["nice"]);
//! assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
//! assert_eq!(synonym_map["evil"], Vec::<&str>::new());
//! ```
//!

pub use hashmap::DefaultHashMap;

mod hashmap {
    use std::hash::Hash;
    use std::collections::HashMap;
    use std::collections::hash_map::*;
    use std::borrow::Borrow;
    use std::ops::{Index, IndexMut};

    /// A `HashMap` that has returns a default when keys are accessed that are not present.
    #[derive(PartialEq, Eq, Debug)]
    pub struct DefaultHashMap<K: Eq + Hash, V: Clone> {
        map: HashMap<K, V>,
        default: V,
    }

    impl<K: Eq + Hash, V: Default + Clone> Default for DefaultHashMap<K, V> {
        /// The `default()` constructor creates an empty DefaultHashMap with the default of `V`
        /// as the default for missing keys.
        /// This is desired default for most use cases, if your case requires a
        /// different default you should use the `new()` constructor.
        fn default() -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::default(),
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Default + Clone> From<HashMap<K, V>> for DefaultHashMap<K, V> {
        /// If you already have a `HashMap` that you would like to convert to a
        /// `DefaultHashMap` you can use the `into()` method on the `HashMap` or the
        /// `from()` constructor of `DefaultHashMap`.
        /// The default value for missing keys will be `V::default()`,
        /// if this is not desired `DefaultHashMap::new_with_map()` should be used.
        fn from(map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Clone> Into<HashMap<K, V>> for DefaultHashMap<K, V> {
        /// The into method can be used to convert a `DefaultHashMap` back into a
        /// `HashMap`.
        fn into(self) -> HashMap<K, V> {
            self.map
        }
    }

    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        /// Creates an empty `DefaultHashmap` with `default` as the default for missing keys.
        /// When the provided `default` is equivalent to `V::default()` it is preferred to use
        /// `DefaultHashMap::default()` instead.
        pub fn new(default: V) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::new(),
                default: default,
            }
        }

        /// Creates a `DefaultHashMap` based on a default and an already existing `HashMap`.
        /// If `V::default()` is the supplied default, usage of the `from()` constructor or the
        /// `into()` method on the original `HashMap` is preferred.
        pub fn new_with_map(default: V, map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: default,
            }
        }

        /// Returns a reference to the value stored for the provided key.
        /// If the key is not in the `DefaultHashMap` a reference to the default value is returned.
        /// Usually the `map[key]` method of retrieving keys is prefered over using `get` directly.
        /// This method accepts both references and owned values as the key.
        pub fn get<Q, QB: Borrow<Q>>(&self, key: QB) -> &V
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.get(key.borrow()).unwrap_or(&self.default)
        }

        /// Returns a mutable reference to the value stored for the provided key.
        /// If there is no value stored for the key the default value is first inserted for this
        /// key before returning the reference.
        /// Usually the `map[key] = new_val` is prefered over using `get_mut` directly.
        /// This method only accepts owned values as the key.
        pub fn get_mut(&mut self, key: K) -> &mut V {
            self.map.entry(key).or_insert(self.default.clone())
        }
    }

    /// Implements the `Index` trait so you can do `map[key]`.
    /// Nonmutable indexing can be done both by passing a reference or an owned value as the key.
    impl<'a, K: Eq + Hash, KB: Borrow<K>, V: Clone> Index<KB> for DefaultHashMap<K, V> {
        type Output = V;

        fn index(&self, index: KB) -> &V {
            self.get(index)
        }
    }

    /// Implements the `IndexMut` trait so you can do `map[key] = val`.
    /// Mutably indexing can only be done when passing an owned value as the key.
    impl<K: Eq + Hash, V: Clone> IndexMut<K> for DefaultHashMap<K, V> {
        #[inline]
        fn index_mut(&mut self, index: K) -> &mut V {
            self.get_mut(index)
        }
    }

    /// These methods simply forward to the underlying `HashMap`, see that
    /// [documentation](https://doc.rust-lang.org/std/collections/struct.HashMap.html) for
    /// the usage of these methods.
    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        pub fn capacity(&self) -> usize {
            self.map.capacity()
        }
        #[inline]
        pub fn reserve(&mut self, additional: usize) {
            self.map.reserve(additional)
        }
        #[inline]
        pub fn shrink_to_fit(&mut self) {
            self.map.shrink_to_fit()
        }
        #[inline]
        pub fn keys(&self) -> Keys<K, V> {
            self.map.keys()
        }
        #[inline]
        pub fn values(&self) -> Values<K, V> {
            self.map.values()
        }
        #[inline]
        pub fn values_mut(&mut self) -> ValuesMut<K, V> {
            self.map.values_mut()
        }
        #[inline]
        pub fn iter(&self) -> Iter<K, V> {
            self.map.iter()
        }
        #[inline]
        pub fn iter_mut(&mut self) -> IterMut<K, V> {
            self.map.iter_mut()
        }
        #[inline]
        pub fn entry(&mut self, key: K) -> Entry<K, V> {
            self.map.entry(key)
        }
        #[inline]
        pub fn len(&self) -> usize {
            self.map.len()
        }
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.map.is_empty()
        }
        #[inline]
        pub fn drain(&mut self) -> Drain<K, V> {
            self.map.drain()
        }
        #[inline]
        pub fn clear(&mut self) {
            self.map.clear()
        }
        #[inline]
        pub fn insert(&mut self, k: K, v: V) -> Option<V> {
            self.map.insert(k, v)
        }
        #[inline]
        pub fn contains_key<Q>(&self, k: &Q) -> (bool)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.contains_key(k)
        }
        #[inline]
        pub fn remove<Q>(&mut self, k: &Q) -> (Option<V>)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.remove(k)
        }
    }

}

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

    #[test]
    fn add() {
        let mut map: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        *map.get_mut(0) += 1;
        map[1] += 4;
        map[2] = map[0] + map.get(&1);
        assert_eq!(*map.get(0), 1);
        assert_eq!(*map.get(&0), 1);
        assert_eq!(map[0], 1);
        assert_eq!(map[&0], 1);
        assert_eq!(*map.get(&1), 4);
        assert_eq!(*map.get(&2), 5);
        assert_eq!(*map.get(999), 0);
        assert_eq!(*map.get(&999), 0);
        assert_eq!(map[999], 0);
        assert_eq!(map[&999], 0);
    }

    #[test]
    fn counter() {
        let nums = [1, 4, 3, 3, 4, 2, 4];
        let mut counts: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        for num in nums.into_iter() {
            counts[*num] += 1;
        }

        assert_eq!(1, counts[1]);
        assert_eq!(1, counts[2]);
        assert_eq!(2, counts[3]);
        assert_eq!(3, counts[4]);
        assert_eq!(0, counts[5]);
    }

    #[test]
    fn synonyms() {
        let synonym_tuples = [("nice", "sweet"),
                              ("sweet", "candy"),
                              ("nice", "entertaining"),
                              ("nice", "good"),
                              ("entertaining", "absorbing")];

        let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::default();

        for &(l, r) in synonym_tuples.into_iter() {
            synonym_map[l].push(r);
            synonym_map[r].push(l);
        }

        println!("{:#?}", synonym_map);
        assert_eq!(synonym_map["good"], vec!["nice"]);
        assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
        assert_eq!(synonym_map["evil"], Vec::<&str>::new());
        // assert!(false)
    }

    #[derive(Clone)]
    struct Clonable;

    #[derive(Default, Clone)]
    struct DefaultableValue;

    #[derive(Hash, Eq, PartialEq)]
    struct Hashable(i32);

    #[test]
    fn minimal_derives() {
        let _: DefaultHashMap<Hashable, Clonable> = DefaultHashMap::new(Clonable);
        let _: DefaultHashMap<Hashable, DefaultableValue> = DefaultHashMap::default();
    }

    #[test]
    fn from() {
        let normal: HashMap<i32, i32> = vec![(0, 1), (2, 3)].into_iter().collect();
        let mut default: DefaultHashMap<_, _> = normal.into();
        default.get_mut(4);
        assert_eq!(default[0], 1);
        assert_eq!(default[2], 3);
        assert_eq!(default[1], 0);
        assert_eq!(default[4], 0);
        let expected: HashMap<i32, i32> = vec![(0, 1), (2, 3), (4, 0)].into_iter().collect();
        assert_eq!(expected, default.into());
    }

}
<commit_msg>Add macro copied from maplit<commit_after>//! It can be useful to not have to worry about missing keys in a map.
//! If a key is requested that doesn't have a value a default value is simply returned.
//! This is exactly what this library provides.
//!
//! ## Examples

//! ### Counter
//! A clear use case of this is when counting the unique elements in a list.
//! Here you want to add one to the existing value in the map for that key.
//! This is a problem for the first addition when there's no value for the key yet.
//! With this library you can specify when creating the map that the default value should be zero.
//!

//! ```rust
//! # use defaultmap::*;
//! let nums = [1, 4, 3, 3, 4, 2, 4];
//! let mut counts:  DefaultHashMap<i32, i32> = DefaultHashMap::new(0);
//! // DefaultHashMap::default() is equivalent.
//!
//! for num in nums.into_iter() {
//!     counts[*num] += 1;
//! }
//!
//! println!("{:?}", counts);
//! // DefaultHashMap { map: {1: 1, 3: 2, 2: 1, 4: 3}, default: 0 }
//!
//! # assert_eq!(1, counts[1]);
//! # assert_eq!(1, counts[2]);
//! # assert_eq!(2, counts[3]);
//! # assert_eq!(3, counts[4]);
//! ```
//!

//! ### Synonym lists
//!
//! Another way the default map can be used is using a map filled with other collections, such as a
//! `Vec`, a `HashMap` or even another default map.
//! Next follows some code to create a map where we start with tuples of synonyms and we end with a
//! map that contains the list of synonyms for each word.
//!
//! ```rust
//! # use defaultmap::*;
//!
//! let synonym_tuples = [
//!     ("nice", "sweet"),
//!     ("sweet", "candy"),
//!     ("nice", "entertaining"),
//!     ("nice", "good"),
//!     ("entertaining", "absorbing"),
//! ];
//!
//! let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::new(vec![]);
//! // DefaultHashMap::default() is equivalent.
//!
//! for &(l, r) in synonym_tuples.into_iter() {
//!     synonym_map[l].push(r);
//!     synonym_map[r].push(l);
//! }
//!
//! assert_eq!(synonym_map["good"], vec!["nice"]);
//! assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
//! assert_eq!(synonym_map["evil"], Vec::<&str>::new());
//! ```
//!

pub use hashmap::DefaultHashMap;

mod hashmap {
    use std::hash::Hash;
    use std::collections::HashMap;
    use std::collections::hash_map::*;
    use std::borrow::Borrow;
    use std::ops::{Index, IndexMut};

    /// A `HashMap` that has returns a default when keys are accessed that are not present.
    #[derive(PartialEq, Eq, Debug)]
    pub struct DefaultHashMap<K: Eq + Hash, V: Clone> {
        map: HashMap<K, V>,
        default: V,
    }

    impl<K: Eq + Hash, V: Default + Clone> Default for DefaultHashMap<K, V> {
        /// The `default()` constructor creates an empty DefaultHashMap with the default of `V`
        /// as the default for missing keys.
        /// This is desired default for most use cases, if your case requires a
        /// different default you should use the `new()` constructor.
        fn default() -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::default(),
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Default + Clone> From<HashMap<K, V>> for DefaultHashMap<K, V> {
        /// If you already have a `HashMap` that you would like to convert to a
        /// `DefaultHashMap` you can use the `into()` method on the `HashMap` or the
        /// `from()` constructor of `DefaultHashMap`.
        /// The default value for missing keys will be `V::default()`,
        /// if this is not desired `DefaultHashMap::new_with_map()` should be used.
        fn from(map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Clone> Into<HashMap<K, V>> for DefaultHashMap<K, V> {
        /// The into method can be used to convert a `DefaultHashMap` back into a
        /// `HashMap`.
        fn into(self) -> HashMap<K, V> {
            self.map
        }
    }

    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        /// Creates an empty `DefaultHashmap` with `default` as the default for missing keys.
        /// When the provided `default` is equivalent to `V::default()` it is preferred to use
        /// `DefaultHashMap::default()` instead.
        pub fn new(default: V) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::new(),
                default: default,
            }
        }

        /// Creates a `DefaultHashMap` based on a default and an already existing `HashMap`.
        /// If `V::default()` is the supplied default, usage of the `from()` constructor or the
        /// `into()` method on the original `HashMap` is preferred.
        pub fn new_with_map(default: V, map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: default,
            }
        }

        /// Returns a reference to the value stored for the provided key.
        /// If the key is not in the `DefaultHashMap` a reference to the default value is returned.
        /// Usually the `map[key]` method of retrieving keys is prefered over using `get` directly.
        /// This method accepts both references and owned values as the key.
        pub fn get<Q, QB: Borrow<Q>>(&self, key: QB) -> &V
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.get(key.borrow()).unwrap_or(&self.default)
        }

        /// Returns a mutable reference to the value stored for the provided key.
        /// If there is no value stored for the key the default value is first inserted for this
        /// key before returning the reference.
        /// Usually the `map[key] = new_val` is prefered over using `get_mut` directly.
        /// This method only accepts owned values as the key.
        pub fn get_mut(&mut self, key: K) -> &mut V {
            self.map.entry(key).or_insert(self.default.clone())
        }
    }

    /// Implements the `Index` trait so you can do `map[key]`.
    /// Nonmutable indexing can be done both by passing a reference or an owned value as the key.
    impl<'a, K: Eq + Hash, KB: Borrow<K>, V: Clone> Index<KB> for DefaultHashMap<K, V> {
        type Output = V;

        fn index(&self, index: KB) -> &V {
            self.get(index)
        }
    }

    /// Implements the `IndexMut` trait so you can do `map[key] = val`.
    /// Mutably indexing can only be done when passing an owned value as the key.
    impl<K: Eq + Hash, V: Clone> IndexMut<K> for DefaultHashMap<K, V> {
        #[inline]
        fn index_mut(&mut self, index: K) -> &mut V {
            self.get_mut(index)
        }
    }

    /// These methods simply forward to the underlying `HashMap`, see that
    /// [documentation](https://doc.rust-lang.org/std/collections/struct.HashMap.html) for
    /// the usage of these methods.
    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        pub fn capacity(&self) -> usize {
            self.map.capacity()
        }
        #[inline]
        pub fn reserve(&mut self, additional: usize) {
            self.map.reserve(additional)
        }
        #[inline]
        pub fn shrink_to_fit(&mut self) {
            self.map.shrink_to_fit()
        }
        #[inline]
        pub fn keys(&self) -> Keys<K, V> {
            self.map.keys()
        }
        #[inline]
        pub fn values(&self) -> Values<K, V> {
            self.map.values()
        }
        #[inline]
        pub fn values_mut(&mut self) -> ValuesMut<K, V> {
            self.map.values_mut()
        }
        #[inline]
        pub fn iter(&self) -> Iter<K, V> {
            self.map.iter()
        }
        #[inline]
        pub fn iter_mut(&mut self) -> IterMut<K, V> {
            self.map.iter_mut()
        }
        #[inline]
        pub fn entry(&mut self, key: K) -> Entry<K, V> {
            self.map.entry(key)
        }
        #[inline]
        pub fn len(&self) -> usize {
            self.map.len()
        }
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.map.is_empty()
        }
        #[inline]
        pub fn drain(&mut self) -> Drain<K, V> {
            self.map.drain()
        }
        #[inline]
        pub fn clear(&mut self) {
            self.map.clear()
        }
        #[inline]
        pub fn insert(&mut self, k: K, v: V) -> Option<V> {
            self.map.insert(k, v)
        }
        #[inline]
        pub fn contains_key<Q>(&self, k: &Q) -> (bool)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.contains_key(k)
        }
        #[inline]
        pub fn remove<Q>(&mut self, k: &Q) -> (Option<V>)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.remove(k)
        }
    }

}

// Copied almost verbatim from maplit
macro_rules! defaulthashmap {
    (@single $($x:tt)*) => (());
    (@count $($rest:expr),*) => (<[()]>::len(&[$(defaulthashmap!(@single $rest)),*]));

    ($($key:expr => $value:expr,)+) => { defaulthashmap!($($key => $value),+) };
    ($($key:expr => $value:expr),*) => {
        {
            let _cap = defaulthashmap!(@count $($key),*);
            let mut _map = ::std::collections::HashMap::with_capacity(_cap);
            $(
                _map.insert($key, $value);
            )*
            let _defmap: DefaultHashMap<_,_> = _map.into();
            _defmap
        }
    };
}

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

    #[test]
    fn macro_test() {
        let macro_map: DefaultHashMap<i32, i32> = defaulthashmap!{};
        let normal_map = DefaultHashMap::<i32, i32>::default();
        assert_eq!(macro_map, normal_map);

        let macro_map: DefaultHashMap<_, _> = defaulthashmap!{
            1 => 2,
            2 => 3,
        };
        let mut normal_map = DefaultHashMap::<_, _>::default();
        normal_map[1] = 2;
        normal_map[2] = 3;
        assert_eq!(macro_map, normal_map);
    }

    #[test]
    fn add() {
        let mut map: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        *map.get_mut(0) += 1;
        map[1] += 4;
        map[2] = map[0] + map.get(&1);
        assert_eq!(*map.get(0), 1);
        assert_eq!(*map.get(&0), 1);
        assert_eq!(map[0], 1);
        assert_eq!(map[&0], 1);
        assert_eq!(*map.get(&1), 4);
        assert_eq!(*map.get(&2), 5);
        assert_eq!(*map.get(999), 0);
        assert_eq!(*map.get(&999), 0);
        assert_eq!(map[999], 0);
        assert_eq!(map[&999], 0);
    }

    #[test]
    fn counter() {
        let nums = [1, 4, 3, 3, 4, 2, 4];
        let mut counts: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        for num in nums.into_iter() {
            counts[*num] += 1;
        }

        assert_eq!(1, counts[1]);
        assert_eq!(1, counts[2]);
        assert_eq!(2, counts[3]);
        assert_eq!(3, counts[4]);
        assert_eq!(0, counts[5]);
    }

    #[test]
    fn synonyms() {
        let synonym_tuples = [("nice", "sweet"),
                              ("sweet", "candy"),
                              ("nice", "entertaining"),
                              ("nice", "good"),
                              ("entertaining", "absorbing")];

        let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::default();

        for &(l, r) in synonym_tuples.into_iter() {
            synonym_map[l].push(r);
            synonym_map[r].push(l);
        }

        println!("{:#?}", synonym_map);
        assert_eq!(synonym_map["good"], vec!["nice"]);
        assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
        assert_eq!(synonym_map["evil"], Vec::<&str>::new());
        // assert!(false)
    }

    #[derive(Clone)]
    struct Clonable;

    #[derive(Default, Clone)]
    struct DefaultableValue;

    #[derive(Hash, Eq, PartialEq)]
    struct Hashable(i32);

    #[test]
    fn minimal_derives() {
        let _: DefaultHashMap<Hashable, Clonable> = DefaultHashMap::new(Clonable);
        let _: DefaultHashMap<Hashable, DefaultableValue> = DefaultHashMap::default();
    }

    #[test]
    fn from() {
        let normal: HashMap<i32, i32> = vec![(0, 1), (2, 3)].into_iter().collect();
        let mut default: DefaultHashMap<_, _> = normal.into();
        default.get_mut(4);
        assert_eq!(default[0], 1);
        assert_eq!(default[2], 3);
        assert_eq!(default[1], 0);
        assert_eq!(default[4], 0);
        let expected: HashMap<i32, i32> = vec![(0, 1), (2, 3), (4, 0)].into_iter().collect();
        assert_eq!(expected, default.into());
    }

}
<|endoftext|>


<commit_before>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UString {
    /// Appends a character to the end of the string.
    pub fn push(&mut self, c: char) {
        self.0.push(c);
    }

    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }

    pub fn starts_with<'a, T: AsRef<UStr>>(&self, prefix: &'a T) -> bool {
        self.0.starts_with(&prefix.as_ref().0)
    }

    pub fn ends_with<'a, T: AsRef<UStr>>(&self, suffix: &'a T) -> bool {
        self.0.ends_with(&suffix.as_ref().0)
    }
}

impl AsRef<UStr> for UString {
    fn as_ref(&self) -> &UStr {
        &self
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<char> for UString {
    fn from(c: char) -> UString {
        UString(vec![c])
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UString> for String {
    fn from(string: &UString) -> String {
        String::from_iter(string.into_iter().cloned())
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

#[derive(Debug)]
pub struct Iter<'a>(&'a [char]);

#[derive(Debug)]
pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<commit_msg>Derive Eq for UStr slices<commit_after>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
#[derive(PartialEq, Eq)]
pub struct UStr([char]);

impl UString {
    /// Appends a character to the end of the string.
    pub fn push(&mut self, c: char) {
        self.0.push(c);
    }

    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }

    pub fn starts_with<'a, T: AsRef<UStr>>(&self, prefix: &'a T) -> bool {
        self.0.starts_with(&prefix.as_ref().0)
    }

    pub fn ends_with<'a, T: AsRef<UStr>>(&self, suffix: &'a T) -> bool {
        self.0.ends_with(&suffix.as_ref().0)
    }
}

impl AsRef<UStr> for UString {
    fn as_ref(&self) -> &UStr {
        &self
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<char> for UString {
    fn from(c: char) -> UString {
        UString(vec![c])
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UString> for String {
    fn from(string: &UString) -> String {
        String::from_iter(string.into_iter().cloned())
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

#[derive(Debug)]
pub struct Iter<'a>(&'a [char]);

#[derive(Debug)]
pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub trait FromAscii: Sized {
    type Err;

    fn from_ascii(s: &[u8]) -> Result<Self, Self::Err>;
}

/// An error returned when parsing a `bool` from a ascii string fails.
#[derive(Debug, Clone, PartialEq)]
pub enum ParseBoolError {
    ParseBoolError
}

impl fmt::Display for ParseBoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "provided string was not `true` or `false`".fmt(f)
    }
}

impl FromAscii for bool {
    type Err = ParseBoolError;

    #[inline]
    fn from_ascii(s: &[u8]) -> Result<bool, ParseBoolError> {
        match s {
            b"true"  => Ok(true),
            b"false" => Ok(false),
            _       => Err(ParseBoolError::ParseBoolError),
        }
    }
}

#[inline]
pub fn dec_to_digit(c: u8) -> Option<u8> {
    let val = match c {
        b'0' ... b'9' => c - b'0',
        _ => return None,
    };
    Some(val)
}

#[inline]
pub fn from_bytes(src: &[u8]) -> Option<i64> {
    if src.is_empty() {
        return None;
    }

    let (is_positive, digits) = match src[0] {
        b'+' => (true, &src[1..]),
        b'-' => (false, &src[1..]),
        _ => (true, src)
    };

    if digits.is_empty() {
        return None;
    }

    let mut result = 0;

    if is_positive {
        for &c in digits {
            result = result * 10 + match dec_to_digit(c) {
                Some(x) => x as i64,
                None => return None,
            };
        }
    } else {
        for &c in digits {
            result = result * 10 - match dec_to_digit(c) {
                Some(x) => x as i64,
                None => return None,
            };
        }
    }
    Some(result)
}

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

    #[test]
    fn test_parse_bool() {
        assert_eq!(bool::from_ascii(b"true"), Ok(true));
        assert_eq!(bool::from_ascii(b"false"), Ok(false));
        assert_eq!(bool::from_ascii(b""), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"true "), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"false "), Err(ParseBoolError::ParseBoolError));
    }
}
<commit_msg>Implement FromAscii for numeric types<commit_after>use std::fmt;

pub trait FromAscii: Sized {
    type Err;

    fn from_ascii(s: &[u8]) -> Result<Self, Self::Err>;
}

/// An error returned when parsing a `bool` from a ascii string fails.
#[derive(Debug, Clone, PartialEq)]
pub enum ParseBoolError {
    ParseBoolError
}

impl fmt::Display for ParseBoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "provided string was not `true` or `false`".fmt(f)
    }
}

impl FromAscii for bool {
    type Err = ParseBoolError;

    #[inline]
    fn from_ascii(s: &[u8]) -> Result<bool, ParseBoolError> {
        match s {
            b"true"  => Ok(true),
            b"false" => Ok(false),
            _       => Err(ParseBoolError::ParseBoolError),
        }
    }
}

trait FromStrHelper: {
    fn signed() -> bool;
}

pub enum ParseIntError {
    Empty,
    InvalidDigit,
    Overflow,
    Underflow,
}

#[inline]
pub fn dec_to_digit(c: u8) -> Option<u8> {
    let val = match c {
        b'0' ... b'9' => c - b'0',
        _ => return None,
    };
    Some(val)
}

macro_rules! from_bytes {
    ($src: expr, $t: ty) => ({
        if $src.is_empty() {
            return Err(ParseIntError::Empty);
        }

        let (is_positive, digits) = match $src[0] {
            b'+' => (true, &$src[1..]),
            b'-' if <$t>::signed() => (false, &$src[1..]),
            _ => (true, $src)
        };

        if digits.is_empty() {
            return Err(ParseIntError::Empty);
        }

        let mut result: $t = 0;

        if is_positive {
            for &c in digits {
                let x = match dec_to_digit(c) {
                    Some(x) => x as $t,
                    None => return Err(ParseIntError::InvalidDigit),
                };
                result = match result.checked_mul(10) {
                    Some(result) => result,
                    None => return Err(ParseIntError::Overflow),
                };
                result = match result.checked_add(x) {
                    Some(result) => result,
                    None => return Err(ParseIntError::Overflow),
                };
            }
        } else {
            for &c in digits {
                let x = match dec_to_digit(c) {
                    Some(x) => x as $t,
                    None => return Err(ParseIntError::InvalidDigit),
                };
                result = match result.checked_mul(10) {
                    Some(result) => result,
                    None => return Err(ParseIntError::Underflow),
                };
                result = match result.checked_sub(x) {
                    Some(result) => result,
                    None => return Err(ParseIntError::Underflow),
                };
            }
        }
        Ok(result)
    })
}

macro_rules! impl_helpers {
    ($t:ty, $signed: expr) => {
        impl FromStrHelper for $t {
            #[inline]
            fn signed() -> bool { $signed }
        }

        impl FromAscii for $t {
            type Err = ParseIntError;

            #[inline]
            fn from_ascii(src: &[u8]) -> Result<Self, Self::Err> {
                from_bytes!(src, $t)
            }
        }
    }
}

impl_helpers!(i8, true);
impl_helpers!(i16, true);
impl_helpers!(i32, true);
impl_helpers!(i64, true);
impl_helpers!(isize, true);
impl_helpers!(u8, false);
impl_helpers!(u16, false);
impl_helpers!(u32, false);
impl_helpers!(u64, false);
impl_helpers!(usize, false);

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

    #[test]
    fn test_parse_bool() {
        assert_eq!(bool::from_ascii(b"true"), Ok(true));
        assert_eq!(bool::from_ascii(b"false"), Ok(false));
        assert_eq!(bool::from_ascii(b""), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"true "), Err(ParseBoolError::ParseBoolError));
        assert_eq!(bool::from_ascii(b"false "), Err(ParseBoolError::ParseBoolError));
    }
}
<|endoftext|>


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

//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: http://yaml.org
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```rust
//! extern crate serde_yaml;
//!
//! use std::collections::BTreeMap;
//!
//! // You have some type.
//! let mut map = BTreeMap::new();
//! map.insert("x".to_string(), 1.0);
//! map.insert("y".to_string(), 2.0);
//!
//! // Serialize it to a YAML string.
//! let s = serde_yaml::to_string(&map).unwrap();
//! assert_eq!(s, "---\nx: 1\ny: 2");
//!
//! // Deserialize it back to a Rust type.
//! let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s).unwrap();
//! assert_eq!(map, deserialized_map);
//! ```
//!
//! ## Using serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```rust
//! #[macro_use] extern crate serde_derive;
//! extern crate serde_yaml;
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point { x: f64, y: f64 }
//!
//! # fn main() {
//! let point = Point { x: 1.0, y: 2.0 };
//!
//! let s = serde_yaml::to_string(&point).unwrap();
//! assert_eq!(s, "---\nx: 1\ny: 2");
//!
//! let deserialized_point: Point = serde_yaml::from_str(&s).unwrap();
//! assert_eq!(point, deserialized_point);
//! # }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.7.1")]

#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// private Deserializer::next
    should_implement_trait,
// things are often more readable this way
    single_match_else,
    stutter,
// not practical
    missing_docs_in_private_items,
// not stable
    empty_enum,
))]

extern crate linked_hash_map;
extern crate num_traits;
#[macro_use]
extern crate serde;
extern crate yaml_rust;

pub use self::de::{from_reader, from_slice, from_str};
pub use self::ser::{to_string, to_vec, to_writer};
pub use self::value::{Sequence, Value, from_value, to_value, Number};
pub use self::error::{Error, Result};
pub use self::mapping::Mapping;

mod de;
mod ser;
mod value;
mod error;
mod path;
mod mapping;
mod number;
<commit_msg>Ignore clippy's use_self lint<commit_after>// Copyright 2016 Serde YAML Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: http://yaml.org
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```rust
//! extern crate serde_yaml;
//!
//! use std::collections::BTreeMap;
//!
//! // You have some type.
//! let mut map = BTreeMap::new();
//! map.insert("x".to_string(), 1.0);
//! map.insert("y".to_string(), 2.0);
//!
//! // Serialize it to a YAML string.
//! let s = serde_yaml::to_string(&map).unwrap();
//! assert_eq!(s, "---\nx: 1\ny: 2");
//!
//! // Deserialize it back to a Rust type.
//! let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s).unwrap();
//! assert_eq!(map, deserialized_map);
//! ```
//!
//! ## Using serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```rust
//! #[macro_use] extern crate serde_derive;
//! extern crate serde_yaml;
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point { x: f64, y: f64 }
//!
//! # fn main() {
//! let point = Point { x: 1.0, y: 2.0 };
//!
//! let s = serde_yaml::to_string(&point).unwrap();
//! assert_eq!(s, "---\nx: 1\ny: 2");
//!
//! let deserialized_point: Point = serde_yaml::from_str(&s).unwrap();
//! assert_eq!(point, deserialized_point);
//! # }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.7.1")]

#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// private Deserializer::next
    should_implement_trait,
// things are often more readable this way
    single_match_else,
    stutter,
    use_self,
// not practical
    missing_docs_in_private_items,
// not stable
    empty_enum,
))]

extern crate linked_hash_map;
extern crate num_traits;
#[macro_use]
extern crate serde;
extern crate yaml_rust;

pub use self::de::{from_reader, from_slice, from_str};
pub use self::ser::{to_string, to_vec, to_writer};
pub use self::value::{Sequence, Value, from_value, to_value, Number};
pub use self::error::{Error, Result};
pub use self::mapping::Mapping;

mod de;
mod ser;
mod value;
mod error;
mod path;
mod mapping;
mod number;
<|endoftext|>


<commit_before>extern crate libc;

use libc::{c_char, c_int, c_uint, c_void};
use std::sync::Arc;
use ffi::{QVariant, QrsEngine, QObject};
use std::path::Path;
use std::convert::AsRef;

/* Re-exports */

pub use variant::{Variant, FromQVariant, ToQVariant};
pub use ffi::QVariant as OpaqueQVariant;

/* Submodules */

#[allow(dead_code)]
mod ffi;
mod macros;
mod variant;

/*
pub trait Object {
    fn qt_metaobject(&self) -> &'static MetaObject;
    fn qt_metacall(&mut self, slot: i32, args: *const *const OpaqueQVariant);
    //fn qt_emit(&self, signal: &str);
}

pub fn __qobject_emit<T: Object>(obj: &T, id: u32) {
    unsafe {
        ffi::qmlrs_object_emit_signal(get_qobject(obj), id as c_uint);
    }
}

/* This is unsafe in case the user copies the data. Might need to figure out something different. */
fn get_qobject<T: Object>(ptr: &T) -> *mut QObject {
    unsafe {
        let t_addr: usize = std::mem::transmute(ptr);
        let hdr: &PropHdr<T> = std::mem::transmute(t_addr - std::mem::size_of::<*mut QObject>());
        hdr.qobj
    }
}
*/
struct EngineInternal {
    p: *mut QrsEngine,
}

/* Hack to get invoke working. Need to figure out better way for invokes anyway.. */
unsafe impl Send for EngineInternal { }
unsafe impl Sync for EngineInternal { }

impl Drop for EngineInternal {
    fn drop(&mut self) {
        unsafe { ffi::qmlrs_destroy_engine(self.p); }
    }
}

pub struct Engine {
    i: Arc<EngineInternal>,
}

/*
#[repr(packed)]
struct PropHdr<T: Object> {
    qobj: *mut QObject,
    obj: T
}
*/

extern "C" fn slot_handler(data: *mut c_void, slot: c_int,
                                      args: *const *const ffi::QVariant)
{
  /*  unsafe {
        let hdr: &mut PropHdr<T> = std::mem::transmute(data);
        hdr.obj.qt_metacall(slot as i32, args);
    }*/
}

impl Engine {
    pub fn new() -> Engine {
        let p = unsafe { ffi::qmlrs_create_engine() };
        assert!(!p.is_null());

        let i = Arc::new(EngineInternal {
            p: p,
        });

        Engine {
            i: i
        }
    }

    pub fn new_headless() -> Engine {
        let p = unsafe { ffi::qmlrs_create_engine_headless() };
        assert!(!p.is_null());

        let i = Arc::new(EngineInternal {
            p: p,
        });

        Engine {
            i: i
        }
    }

    pub fn load_url(&mut self, path: &str) {
        unsafe {
            ffi::qmlrs_engine_load_url(self.i.p, path.as_ptr() as *const c_char,
                                       path.len() as c_uint);
        }
    }

    pub fn load_data(&mut self, data: &str) {
        unsafe {
            ffi::qmlrs_engine_load_from_data(self.i.p, data.as_ptr() as *const c_char,
                                             data.len() as c_uint);
        }
    }

    pub fn load_local_file<P: AsRef<Path>>(&mut self, name: P) {
        let path_raw = std::env::current_dir().unwrap().join(name);
        let path
            = if cfg!(windows) {
                format!("file:///{}",path_raw.display())
            } else {
                format!("file://{}",path_raw.display())
            } ;
        self.load_url(&path);
    }

    pub fn exec(self) {
        unsafe { ffi::qmlrs_app_exec(); }
    }

    /*
    pub fn handle(&self) -> Handle {
        Handle { i: self.i.downgrade() }
    }
    */

    pub fn set_property(&mut self, name: &str, obj: &Object) {
        unsafe {
            ffi::qmlrs_engine_set_property(self.i.p, name.as_ptr() as *const c_char,
                                           name.len() as c_uint, obj.p);
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct MetaObject {
    p: *mut ffi::QrsMetaObject
}

impl MetaObject {
    pub fn new() -> MetaObject {
        let p = unsafe { ffi::qmlrs_metaobject_create() };
        assert!(!p.is_null());

        MetaObject { p: p }
    }

    pub fn slot(self, name: &str, argc: u8) -> MetaObject {
        unsafe {
            ffi::qmlrs_metaobject_add_slot(self.p, name.as_ptr() as *const c_char,
                                           name.len() as c_uint, argc as c_uint);
        }
        self
    }

    pub fn signal(self, name: &str, argc: u8) -> MetaObject {
        unsafe {
            ffi::qmlrs_metaobject_add_signal(self.p, name.as_ptr() as *const c_char,
                                             name.len() as c_uint, argc as c_uint);
        }
        self
    }

    pub fn instantiate(&self) -> Object {
        unsafe {
            let mo = self.p;
            let qobj = ffi::qmlrs_metaobject_instantiate(mo);

            Object{ p: qobj }
        }
    }

}

#[derive(Clone)]
pub struct Object {
    p: *mut ffi::QObject
}

/*
pub struct Handle {
    i: Weak<EngineInternal>
}

impl Handle {
    pub fn invoke(&self, method: &str, args: &[Variant]) -> Result<Option<Variant>, &'static str> {
        unsafe {
            let cstr = method.to_c_str();

            let c_args = ffi::qmlrs_varlist_create();
            assert!(!c_args.is_null());
            for arg in args.iter() {
                let c_arg = ffi::qmlrs_varlist_push(c_args);
                assert!(!c_arg.is_null());
                arg.to_qvariant(c_arg);
            }

            let result = ffi::qmlrs_variant_create();
            assert!(!result.is_null());

            match self.i.upgrade() {
                Some(i) => ffi::qmlrs_engine_invoke(i.p, cstr.as_ptr(), result,
                                               c_args as *const QVariantList),
                None    => {
                    ffi::qmlrs_variant_destroy(result);
                    ffi::qmlrs_varlist_destroy(c_args);
                    return Err("View has been freed")
                }
            }

            ffi::qmlrs_varlist_destroy(c_args);

            let ret = FromQVariant::from_qvariant(result as *const QVariant);
            ffi::qmlrs_variant_destroy(result);

            Ok(ret)
        }
    }
}
*/

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

    #[test]
    fn test_create_engine() {
        Engine::new_headless();
    }
}
<commit_msg>extend Object API<commit_after>extern crate libc;

use libc::{c_char, c_uint, c_int};
use std::sync::Arc;
use ffi::{QrsEngine, QObject};
use std::path::Path;
use std::convert::AsRef;

/* Re-exports */

pub use variant::{Variant, FromQVariant, ToQVariant};
pub use ffi::QVariant as OpaqueQVariant;

/* Submodules */

#[allow(dead_code)]
pub mod ffi;
mod macros;
pub mod variant;

struct EngineInternal {
    p: *mut QrsEngine,
}

/* Hack to get invoke working. Need to figure out better way for invokes anyway.. */
unsafe impl Send for EngineInternal { }
unsafe impl Sync for EngineInternal { }

impl Drop for EngineInternal {
    fn drop(&mut self) {
        unsafe { ffi::qmlrs_destroy_engine(self.p); }
    }
}

pub struct Engine {
    i: Arc<EngineInternal>,
}

impl Engine {
    pub fn new() -> Engine {
        let p = unsafe { ffi::qmlrs_create_engine() };
        assert!(!p.is_null());

        let i = Arc::new(EngineInternal {
            p: p,
        });

        Engine {
            i: i
        }
    }

    pub fn new_headless() -> Engine {
        let p = unsafe { ffi::qmlrs_create_engine_headless() };
        assert!(!p.is_null());

        let i = Arc::new(EngineInternal {
            p: p,
        });

        Engine {
            i: i
        }
    }

    pub fn load_url(&mut self, path: &str) {
        unsafe {
            ffi::qmlrs_engine_load_url(self.i.p, path.as_ptr() as *const c_char,
                                       path.len() as c_uint);
        }
    }

    pub fn load_data(&mut self, data: &str) {
        unsafe {
            ffi::qmlrs_engine_load_from_data(self.i.p, data.as_ptr() as *const c_char,
                                             data.len() as c_uint);
        }
    }

    pub fn load_local_file<P: AsRef<Path>>(&mut self, name: P) {
        let path_raw = std::env::current_dir().unwrap().join(name);
        let path
            = if cfg!(windows) {
                format!("file:///{}",path_raw.display())
            } else {
                format!("file://{}",path_raw.display())
            } ;
        self.load_url(&path);
    }

    pub fn exec(self) {
        unsafe { ffi::qmlrs_app_exec(); }
    }

    pub fn set_property(&mut self, name: &str, obj: &Object) {
        unsafe {
            ffi::qmlrs_engine_set_property(self.i.p, name.as_ptr() as *const c_char,
                                           name.len() as c_uint, obj.p);
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct MetaObject {
    p: *mut ffi::QrsMetaObject
}

impl MetaObject {
    pub fn new(name: &str, fun: ffi::SlotFunction) -> MetaObject {
        let p = unsafe { ffi::qmlrs_metaobject_create(name.as_ptr() as *const c_char,name.len() as c_uint,fun) };
        assert!(!p.is_null());

        MetaObject { p: p }
    }

    pub fn add_signal(&mut self, sig: &str) -> isize {
        unsafe { ffi::qmlrs_metaobject_add_signal(self.p,sig.as_ptr() as *const c_char,sig.len() as c_uint) as isize }
    }

    pub fn add_property(&mut self, name: &str, ty: &str, signal: Option<&str>) {
        unsafe {
            if let Some(sig) = signal {
                ffi::qmlrs_metaobject_add_property(self.p,name.as_ptr() as *const c_char,name.len() as c_uint,
                                                   ty.as_ptr() as *const c_char, ty.len() as c_uint,
                                                   sig.as_ptr() as *const c_char, sig.len() as c_uint);
            } else {
                let s = "";
                ffi::qmlrs_metaobject_add_property(self.p,name.as_ptr() as *const c_char,name.len() as c_uint,
                                                   ty.as_ptr() as *const c_char,ty.len() as c_uint,
                                                   s.as_ptr() as *const c_char, 0);
            }
        }
    }

    pub fn add_slot(&mut self, sig: &str) -> isize {
        unsafe { ffi::qmlrs_metaobject_add_slot(self.p,sig.as_ptr() as *const c_char,sig.len() as c_uint) as isize }
    }

    pub fn add_method(&mut self, sig: &str) -> isize {
        unsafe { ffi::qmlrs_metaobject_add_method(self.p,sig.as_ptr() as *const c_char,sig.len() as c_uint) as isize }
    }

    pub fn instantiate(&mut self) -> Object {
        Object{ p: unsafe {
            ffi::qmlrs_metaobject_instantiate(self.p)
        } }
    }
}

pub struct Object {
    p: *mut ffi::QObject
}

impl Object {
    pub fn set_property(&mut self, name: &str, value: Variant) {
        unsafe {
            let var = ffi::qmlrs_variant_create();
            value.to_qvariant(var);

            ffi::qmlrs_object_set_property(self.p,name.as_ptr() as *const c_char,name.len() as c_uint,var);
            ffi::qmlrs_variant_destroy(var);
        }
    }

    pub fn get_property(&self, name: &str) -> Variant {
        unsafe {
            let var = ffi::qmlrs_variant_create();

            ffi::qmlrs_object_get_property(self.p,name.as_ptr() as *const c_char,name.len() as c_uint,var);
            let ret = Variant::from_qvariant(var);

            ffi::qmlrs_variant_destroy(var);
            ret.unwrap()
        }
    }

    pub fn call(&self, id: isize, args: &[Variant]) -> Option<Variant> {
        unsafe {
            let vl = ffi::qmlrs_varlist_create();
            let ret = ffi::qmlrs_variant_create();

            for v in args {
                let var = ffi::qmlrs_varlist_push(vl);
                v.to_qvariant(var);
            }

            ffi::qmlrs_object_call(self.p, id as c_int, vl, ret);
            ffi::qmlrs_varlist_destroy(vl);

            let r = Variant::from_qvariant(ret);
            ffi::qmlrs_variant_destroy(ret);

            r
        }
    }

    pub fn emit(&self, id: isize, args: &[Variant]) {
        unsafe {
            let vl = ffi::qmlrs_varlist_create();

            for v in args {
                let var = ffi::qmlrs_varlist_push(vl);
                v.to_qvariant(var);
            }

            ffi::qmlrs_object_emit(self.p, id as c_int, vl);
            ffi::qmlrs_varlist_destroy(vl);
        }
    }

    pub fn delete_later(&mut self) {
        unsafe { ffi::qmlrs_object_delete_later(self.p) };
    }
}

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

    #[test]
    fn test_create_engine() {
        Engine::new_headless();
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Google, Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//    http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(convert)]

extern crate openssl;

use openssl::crypto::hash::{hash, Type};

/// List of types currently supported in Multihash.
/// SHA3, Blake2b, and Blake2s are not yet supported in OpenSSL, so are not available in rust-multihash.
pub enum HashTypes {
    SHA1,
    SHA2256,
    SHA2512,
    SHA3,
    Blake2b,
    Blake2s
}

impl HashTypes {
    pub fn to_u8(&self) -> u8 {
        match *self {
            HashTypes::SHA1 => 0x11,
            HashTypes::SHA2256 => 0x12,
            HashTypes::SHA2512 => 0x13,
            HashTypes::SHA3 => 0x14,
            HashTypes::Blake2b => 0x40,
            HashTypes::Blake2s => 0x41,
        }
    }
}

/// Hashes the input using the given hash algorithm. Also adds the leading bytes for type of algo
/// and length of digest.
///
/// # Example
/// ```
/// use rust-multihash:::{HashTypes, multihash};
///
/// let testphrase = b"Hello World"
/// let digest = multihash(HashTypes::SHA2512, testphrase.to_vec());
/// ```
pub fn multihash(wanthash: HashTypes, input: Vec<u8>) -> Result<Vec<u8>, String> {
    let ssl_hash: Option<Type> = match wanthash {
        HashTypes::SHA1 => Some(Type::SHA1),
        HashTypes::SHA2256 => Some(Type::SHA256),
        HashTypes::SHA2512 => Some(Type::SHA512),
        _ => None,
    };
    match ssl_hash {
        Some(openssl_type) => {
            let mut temphash = hash(openssl_type, input.as_slice());
            let length = temphash.len() as u8;
            temphash.insert(0, length);
            temphash.insert(0, wanthash.to_u8()); // Add the hashtype to the hash.
            Ok(temphash)
        }
        None => Err("Sorry, we don't support that hash algorithm yet.".to_string()),
    }
}

#[cfg(test)]
mod test {
    use super::{HashTypes, multihash};
    use openssl::crypto::hash::{hash, Type};

    #[test]
    fn test1() {
        let example = b"Hello World";
        let mut result = hash(Type::SHA256, example);
        let length = result.len() as u8;
        result.insert(0, 0x12);
        result.insert(1, length);

        assert_eq!(multihash(HashTypes::SHA2256, example.to_vec()).unwrap(), result);
    }
}
<commit_msg>Derive some useful traits for HashTypes<commit_after>// Copyright 2015 Google, Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//    http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(convert)]

extern crate openssl;

use openssl::crypto::hash::{hash, Type};

/// List of types currently supported in Multihash.
/// SHA3, Blake2b, and Blake2s are not yet supported in OpenSSL, so are not available in rust-multihash.
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum HashTypes {
    SHA1,
    SHA2256,
    SHA2512,
    SHA3,
    Blake2b,
    Blake2s
}

impl HashTypes {
    pub fn to_u8(&self) -> u8 {
        match *self {
            HashTypes::SHA1 => 0x11,
            HashTypes::SHA2256 => 0x12,
            HashTypes::SHA2512 => 0x13,
            HashTypes::SHA3 => 0x14,
            HashTypes::Blake2b => 0x40,
            HashTypes::Blake2s => 0x41,
        }
    }
}

/// Hashes the input using the given hash algorithm. Also adds the leading bytes for type of algo
/// and length of digest.
///
/// # Example
/// ```
/// use rust-multihash:::{HashTypes, multihash};
///
/// let testphrase = b"Hello World"
/// let digest = multihash(HashTypes::SHA2512, testphrase.to_vec());
/// ```
pub fn multihash(wanthash: HashTypes, input: Vec<u8>) -> Result<Vec<u8>, String> {
    let ssl_hash: Option<Type> = match wanthash {
        HashTypes::SHA1 => Some(Type::SHA1),
        HashTypes::SHA2256 => Some(Type::SHA256),
        HashTypes::SHA2512 => Some(Type::SHA512),
        _ => None,
    };
    match ssl_hash {
        Some(openssl_type) => {
            let mut temphash = hash(openssl_type, input.as_slice());
            let length = temphash.len() as u8;
            temphash.insert(0, length);
            temphash.insert(0, wanthash.to_u8()); // Add the hashtype to the hash.
            Ok(temphash)
        }
        None => Err("Sorry, we don't support that hash algorithm yet.".to_string()),
    }
}

#[cfg(test)]
mod test {
    use super::{HashTypes, multihash};
    use openssl::crypto::hash::{hash, Type};

    #[test]
    fn test1() {
        let example = b"Hello World";
        let mut result = hash(Type::SHA256, example);
        let length = result.len() as u8;
        result.insert(0, 0x12);
        result.insert(1, length);

        assert_eq!(multihash(HashTypes::SHA2256, example.to_vec()).unwrap(), result);
    }
}
<|endoftext|>


<commit_before>//! Wayland Window, a minimalistic decoration-drawing library for
//! wayland applications.
//!
//! This crate is only usable in conjuction of the
//! [`wayland-client`](https://crates.io/crates/wayland-client) crate.
//!
//! ## Creating a decorated shell surface
//!
//! Creating a decorated window is as simple as wrapping it in a
//! `DecoratedSurface`:
//!
//! ```ignore
//! use wayland_window::DecoratedSurface;
//! let decorated = DecoratedSurface::new(my_surface, width, height, &registry, &seat);
//! ```
//!
//! As you can see, you need to pass the `Registry` and a `Seat` as well. It is required
//! for the library to be able to create the surfaces to draw the borders, and register
//! the callback to detect user input in the borders, for resizeing and move. These callback
//! will be registered on the seat you passed as argument. (So if you are on a setup with more
//! than one pointer, only one of them will be able to resize the window).
//!
//! ## Processing the events
//!
//! The `DecoratedSurface` object will not resize your window itself, as it cannot do it.
//!
//! When the user clicks on a border and starts a resize, the server will start to generate a
//! number of `configure` events on the shell surface. You'll need to register a callback on
//! it to handle them:
//!
//! ```ignore
//! decorated.get_shell().set_configure_callback(move |edge, width, height| {
//!     /* ... */
//! });
//! ```
//!
//! The wayland server can (and will) generate a ton of `configure` events during a single
//! `Display::dispatch()` if the user is currently resizing the window. You are only required to
//! process the last one, and if you try to handle them all your aplication will be very
//! laggy.
//!
//! The proper way is to use the callback to only store them in a container, overwriting the
//! the previous one each time, and manually checking if one has been received in the main loop
//! of your program, like this:
//!
//! ```ignore
//! // create a shared storage: (width, heigh, need_resize ?)
//! let need_resize = Arc::new(Mutex::new((0, 0, false)));
//! // clone it and put it in the callback
//! let my_need_resize = need_resize.clone();
//! decorated.w.get_shell().set_configure_callback(move |_edge, width, height| {
//!     let mut guard = my_newsize.lock().unwrap();
//!     // we overwrite it each time, to only keep the last one
//!     *guard = (width, height, true);
//! });
//! // then handle all this in the main loop:
//! loop {
//!     display.dispatch();
//!     let guard = need_resize.lock().unwrap();
//!     let (width, height, resize) = *guard;
//!     if resize {
//!         /* handle the resizing here */
//!     }
//!     // reset the storage
//!     *guard = (0, 0, false);
//! }
//! ```
//!
//! ## Resizing the surface
//!
//! When resizing your main surface, you need to tell the `DecoratedSurface` that it
//! must update its dimensions. This is very simple:
//!
//! ```ignore
//! /* update the buffer of decorated */
//! decorated.resize(width, height);
//! decorated.get_shell().commit();
//! ```
//!
//! If you do this as a response of a `configure` event, note the following points:
//!
//! - You do not have to respect the exact sizes provided by the compositor, it is
//!   just a hint. You can even ignore it if you don't want the window to be resized.
//! - In case you chose to ignore the resize, it can be appropiate to still resize your
//!   window to its current size (update the buffer to the compositor), as the compositer
//!   might have resized your window without telling you.
//! - The size hint provided by the compositor counts the borders size, to get the real
//!   size hint for your interior surface, use the function `substract_borders(..)` provided
//!   by this library.

extern crate byteorder;
extern crate tempfile;
extern crate wayland_client;

mod decorated_surface;

pub use decorated_surface::{DecoratedSurface, substract_borders};<commit_msg>Update docs accordingly.<commit_after>//! Wayland Window, a minimalistic decoration-drawing library for
//! wayland applications.
//!
//! This crate is only usable in conjuction of the
//! [`wayland-client`](https://crates.io/crates/wayland-client) crate.
//!
//! ## Creating a decorated shell surface
//!
//! Creating a decorated window is as simple as wrapping it in a
//! `DecoratedSurface`:
//!
//! ```ignore
//! use wayland_window::DecoratedSurface;
//! let decorated = DecoratedSurface::new(my_surface, width, height, &compositor, &subcompositor, &shm, &shell, Some(seat));
//! ```
//!
//! As you can see, you need to pass several references to global objects as well as a `WlSeat`.
//! It is required for the library to be able to create the surfaces to draw the borders, react
//! to user input in the borders, for resizeing and move. It will use the events provided on the
//! seat you passed as argument. (So if you are on a setup with more than one pointer,
//! only the one associated with this seat will be able to resize the window).
//!
//! ## Processing the events
//!
//! The `DecoratedSurface` object will not resize your window itself, as it cannot do it.
//!
//! When the user clicks on a border and starts a resize, the server will start to generate a
//! number of `configure` events on the shell surface. You'll need to process the events generated
//! by the surface to handle them, as the surface is also an event iterator :
//!
//! ```ignore
//! for (time, x, y) in &mut decorated_surface {
//!     // handle the event
//! }
//! ```
//!
//! The wayland server can (and will) generate a ton of `configure` events during a single
//! `WlDisplay::dispatch()` if the user is currently resizing the window. You are only required to
//! process the last one, and if you try to handle them all your aplication will be very
//! laggy.
//!
//! The proper way is to prcess the iterator and only store them in a container, overwriting the
//! the previous one each time, and manually checking if one has been received in the main loop
//! of your program, like this:
//!
//! ```ignore
//! let mut newsize = None;
//! for (_, x, y) in &mut decorated_surface {
//!     newsize = Some((x, y))
//! }
//! if let Some((x, y)) = newsize {
//!     let (x, y) = substract_borders(x, y);
//!     window.resize(x, y);
//! }
//! ```
//!
//! ## Resizing the surface
//!
//! When resizing your main surface, you need to tell the `DecoratedSurface` that it
//! must update its dimensions. This is very simple:
//!
//! ```ignore
//! /* update the borders size */
//! surface.attach(Some(&new_buffer));
//! decorated_surface.resize(width, height);
//! surface.commit();
//! ```
//!
//! If you do this as a response of a `configure` event, note the following points:
//!
//! - You do not have to respect the exact sizes provided by the compositor, it is
//!   just a hint. You can even ignore it if you don't want the window to be resized.
//! - In case you chose to ignore the resize, it can be appropiate to still resize your
//!   window to its current size (update the buffer to the compositor), as the compositer
//!   might have resized your window without telling you.
//! - The size hint provided by the compositor counts the borders size, to get the real
//!   size hint for your interior surface, use the function `substract_borders(..)` provided
//!   by this library.

extern crate byteorder;
extern crate tempfile;
extern crate wayland_client;

mod decorated_surface;

pub use decorated_surface::{DecoratedSurface, substract_borders};<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Capture the screen with xlib

#![feature(unique)]
#![allow(dead_code, non_upper_case_globals, non_camel_case_types)]

extern crate x11;
extern crate libc;

use ffi::*;
use x11::xlib::{ self, Display, Window };
use libc::{ c_ulong, c_int };
use std::ptr::{ self, Unique };
use std::slice;

pub mod ffi;

#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[repr(C, packed)]
pub struct RGB8 {
	r: u8,
	g: u8,
	b: u8,
}

/// From a bitmask for a color in a pixel, calculate the color size in bits and the bitshift
fn mask_size_and_shift(mut mask: c_ulong) -> (c_ulong, u16) {
	let (mut bits, mut shift) = (0, 0);
	let mut prev = 0;
	for _ in 0..(c_ulong::max_value() as f64).log2() as u16 {
		if mask & 1 == 1 {
			bits += 1;
			prev = 1;
		} else if prev == 1 {
			break;
		} else {
			shift += 1;
		}
		mask >>= 1;
	}
	(bits, shift)
}

struct Desktop {
	display: Unique<Display>,
	window: Window,
	width: u32, height: u32,
}
impl Desktop {
	fn new(display: Unique<Display>, screen: c_int) -> Desktop {
		let mut root_window = 0;
		let (mut root_x, mut root_y) = (0, 0);
		let (mut root_width, mut root_height, mut root_border_width) = (0, 0, 0);
		let mut root_pixel_depth = 0;
		if unsafe { xlib::XGetGeometry(*display, xlib::XRootWindow(*display, screen),
			&mut root_window,
			&mut root_x, &mut root_y,
			&mut root_width, &mut root_height, &mut root_border_width,
			&mut root_pixel_depth) == 0 }
		{
			panic!("XGetGeometry failed");
		}

		Desktop{
			display: display,
			window: root_window,
			width: root_width, height: root_height,
		}
	}
}
impl Drop for Desktop {
	fn drop(&mut self) {
		unsafe {
			xlib::XCloseDisplay(*self.display);
		}
	}
}

pub struct Capturer {
	desktop: Desktop,
}
impl Capturer {
	pub fn new() -> Capturer {
		// use the information from the environment variable DISPLAY to create the X connection:
		let display = unsafe { Unique::new(xlib::XOpenDisplay(ptr::null_mut())) };
		if display.is_null() {
			panic!("Unable to connect X server");
		}

		let screen = unsafe { xlib::XDefaultScreen(*display) };
		Capturer{ desktop: Desktop::new(display, screen) }
	}

	pub fn capture_frame(&mut self) -> (Vec<RGB8>, (u32, u32)) {
		let image_ptr = unsafe { xlib::XGetImage(*self.desktop.display, self.desktop.window,
			0, 0,
			self.desktop.width, self.desktop.height,
			AllPlanes, ZPixmap) };
		if image_ptr.is_null() {
			panic!("XGetImage failed");
		}
		let image = unsafe { &mut *image_ptr };

		println!("w, h: {:?}; pad: {}; bpl: {}", (image.width, image.height), image.bitmap_pad, image.bytes_per_line);

		unsafe { if image.depth == 24 && image.bits_per_pixel == 32 &&
			image.red_mask == 0xFF0000 && image.green_mask == 0xFF00 && image.blue_mask == 0xFF
		{
			// It's plain (RGB8 + padding)s in memory
			let raw_img_data = slice::from_raw_parts(image.data as *mut (RGB8, u8),
				image.width as usize * image.height as usize
			).iter()
				.map(|&(pixel, _)| pixel)
				.collect();

			xlib::XFree(image_ptr as *mut _);

			(raw_img_data, (image.width as u32, image.height as u32))
		} else {
			xlib::XFree(image_ptr as *mut _);
			panic!("WRONG LAYOUT")
		} }
	}
}

#[test]
fn test() {
	let mut capturer = Capturer::new();
	println!("Any non-black: {}", capturer.capture_frame().0.iter()
		.any(|p| p.r != 0 || p.g != 0 || p.b != 0));
}<commit_msg>Improve API, Result returns<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Capture the screen with xlib

#![feature(unique)]
#![allow(dead_code, non_upper_case_globals, non_camel_case_types)]

extern crate x11;
extern crate libc;

use ffi::*;
use x11::xlib;
use libc::c_int;
use std::ffi::CString;
use std::ptr::{ self, Unique };
use std::slice;

pub mod ffi;

#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[repr(C, packed)]
pub struct RGB8 {
	r: u8,
	g: u8,
	b: u8,
}

pub enum Display {
	Address(&'static str),
	Default
}

#[derive(Clone, Copy)]
pub enum Screen {
	Specific(c_int),
	Default
}

#[derive(Clone, Copy)]
pub enum Window {
	Window(xlib::Window),
	Desktop
}

struct WindowConnection {
	display: Unique<xlib::Display>,
	window: xlib::Window,
	width: u32, height: u32,
}
impl WindowConnection {
	fn new(display: Display, screen: Screen, window: Window) -> Result<WindowConnection, ()> {
		let display_ptr = unsafe {
			Unique::new(xlib::XOpenDisplay(if let Display::Address(address) = display {
				match CString::new(address) {
					Ok(s) => s.as_ptr(),
					Err(_) => return Err(())
				}
			} else {
				ptr::null()
			}))
		};

		if !display_ptr.is_null() {
			let screen_num = if let Screen::Specific(n) = screen {
				n
			} else {
				unsafe { xlib::XDefaultScreen(*display_ptr) }
			};

			let mut window_id = if let Window::Window(id) = window {
				id
			} else {
				unsafe { xlib::XRootWindow(*display_ptr, screen_num) }
			};

			let (mut window_width, mut window_height) = (0, 0);

			if unsafe { xlib::XGetGeometry(*display_ptr, window_id,
				&mut window_id,
				&mut 0, &mut 0,
				&mut window_width, &mut window_height, &mut 0,
				&mut 0) != 0
			}{
				Ok(WindowConnection{
					display: display_ptr,
					window: window_id,
					width: window_width, height: window_height,
				})
			} else {
				Err(())
			}
		} else {
			Err(())
		}
	}
}
impl Drop for WindowConnection {
	fn drop(&mut self) {
		unsafe {
			xlib::XCloseDisplay(*self.display);
		}
	}
}

/// Possible errors when capturing
#[derive(Debug)]
pub enum CaptureError {
	Fail(&'static str),
}

pub struct Capturer {
	screen: Screen,
	window_conn: WindowConnection,
}
impl Capturer {
	pub fn new(screen: Screen) -> Result<Capturer, ()> {
		match WindowConnection::new(Display::Default, screen, Window::Desktop) {
			Ok(conn) => Ok(Capturer{ screen: screen, window_conn: conn }),
			Err(_) => Err(()),
		}
	}

	fn connect(&mut self) -> Result<(), ()> {
		match WindowConnection::new(Display::Default, self.screen, Window::Desktop) {
			Ok(conn) => {
				self.window_conn = conn;
				Ok(())
			},
			Err(_) => Err(()),
		}
	}

	pub fn capture_frame(&mut self) -> Result<(Vec<RGB8>, (u32, u32)), CaptureError> {
		let image_ptr = unsafe { xlib::XGetImage(*self.window_conn.display, self.window_conn.window,
			0, 0,
			self.window_conn.width, self.window_conn.height,
			AllPlanes, ZPixmap) };

		if !image_ptr.is_null() {
			let image = unsafe { &mut *image_ptr };

			unsafe { if image.depth == 24 && image.bits_per_pixel == 32 &&
				image.red_mask == 0xFF0000 && image.green_mask == 0xFF00 && image.blue_mask == 0xFF
			{
				// It's plain (RGB8 + padding)s in memory
				let raw_img_data = slice::from_raw_parts(image.data as *mut (RGB8, u8),
					image.width as usize * image.height as usize
				).iter()
					.map(|&(pixel, _)| pixel)
					.collect();

				xlib::XFree(image_ptr as *mut _);

				Ok((raw_img_data, (image.width as u32, image.height as u32)))
			} else {
				xlib::XFree(image_ptr as *mut _);

				Err(CaptureError::Fail("WRONG LAYOUT"))
			} }
		} else {
			Err(CaptureError::Fail("XGetImage returned null pointer"))
		}
	}
}

#[test]
fn test() {
	let mut capturer = Capturer::new(Screen::Default).unwrap();
	for _ in 0..10 {
		println!("Any non-black: {}", capturer.capture_frame().unwrap().0.iter()
			.any(|p| p.r != 0 || p.g != 0 || p.b != 0));
	}
}<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![deny(warnings)]
// https://github.com/Marwes/combine/issues/172
#![recursion_limit = "256"]

//! # `toml_edit`
//!
//! This crate allows you to parse and modify toml
//! documents, while preserving comments, spaces* and
//! relative order* or items.
//!
//! It is primarily tailored to the needs of [cargo-edit](https://github.com/killercup/cargo-edit/).
//!
//! # Example
//!
//! ```rust
//! extern crate toml_edit;
//!
//! use toml_edit::{Document, value};
//!
//! fn main() {
//!     let toml = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//!     "#;
//!     let mut doc = toml.parse::<Document>().expect("invalid doc");
//!     assert_eq!(doc.to_string(), toml);
//!     // let's add a new key/value pair inside a.b: c = {d = "hello"}
//!     doc["a"]["b"]["c"]["d"] = value("hello");
//!     // autoformat inline table a.b.c: { d = "hello" }
//!     doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt());
//!     let expected = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//! c = { d = "hello" }
//!     "#;
//!     assert_eq!(doc.to_string(), expected);
//! }
//! ```
//!
//! ## Limitations
//!
//! *Things it does not preserve:
//!
//! * Different quotes and spaces around the same table key, e.g.
//!
//! ```text
//! [ 'a'. b]
//! [ "a"  .c]
//! [a.d]
//! ```
//!
//! will be represented as (spaces are removed, the first encountered quote type is used)
//!
//! ```text
//! ['a'.b]
//! ['a'.c]
//! ['a'.d]
//! ```
//!
//! * Children tables before parent table (tables are reordered, see [test]).
//! * Scattered array of tables (tables are reordered, see [test]).
//!
//! The reason behind the first limitation is that `Table` does not store its header,
//! allowing us to safely swap two tables
//! (we store a mapping in each table: child key -> child table).
//!
//! This last two limitations allow us to represent a toml document as a tree-like data structure,
//! which enables easier implementation of editing operations
//! and an easy to use and type-safe API.
//!
//! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84

mod array_of_tables;
mod decor;
mod display;
mod document;
pub(crate) mod formatted;
mod index;
mod key;
mod parser;
mod table;
mod value;

pub use crate::array_of_tables::ArrayOfTables;
pub use crate::document::Document;
pub use crate::key::Key;
pub use crate::parser::TomlError;
pub use crate::table::{array, table, value, Item, Iter, Table, TableLike};
pub use crate::value::{Array, InlineTable, Value};
<commit_msg>[docs] keeps lib docs in sync with README.md<commit_after>#![deny(missing_docs)]
#![deny(warnings)]
// https://github.com/Marwes/combine/issues/172
#![recursion_limit = "256"]

//! # `toml_edit`
//!
//! This crate allows you to parse and modify toml
//! documents, while preserving comments, spaces* and
//! relative order* or items.
//!
//! It is primarily tailored to the needs of [cargo-edit](https://github.com/killercup/cargo-edit/).
//!
//! # Example
//!
//! ```rust
//! extern crate toml_edit;
//!
//! use toml_edit::{Document, value};
//!
//! fn main() {
//!     let toml = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//!     "#;
//!     let mut doc = toml.parse::<Document>().expect("invalid doc");
//!     assert_eq!(doc.to_string(), toml);
//!     // let's add a new key/value pair inside a.b: c = {d = "hello"}
//!     doc["a"]["b"]["c"]["d"] = value("hello");
//!     // autoformat inline table a.b.c: { d = "hello" }
//!     doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt());
//!     let expected = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//! c = { d = "hello" }
//!     "#;
//!     assert_eq!(doc.to_string(), expected);
//! }
//! ```
//!
//! ## Limitations
//!
//! Things it does not preserve:
//!
//! * Different quotes and spaces around the same table key, e.g.
//!
//! ```text
//! [ 'a'. b]
//! [ "a"  .c]
//! [a.d]
//! ```
//!
//! will be represented as (spaces are removed, the first encountered quote type is used)
//!
//! ```text
//! ['a'.b]
//! ['a'.c]
//! ['a'.d]
//! ```
//!
//! * Children tables before parent table (tables are reordered by default, see [test]).
//! * Scattered array of tables (tables are reordered by default, see [test]).
//!
//! The reason behind the first limitation is that `Table` does not store its header,
//! allowing us to safely swap two tables
//! (we store a mapping in each table: child key -> child table).
//!
//! This last two limitations allow us to represent a toml document as a tree-like data structure,
//! which enables easier implementation of editing operations
//! and an easy to use and type-safe API. If you care about the above two cases,
//! you can use `Document::to_string_in_original_order()` to reconstruct tables in their original order.
//!
//! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84

mod array_of_tables;
mod decor;
mod display;
mod document;
pub(crate) mod formatted;
mod index;
mod key;
mod parser;
mod table;
mod value;

pub use crate::array_of_tables::ArrayOfTables;
pub use crate::document::Document;
pub use crate::key::Key;
pub use crate::parser::TomlError;
pub use crate::table::{array, table, value, Item, Iter, Table, TableLike};
pub use crate::value::{Array, InlineTable, Value};
<|endoftext|>