<commit_before>//! Bidirectional maps for Rust.
//!
//! # Examples
//!
//! ```
//! use bidir_map::BidirMap;
//!
//! let mut map = BidirMap::new();
//! map.insert(1, "a");
//! assert_eq!(map.get_by_first(&1), Some(&"a"));
//! assert_eq!(map.get_by_first(&2), None);
//! assert_eq!(map.get_by_second(&"a"), Some(&1));
//! assert_eq!(map.get_by_second(&"b"), None);
//! ```

use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

/// A bidirectional map.
///
/// Bidirectional maps allow for mapping from and to both types.
///
/// The interface is based on that of `BTreeMap`, except, that for all functions, where one would supply a key, there are two functions,
/// each treating one of the types as keys (`get()` -> `get_by_{first,second}()`).
///
/// Performance: `O(n)`, mostly.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	/// Clears the map, removing all entries.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.clear();
	/// assert!(a.is_empty());
	/// ```
	pub fn clear(&mut self) {
		self.cont.clear()
	}

	/// Inserts a K/V-K/V pair into the map.
	///
	/// If the map did not have this K/V-K/V pair present, `None` is returned.
	///
	/// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
		let retval =
			if self.contains_first_key(&kv1) {
				self.remove_by_first(&kv1)
			} else if self.contains_second_key(&kv2) {
				self.remove_by_second(&kv2)
			} else {
				None
			};

		self.cont.push((kv1, kv2));

		retval
	}

	/// Gets an iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// map.insert(2, "b");
	/// map.insert(3, "c");
	///
	/// for kv in map.iter() {
	/// 	println!("{}: {}", kv.0, kv.1);
	/// }
	///
	/// let first = map.iter().next().unwrap();
	/// assert_eq!(*first, (1, "a"));
	/// ```
	pub fn iter<'a>(&'a self) -> slice::Iter<'a, (Kv1, Kv2)> {
		self.cont.iter()
	}

	/// Gets a mutable iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert("a", 1);
	/// map.insert("b", 2);
	/// map.insert("c", 3);
	///
	/// // add 10 to the value if the key isn't "a"
	/// for kv in map.iter_mut() {
	/// 	if &kv.0 != &"a" {
	/// 		kv.1 += 10;
	/// 	}
	/// }
	/// ```
	pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	//TODO: maybe implement keys() and values() as first_col() and second_col()?

	/// Returns the number of elements in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert_eq!(a.len(), 0);
	/// a.insert(1, "a");
	/// assert_eq!(a.len(), 1);
	/// ```
	pub fn len(&self) -> usize {
		self.cont.len()
	}

	/// Returns true if the map contains no elements.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert!(a.is_empty());
	/// a.insert(1, "a");
	/// assert!(!a.is_empty());
	/// ```
	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_first(&1), Some(&"a"));
	/// assert_eq!(map.get_by_first(&2), None);
	/// ```
	pub fn get_by_first<Q>(&self, key: &Q) -> Option<&Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_second(&"a"), Some(&1));
	/// assert_eq!(map.get_by_second(&"b"), None);
	/// ```
	pub fn get_by_second<Q>(&self, key: &Q) -> Option<&Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
	}

	/// Check if the map contains the first K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_first_key(&1), true);
	/// assert_eq!(map.contains_first_key(&2), false);
	/// ```
	pub fn contains_first_key<Q>(&self, key: &Q) -> bool
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.0)
	}

	/// Check if the map contains the second K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_second_key(&"a"), true);
	/// assert_eq!(map.contains_second_key(&"b"), false);
	/// ```
	pub fn contains_second_key<Q>(&self, key: &Q) -> bool
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.1)
	}

	/// Returns a mutable reference to the second K/V corresponding to the first K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_first(&1) {
	///     *x = "b";
	/// }
	/// assert_eq!(map.get_by_first(&1), Some(&"b"));
	/// ```
	pub fn get_mut_by_first<Q>(&mut self, key: &Q) -> Option<&mut Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.0).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.1) as *const Kv2) as *mut Kv2) })  // This *should* be safe, we're casting &Kv2 to &mut Kv2 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Returns a mutable reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_second(&"a") {
	///     *x = 2;
	/// }
	/// assert_eq!(map.get_by_second(&"a"), Some(&2));
	/// ```
	pub fn get_mut_by_second<Q>(&mut self, key: &Q) -> Option<&mut Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.1).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.0) as *const Kv1) as *mut Kv1) })  // This *should* be safe, we're casting &Kv1 to &mut Kv1 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
	/// assert_eq!(map.remove_by_first(&1), None);
	/// ```
	pub fn remove_by_first<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
	/// assert_eq!(map.remove_by_second(&"b"), None);
	/// ```
	pub fn remove_by_second<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

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

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}
<commit_msg>Implement {first,second}_col() analogous to BTreeMap's keys()/values()<commit_after>//! Bidirectional maps for Rust.
//!
//! # Examples
//!
//! ```
//! use bidir_map::BidirMap;
//!
//! let mut map = BidirMap::new();
//! map.insert(1, "a");
//! assert_eq!(map.get_by_first(&1), Some(&"a"));
//! assert_eq!(map.get_by_first(&2), None);
//! assert_eq!(map.get_by_second(&"a"), Some(&1));
//! assert_eq!(map.get_by_second(&"b"), None);
//! ```

use std::borrow::Borrow;
use std::slice;
use std::iter::{Extend, FromIterator};
use std::vec;

/// A bidirectional map.
///
/// Bidirectional maps allow for mapping from and to both types.
///
/// The interface is based on that of `BTreeMap`, except, that for all functions, where one would supply a key, there are two functions,
/// each treating one of the types as keys (`get()` -> `get_by_{first,second}()`).
///
/// Performance: `O(n)`, mostly.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct BidirMap<Kv1: PartialEq, Kv2: PartialEq> {
	cont: Vec<(Kv1, Kv2)>,
}

impl<Kv1: PartialEq, Kv2: PartialEq> BidirMap<Kv1, Kv2> {
	/// Create a new empty instance of `BidirMap`
	pub fn new() -> Self {
		BidirMap{
			cont: Vec::new(),
		}
	}

	/// Clears the map, removing all entries.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.clear();
	/// assert!(a.is_empty());
	/// ```
	pub fn clear(&mut self) {
		self.cont.clear()
	}

	/// Inserts a K/V-K/V pair into the map.
	///
	/// If the map did not have this K/V-K/V pair present, `None` is returned.
	///
	/// If the map did have this K/V-K/V pair present, it's updated and the old K/V-K/V pair is returned.
	pub fn insert(&mut self, kv1: Kv1, kv2: Kv2) -> Option<(Kv1, Kv2)> {
		let retval =
			if self.contains_first_key(&kv1) {
				self.remove_by_first(&kv1)
			} else if self.contains_second_key(&kv2) {
				self.remove_by_second(&kv2)
			} else {
				None
			};

		self.cont.push((kv1, kv2));

		retval
	}

	/// Gets an iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// map.insert(2, "b");
	/// map.insert(3, "c");
	///
	/// for kv in map.iter() {
	/// 	println!("{}: {}", kv.0, kv.1);
	/// }
	///
	/// let first = map.iter().next().unwrap();
	/// assert_eq!(*first, (1, "a"));
	/// ```
	pub fn iter<'s>(&'s self) -> slice::Iter<'s, (Kv1, Kv2)> {
		self.cont.iter()
	}

	/// Gets a mutable iterator over the entries of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert("a", 1);
	/// map.insert("b", 2);
	/// map.insert("c", 3);
	///
	/// // add 10 to the value if the key isn't "a"
	/// for kv in map.iter_mut() {
	/// 	if &kv.0 != &"a" {
	/// 		kv.1 += 10;
	/// 	}
	/// }
	/// ```
	pub fn iter_mut<'s>(&'s mut self) -> slice::IterMut<'s, (Kv1, Kv2)> {
		self.cont.iter_mut()
	}

	/// Gets an iterator over the first K/V of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.insert(2, "b");
	///
	/// let keys: Vec<_> = a.first_col().cloned().collect();
	/// assert_eq!(keys, [1, 2]);
	/// ```
	pub fn first_col<'s>(&'s self) -> FirstColumn<'s, Kv1, Kv2> {
		FirstColumn{
			iter: self.cont.iter(),
		}
	}

	/// Gets an iterator over the second K/V of the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// a.insert(1, "a");
	/// a.insert(2, "b");
	///
	/// let keys: Vec<_> = a.second_col().cloned().collect();
	/// assert_eq!(keys, ["a", "b"]);
	/// ```
	pub fn second_col<'s>(&'s self) -> SecondColumn<'s, Kv1, Kv2> {
		SecondColumn{
			iter: self.cont.iter(),
		}
	}

	/// Returns the number of elements in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert_eq!(a.len(), 0);
	/// a.insert(1, "a");
	/// assert_eq!(a.len(), 1);
	/// ```
	pub fn len(&self) -> usize {
		self.cont.len()
	}

	/// Returns true if the map contains no elements.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut a = BidirMap::new();
	/// assert!(a.is_empty());
	/// a.insert(1, "a");
	/// assert!(!a.is_empty());
	/// ```
	pub fn is_empty(&self) -> bool {
		self.cont.is_empty()
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_first(&1), Some(&"a"));
	/// assert_eq!(map.get_by_first(&2), None);
	/// ```
	pub fn get_by_first<Q>(&self, key: &Q) -> Option<&Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.0).map(|ref kvs| &kvs.1)
	}

	/// Returns a reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.get_by_second(&"a"), Some(&1));
	/// assert_eq!(map.get_by_second(&"b"), None);
	/// ```
	pub fn get_by_second<Q>(&self, key: &Q) -> Option<&Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|&kvs| *key == kvs.1).map(|ref kvs| &kvs.0)
	}

	/// Check if the map contains the first K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_first_key(&1), true);
	/// assert_eq!(map.contains_first_key(&2), false);
	/// ```
	pub fn contains_first_key<Q>(&self, key: &Q) -> bool
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.0)
	}

	/// Check if the map contains the second K/V
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.contains_second_key(&"a"), true);
	/// assert_eq!(map.contains_second_key(&"b"), false);
	/// ```
	pub fn contains_second_key<Q>(&self, key: &Q) -> bool
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().any(|ref kvs| *key == kvs.1)
	}

	/// Returns a mutable reference to the second K/V corresponding to the first K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_first(&1) {
	///     *x = "b";
	/// }
	/// assert_eq!(map.get_by_first(&1), Some(&"b"));
	/// ```
	pub fn get_mut_by_first<Q>(&mut self, key: &Q) -> Option<&mut Kv2>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.0).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.1) as *const Kv2) as *mut Kv2) })  // This *should* be safe, we're casting &Kv2 to &mut Kv2 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Returns a mutable reference to the first K/V corresponding to the second K/V.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// if let Some(x) = map.get_mut_by_second(&"a") {
	///     *x = 2;
	/// }
	/// assert_eq!(map.get_by_second(&"a"), Some(&2));
	/// ```
	pub fn get_mut_by_second<Q>(&mut self, key: &Q) -> Option<&mut Kv1>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().find(|ref kvs| *key == kvs.1).and_then(|ref kvs| {
			Some(unsafe { &mut *(((&kvs.0) as *const Kv1) as *mut Kv1) })  // This *should* be safe, we're casting &Kv1 to &mut Kv1 from a mutable context
			                                                               // Using mutables all the way wouldn't work for the life of me.
		})
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_first(&1), Some((1, "a")));
	/// assert_eq!(map.remove_by_first(&1), None);
	/// ```
	pub fn remove_by_first<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv1: Borrow<Q>,
		      Q  : PartialEq<Kv1>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.0).map(|idx| self.cont.swap_remove(idx))
	}

	/// Removes the pair corresponding to the first K/V from the map, returning it if the key was previously in the map.
	///
	/// # Examples
	///
	/// ```
	/// use bidir_map::BidirMap;
	///
	/// let mut map = BidirMap::new();
	/// map.insert(1, "a");
	/// assert_eq!(map.remove_by_second(&"a"), Some((1, "a")));
	/// assert_eq!(map.remove_by_second(&"b"), None);
	/// ```
	pub fn remove_by_second<Q>(&mut self, key: &Q) -> Option<(Kv1, Kv2)>
		where Kv2: Borrow<Q>,
		      Q  : PartialEq<Kv2>,
	{
		self.cont.iter().position(|ref kvs| *key == kvs.1).map(|idx| self.cont.swap_remove(idx))
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> IntoIterator for BidirMap<Kv1, Kv2> {
	type Item = (Kv1, Kv2);
	type IntoIter = vec::IntoIter<Self::Item>;

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

impl<Kv1: PartialEq, Kv2: PartialEq> FromIterator<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn from_iter<T: IntoIterator<Item=(Kv1, Kv2)>>(iter: T) -> Self {
		BidirMap{
			cont: Vec::from_iter(iter),
		}
	}
}

impl<Kv1: PartialEq, Kv2: PartialEq> Extend<(Kv1, Kv2)> for BidirMap<Kv1, Kv2> {
	fn extend<T: IntoIterator<Item=(Kv1, Kv2)>>(&mut self, iter: T) {
		self.cont.extend(iter)
	}
}

pub struct FirstColumn<'a, Kv1: 'a, Kv2: 'a> {
	iter: slice::Iter<'a, (Kv1, Kv2)>,
}

impl<'a, Kv1, Kv2> Iterator for FirstColumn<'a, Kv1, Kv2> {
	type Item = &'a Kv1;
	fn next(&mut self) -> Option<Self::Item> {
		self.iter.next().map(|ref kvs| &kvs.0)
	}
}

pub struct SecondColumn<'a, Kv1: 'a, Kv2: 'a> {
	iter: slice::Iter<'a, (Kv1, Kv2)>,
}

impl<'a, Kv1, Kv2> Iterator for SecondColumn<'a, Kv1, Kv2> {
	type Item = &'a Kv2;
	fn next(&mut self) -> Option<Self::Item> {
		self.iter.next().map(|ref kvs| &kvs.1)
	}
}
<|endoftext|>


<commit_before>//! Calculate the crc64 checksum of the given data, starting with the given crc.
//!
//! Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
//!
//! Specification of this CRC64 variant follows:
//!
//! ```text
//! Name: crc-64-jones
//! Width: 64 bites
//! Poly: 0xad93d23594c935a9
//! Reflected In: True
//! Xor_In: 0xffffffffffffffff
//! Reflected_Out: True
//! Xor_Out: 0x0
//! Check("123456789"): 0xe9c6d914c4b8d9ca
//! ```
//!
//! Example:
//!
//! ```rust
//! let cksum = crc64::crc64(0, "123456789".as_bytes());
//! assert_eq!(16845390139448941002, cksum);
//! ```

use std::io::{self, Write};
use std::mem;

use crc_table::CRC64_TAB;

mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i += 1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly: u64 = 0xad93d23594c935a9;

    let mut bit: bool;

    let mut offset = 0;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset += 1;
    }
    crc &= 0xffffffffffffffff;

    crc_reflect(crc, 64)
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc: u64;

    let mut table: Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in 0..8 {
        table.push(Vec::with_capacity(256));
    }

    for n in 0..256 {
        table[0].push(crc64_trivial(0, &[n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in 0..256 {
        crc = table[0][n];
        for k in 1..8 {
            let idx = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    }

    table
}

// transmute slice of 8 u8 values to one u64 (drop the length)
macro_rules! slice_to_long {
    ($curVec:expr) => {{
        unsafe {
            let (tmp, _): (*const u64, usize) = mem::transmute(&$curVec);
            *tmp
        }
    }};
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= slice_to_long!(data[offset..(offset + 8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize]
            ^ CRC64_TAB[6][((crc >> 8) & 0xff) as usize]
            ^ CRC64_TAB[5][((crc >> 16) & 0xff) as usize]
            ^ CRC64_TAB[4][((crc >> 24) & 0xff) as usize]
            ^ CRC64_TAB[3][((crc >> 32) & 0xff) as usize]
            ^ CRC64_TAB[2][((crc >> 40) & 0xff) as usize]
            ^ CRC64_TAB[1][((crc >> 48) & 0xff) as usize]
            ^ CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Default for Crc64 {
    fn default() -> Self {
        Self::new()
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<commit_msg>Use safe way to convert a vec to u64<commit_after>//! Calculate the crc64 checksum of the given data, starting with the given crc.
//!
//! Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
//!
//! Specification of this CRC64 variant follows:
//!
//! ```text
//! Name: crc-64-jones
//! Width: 64 bites
//! Poly: 0xad93d23594c935a9
//! Reflected In: True
//! Xor_In: 0xffffffffffffffff
//! Reflected_Out: True
//! Xor_Out: 0x0
//! Check("123456789"): 0xe9c6d914c4b8d9ca
//! ```
//!
//! Example:
//!
//! ```rust
//! let cksum = crc64::crc64(0, "123456789".as_bytes());
//! assert_eq!(16845390139448941002, cksum);
//! ```

use std::io::{self, Write};

use crc_table::CRC64_TAB;

mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i += 1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly: u64 = 0xad93d23594c935a9;

    let mut bit: bool;

    let mut offset = 0;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset += 1;
    }
    crc &= 0xffffffffffffffff;

    crc_reflect(crc, 64)
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc: u64;

    let mut table: Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in 0..8 {
        table.push(Vec::with_capacity(256));
    }

    for n in 0..256 {
        table[0].push(crc64_trivial(0, &[n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in 0..256 {
        crc = table[0][n];
        for k in 1..8 {
            let idx = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    }

    table
}

fn to_u64(data: &[u8]) -> u64 {
    debug_assert!(data.len() == 8);
    let arr: [u8; 8] = data.try_into().expect("incorrect length");
    u64::from_le_bytes(arr)
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= to_u64(&data[offset..(offset + 8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize]
            ^ CRC64_TAB[6][((crc >> 8) & 0xff) as usize]
            ^ CRC64_TAB[5][((crc >> 16) & 0xff) as usize]
            ^ CRC64_TAB[4][((crc >> 24) & 0xff) as usize]
            ^ CRC64_TAB[3][((crc >> 32) & 0xff) as usize]
            ^ CRC64_TAB[2][((crc >> 40) & 0xff) as usize]
            ^ CRC64_TAB[1][((crc >> 48) & 0xff) as usize]
            ^ CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Default for Crc64 {
    fn default() -> Self {
        Self::new()
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<|endoftext|>


<commit_before>#![warn(missing_docs)]

//! input-map
//! =========
//!
//! A library for binding input keys to actions, and manipulating mouse input

extern crate input;
extern crate piston_window;
extern crate rustc_serialize;
extern crate viewport;

mod builder;

use input::{Input, Button, Motion};
use piston_window::Size;
use std::collections::HashMap;
use std::default::Default;
use std::hash::Hash;
use viewport::Viewport;

pub use builder::InputTranslatorBuilder;

/// Represents a logical action to be bound to a particular button press, e.g.
/// jump, attack, or move forward. Needs to be hashable, as it is used as a
/// lookup key when rebinding an action to a different key.
pub trait Action: Copy + PartialEq + Eq + Hash { }

/// A translated action.
#[derive(Debug, Copy, Clone)]
pub enum Translated<A: Action> {
    /// A keypress event which was bound to an action
    Press(A),

    /// A key release event which was bound to an action
    Release(A),

    /// A translated mouse motion. The logical origin of a translated MouseCursor event
    /// is in the top left corner of the window, and the logical scroll is non-natural.
    /// Relative events are unchanged for now.
    Move(Motion)
}

/// A three-element tuple of Option<Button>. For simplicity, a maximum number of 3
/// buttons can be bound to each action, and this is exposed through the `InputRebind`
/// struct.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ButtonTuple(pub Option<Button>, pub Option<Button>, pub Option<Button>);

impl ButtonTuple {
    /// Creates a new tuple with no buttons in it (equivalent to `Default::default()`).
    pub fn new() -> Self { Default::default() }

    /// Check if the button is in the tuple.
    pub fn contains(&self, button: Button) -> bool {
        let sbtn = Some(button);
        self.0 == sbtn || self.1 == sbtn || self.2 == sbtn
    }

    /// Insert a button into the tuple if there is room, searching from left to right.
    /// If the button is inserted, returns true. Otherwise, if the button is not inserted,
    /// this function returns false.
    pub fn insert_inplace(&mut self, button: Button) -> bool {
        match self {
            &mut ButtonTuple(a, b, c) if a.is_none() => {*self = ButtonTuple(Some(button), b, c); true},
            &mut ButtonTuple(a, b, c) if b.is_none() => {*self = ButtonTuple(a, Some(button), c); true},
            &mut ButtonTuple(a, b, c) if c.is_none() => {*self = ButtonTuple(a, b, Some(button)); true}
            _ => false
        }
    }
}

impl Default for ButtonTuple {
    /// Creates a new tuple with no buttons in it.
    fn default() -> Self { ButtonTuple(None, None, None) }
}

/// An object which translates piston::input::Input events into input_map::Translated<A> events
#[derive(Clone)]
pub struct InputTranslator<A: Action> {
    keymap: HashMap<Button, A>,
    mouse_translator: MouseTranslator
}

impl<A: Action> InputTranslator<A> {

    /// Creates an empty InputTranslator.
    pub fn new(size: Size) -> Self {
        InputTranslator {
            keymap: HashMap::new(),
            mouse_translator: MouseTranslator::new(size)
        }
    }

    /// Translate an Input into a Translated<A> event
    pub fn translate(&self, input: &Input) -> Option<Translated<A>> {
        macro_rules! translate_button(($but_state:ident, $but_var:ident) => (
            match self.keymap.get(&$but_var).map(|x| *x) {
                Some(act) => Some(Translated::$but_state(act)),
                None => None
            });
        );

        match input {
            &Input::Press(button) => translate_button!(Press, button),
            &Input::Release(button) => translate_button!(Release, button),
            &Input::Move(motion) =>
                Some(Translated::Move(self.mouse_translator.translate(motion))),
            _ => None
        }
    }

    /// Re-set the mouse bounds size used for calculating mouse events
    pub fn set_size(&mut self, size: Size) {
        self.mouse_translator.data.viewport_size = size
    }

    /// Re-set the mouse bounds size from a viewport
    pub fn set_size_from_viewport(&mut self, vp: Viewport) {
        self.set_size(Size::from(vp.draw_size));
    }
}

#[derive(Clone)]
struct MouseTranslationData {
    x_axis_motion_inverted: bool,
    y_axis_motion_inverted: bool,
    x_axis_scroll_inverted: bool,
    y_axis_scroll_inverted: bool,
    viewport_size: Size
}

impl MouseTranslationData {
    fn new(size: Size) -> Self {
        MouseTranslationData {
            x_axis_motion_inverted: false,
            y_axis_motion_inverted: false,
            x_axis_scroll_inverted: false,
            y_axis_scroll_inverted: false,
            viewport_size: size
        }
    }
}

#[derive(Clone)]
struct MouseTranslator {
    data: MouseTranslationData
}

impl MouseTranslator {
    fn new(size: Size) -> Self {
        MouseTranslator {
            data: MouseTranslationData::new(size)
        }
    }

    fn translate(&self, motion: Motion) -> Motion {
        match motion {
            Motion::MouseCursor(x, y) => {
                let (sw, sh) = {
                    let Size {width, height} = self.data.viewport_size;
                    (width as f64, height as f64)
                };

                let cx = if self.data.x_axis_motion_inverted { sw - x } else { x };
                let cy = if self.data.y_axis_motion_inverted { sh - y } else { y };

                Motion::MouseCursor(cx, cy)
            },
            Motion::MouseScroll(x, y) => {
                let mx = if self.data.x_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                let my = if self.data.y_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                Motion::MouseScroll(x * mx, y * my)
            },
            relative => relative
        }
    }
}

#[allow(missing_docs)]
pub struct InputRebind<A: Action> {
    keymap: HashMap<A, ButtonTuple>,
    mouse_data: MouseTranslationData
}

impl<A: Action> InputRebind<A> {
    #[allow(missing_docs)]
    pub fn new(size: Size) -> Self {
        InputRebind {
            keymap: HashMap::new(),
            mouse_data: MouseTranslationData::new(size)
        }
    }

    #[allow(missing_docs)]
    pub fn insert_action(&mut self, action: A) -> Option<ButtonTuple> {
        self.keymap.insert(action, ButtonTuple::new())
    }

    #[allow(missing_docs)]
    pub fn insert_action_with_buttons(&mut self, action: A, buttons: ButtonTuple) -> Option<ButtonTuple> {
        self.keymap.insert(action, buttons)
    }

    #[allow(missing_docs)]
    pub fn get_bindings(&self, action: &A) -> Option<&ButtonTuple> {
        self.keymap.get(action)
    }

    #[allow(missing_docs)]
    pub fn get_bindings_mut(&mut self, action: &mut A) -> Option<&mut ButtonTuple> {
        self.keymap.get_mut(action)
    }

    #[allow(missing_docs)]
    pub fn get_x_scroll_inverted(&self) -> &bool {
        &self.mouse_data.x_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_scroll_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.x_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_scroll_inverted(&self) -> &bool {
        &self.mouse_data.y_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_scroll_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.y_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_motion_inverted(&self) -> &bool {
        &self.mouse_data.x_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_motion_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.x_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_motion_inverted(&self) -> &bool {
        &self.mouse_data.y_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_motion_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.y_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_viewport_size(&self) -> &Size {
        &self.mouse_data.viewport_size
    }

    #[allow(missing_docs)]
    pub fn get_viewport_size_mut(&mut self) -> &mut Size {
        &mut self.mouse_data.viewport_size
    }
}

impl<A: Action> Default for InputRebind<A> {
    #[allow(missing_docs)]
    fn default() -> Self {
        InputRebind::new((800, 600).into())
    }
}

impl<A: Action> Into<InputTranslator<A>> for InputRebind<A> {
    #[allow(missing_docs)]
    fn into(self) -> InputTranslator<A> {
        let mut input_translator = InputTranslator::new(self.mouse_data.viewport_size);
        input_translator.mouse_translator.data = self.mouse_data;
        input_translator.keymap = self.keymap.values()
                                             .flat_map(|&bt| bt.into_iter())
                                             .filter_map(|x| x)
                                             .zip(self.keymap.keys().map(|x| *x))
                                             .collect();

        input_translator
    }
}

impl<A: Action> Into<InputRebind<A>> for InputTranslator<A> {
    #[allow(missing_docs)]
    fn into(self) -> InputRebind<A> {
        let mut input_rebind = InputRebind::new(self.mouse_translator.data.viewport_size);
        input_rebind.mouse_data = self.mouse_translator.data;
        //input_rebind.keymap = self.keymap.btn_map.
        //input_rebind.keymap = self.keymap.btn_map.drain().map(|(k, v)| (v, k)).collect();
        input_rebind
    }
}

impl ButtonTuple {
    fn into_iter(self) -> ButtonTupleIterator {
        ButtonTupleIterator {
            button_tuple: self,
            i: 0
        }
    }
}

struct ButtonTupleIterator {
    button_tuple: ButtonTuple,
    i: usize
}

impl Iterator for ButtonTupleIterator {
    type Item = Option<Button>;

    fn next(&mut self) -> Option<Self::Item> {
        let i = self.i;
        self.i += 1;
        match i {
            0 => Some(self.button_tuple.0),
            1 => Some(self.button_tuple.1),
            2 => Some(self.button_tuple.2),
            _ => None
        }
    }
}

<commit_msg>Add derive(PartialEq) to enum Translated declaration<commit_after>#![warn(missing_docs)]

//! input-map
//! =========
//!
//! A library for binding input keys to actions, and manipulating mouse input

extern crate input;
extern crate piston_window;
extern crate rustc_serialize;
extern crate viewport;

mod builder;

use input::{Input, Button, Motion};
use piston_window::Size;
use std::collections::HashMap;
use std::default::Default;
use std::hash::Hash;
use viewport::Viewport;

pub use builder::InputTranslatorBuilder;

/// Represents a logical action to be bound to a particular button press, e.g.
/// jump, attack, or move forward. Needs to be hashable, as it is used as a
/// lookup key when rebinding an action to a different key.
pub trait Action: Copy + PartialEq + Eq + Hash { }

/// A translated action.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Translated<A: Action> {
    /// A keypress event which was bound to an action
    Press(A),

    /// A key release event which was bound to an action
    Release(A),

    /// A translated mouse motion. The logical origin of a translated MouseCursor event
    /// is in the top left corner of the window, and the logical scroll is non-natural.
    /// Relative events are unchanged for now.
    Move(Motion)
}

/// A three-element tuple of Option<Button>. For simplicity, a maximum number of 3
/// buttons can be bound to each action, and this is exposed through the `InputRebind`
/// struct.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ButtonTuple(pub Option<Button>, pub Option<Button>, pub Option<Button>);

impl ButtonTuple {
    /// Creates a new tuple with no buttons in it (equivalent to `Default::default()`).
    pub fn new() -> Self { Default::default() }

    /// Check if the button is in the tuple.
    pub fn contains(&self, button: Button) -> bool {
        let sbtn = Some(button);
        self.0 == sbtn || self.1 == sbtn || self.2 == sbtn
    }

    /// Insert a button into the tuple if there is room, searching from left to right.
    /// If the button is inserted, returns true. Otherwise, if the button is not inserted,
    /// this function returns false.
    pub fn insert_inplace(&mut self, button: Button) -> bool {
        match self {
            &mut ButtonTuple(a, b, c) if a.is_none() => {*self = ButtonTuple(Some(button), b, c); true},
            &mut ButtonTuple(a, b, c) if b.is_none() => {*self = ButtonTuple(a, Some(button), c); true},
            &mut ButtonTuple(a, b, c) if c.is_none() => {*self = ButtonTuple(a, b, Some(button)); true}
            _ => false
        }
    }
}

impl Default for ButtonTuple {
    /// Creates a new tuple with no buttons in it.
    fn default() -> Self { ButtonTuple(None, None, None) }
}

/// An object which translates piston::input::Input events into input_map::Translated<A> events
#[derive(Clone)]
pub struct InputTranslator<A: Action> {
    keymap: HashMap<Button, A>,
    mouse_translator: MouseTranslator
}

impl<A: Action> InputTranslator<A> {

    /// Creates an empty InputTranslator.
    pub fn new(size: Size) -> Self {
        InputTranslator {
            keymap: HashMap::new(),
            mouse_translator: MouseTranslator::new(size)
        }
    }

    /// Translate an Input into a Translated<A> event
    pub fn translate(&self, input: &Input) -> Option<Translated<A>> {
        macro_rules! translate_button(($but_state:ident, $but_var:ident) => (
            match self.keymap.get(&$but_var).map(|x| *x) {
                Some(act) => Some(Translated::$but_state(act)),
                None => None
            });
        );

        match input {
            &Input::Press(button) => translate_button!(Press, button),
            &Input::Release(button) => translate_button!(Release, button),
            &Input::Move(motion) =>
                Some(Translated::Move(self.mouse_translator.translate(motion))),
            _ => None
        }
    }

    /// Re-set the mouse bounds size used for calculating mouse events
    pub fn set_size(&mut self, size: Size) {
        self.mouse_translator.data.viewport_size = size
    }

    /// Re-set the mouse bounds size from a viewport
    pub fn set_size_from_viewport(&mut self, vp: Viewport) {
        self.set_size(Size::from(vp.draw_size));
    }
}

#[derive(Clone)]
struct MouseTranslationData {
    x_axis_motion_inverted: bool,
    y_axis_motion_inverted: bool,
    x_axis_scroll_inverted: bool,
    y_axis_scroll_inverted: bool,
    viewport_size: Size
}

impl MouseTranslationData {
    fn new(size: Size) -> Self {
        MouseTranslationData {
            x_axis_motion_inverted: false,
            y_axis_motion_inverted: false,
            x_axis_scroll_inverted: false,
            y_axis_scroll_inverted: false,
            viewport_size: size
        }
    }
}

#[derive(Clone)]
struct MouseTranslator {
    data: MouseTranslationData
}

impl MouseTranslator {
    fn new(size: Size) -> Self {
        MouseTranslator {
            data: MouseTranslationData::new(size)
        }
    }

    fn translate(&self, motion: Motion) -> Motion {
        match motion {
            Motion::MouseCursor(x, y) => {
                let (sw, sh) = {
                    let Size {width, height} = self.data.viewport_size;
                    (width as f64, height as f64)
                };

                let cx = if self.data.x_axis_motion_inverted { sw - x } else { x };
                let cy = if self.data.y_axis_motion_inverted { sh - y } else { y };

                Motion::MouseCursor(cx, cy)
            },
            Motion::MouseScroll(x, y) => {
                let mx = if self.data.x_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                let my = if self.data.y_axis_scroll_inverted { -1.0f64 } else { 1.0 };
                Motion::MouseScroll(x * mx, y * my)
            },
            relative => relative
        }
    }
}

#[allow(missing_docs)]
pub struct InputRebind<A: Action> {
    keymap: HashMap<A, ButtonTuple>,
    mouse_data: MouseTranslationData
}

impl<A: Action> InputRebind<A> {
    #[allow(missing_docs)]
    pub fn new(size: Size) -> Self {
        InputRebind {
            keymap: HashMap::new(),
            mouse_data: MouseTranslationData::new(size)
        }
    }

    #[allow(missing_docs)]
    pub fn insert_action(&mut self, action: A) -> Option<ButtonTuple> {
        self.keymap.insert(action, ButtonTuple::new())
    }

    #[allow(missing_docs)]
    pub fn insert_action_with_buttons(&mut self, action: A, buttons: ButtonTuple) -> Option<ButtonTuple> {
        self.keymap.insert(action, buttons)
    }

    #[allow(missing_docs)]
    pub fn get_bindings(&self, action: &A) -> Option<&ButtonTuple> {
        self.keymap.get(action)
    }

    #[allow(missing_docs)]
    pub fn get_bindings_mut(&mut self, action: &mut A) -> Option<&mut ButtonTuple> {
        self.keymap.get_mut(action)
    }

    #[allow(missing_docs)]
    pub fn get_x_scroll_inverted(&self) -> &bool {
        &self.mouse_data.x_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_scroll_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.x_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_scroll_inverted(&self) -> &bool {
        &self.mouse_data.y_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_scroll_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.y_axis_scroll_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_motion_inverted(&self) -> &bool {
        &self.mouse_data.x_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_x_motion_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.x_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_motion_inverted(&self) -> &bool {
        &self.mouse_data.y_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_y_motion_inverted_mut(&mut self) -> &mut bool {
        &mut self.mouse_data.y_axis_motion_inverted
    }

    #[allow(missing_docs)]
    pub fn get_viewport_size(&self) -> &Size {
        &self.mouse_data.viewport_size
    }

    #[allow(missing_docs)]
    pub fn get_viewport_size_mut(&mut self) -> &mut Size {
        &mut self.mouse_data.viewport_size
    }
}

impl<A: Action> Default for InputRebind<A> {
    #[allow(missing_docs)]
    fn default() -> Self {
        InputRebind::new((800, 600).into())
    }
}

impl<A: Action> Into<InputTranslator<A>> for InputRebind<A> {
    #[allow(missing_docs)]
    fn into(self) -> InputTranslator<A> {
        let mut input_translator = InputTranslator::new(self.mouse_data.viewport_size);
        input_translator.mouse_translator.data = self.mouse_data;
        input_translator.keymap = self.keymap.values()
                                             .flat_map(|&bt| bt.into_iter())
                                             .filter_map(|x| x)
                                             .zip(self.keymap.keys().map(|x| *x))
                                             .collect();

        input_translator
    }
}

impl<A: Action> Into<InputRebind<A>> for InputTranslator<A> {
    #[allow(missing_docs)]
    fn into(self) -> InputRebind<A> {
        let mut input_rebind = InputRebind::new(self.mouse_translator.data.viewport_size);
        input_rebind.mouse_data = self.mouse_translator.data;
        //input_rebind.keymap = self.keymap.btn_map.
        //input_rebind.keymap = self.keymap.btn_map.drain().map(|(k, v)| (v, k)).collect();
        input_rebind
    }
}

impl ButtonTuple {
    fn into_iter(self) -> ButtonTupleIterator {
        ButtonTupleIterator {
            button_tuple: self,
            i: 0
        }
    }
}

struct ButtonTupleIterator {
    button_tuple: ButtonTuple,
    i: usize
}

impl Iterator for ButtonTupleIterator {
    type Item = Option<Button>;

    fn next(&mut self) -> Option<Self::Item> {
        let i = self.i;
        self.i += 1;
        match i {
            0 => Some(self.button_tuple.0),
            1 => Some(self.button_tuple.1),
            2 => Some(self.button_tuple.2),
            _ => None
        }
    }
}

<|endoftext|>


<commit_before>//! A pure-Rust LDAP client library using the Tokio stack.
//!
//! ## Usage
//!
//! In `Cargo.toml`:
//!
//! ```toml
//! [dependencies.ldap3]
//! version = "0.8"
//! ```
//!
//! ## Summary
//!
//! The library provides both synchronous and asynchronous interfaces. The [`LdapConn`](struct.LdapConn.html)
//! structure is the starting point for all synchronous operations. [`LdapConnAsync`](struct.LdapConnAsync.html)
//! is its asynchronous analogue, and [`Ldap`](struct.Ldap.html) is the low-level asynchronous handle used
//! internally by `LdapConn`, and explicitly by the users of the asynchronous interface.
//!
//! In the [struct list](#structs), async-related structs have an asterisk (__*__) after
//! the short description.
//!
//! The documentation is written for readers familiar with LDAP concepts and terminology,
//! which it won't attempt to explain.
//!
//! ## Compile-time features
//!
//! The following features are available at compile time:
//!
//! * __sync__ (enabled by default): Synchronous API support.
//!
//! * __tls__ (enabled by default): TLS support, backed by the `native-tls` crate, which uses
//!  a platform-specific TLS backend. This is an alias for __tls-native__.
//!
//! * __tls-rustls__ (disabled by default): TLS support, backed by the Rustls library.
//!
//! Without any features, only plain TCP connections (and Unix domain sockets on Unix-like
//! platforms) are available. For TLS support, __tls__ and __tls-rustls__ are mutually
//! exclusive: choosing both will produce a compile-time error.
//!
//! ## Examples
//!
//! The following two examples perform exactly the same operation and should produce identical
//! results. They should be run against the example server in the `data` subdirectory of the crate source.
//! Other sample programs expecting the same server setup can be found in the `examples` subdirectory.
//!
//! ### Synchronous search
//!
//! ```rust,no_run
//! use ldap3::{LdapConn, Scope, SearchEntry};
//! use ldap3::result::Result;
//!
//! fn main() -> Result<()> {
//!     let mut ldap = LdapConn::new("ldap://localhost:2389")?;
//!     let (rs, _res) = ldap.search(
//!         "ou=Places,dc=example,dc=org",
//!         Scope::Subtree,
//!         "(&(objectClass=locality)(l=ma*))",
//!         vec!["l"]
//!     )?.success()?;
//!     for entry in rs {
//!         println!("{:?}", SearchEntry::construct(entry));
//!     }
//!     Ok(ldap.unbind()?)
//! }
//! ```
//!
//! ### Asynchronous search
//!
//! ```rust,no_run
//! use ldap3::{LdapConnAsync, Scope, SearchEntry};
//! use ldap3::result::Result;
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let (conn, mut ldap) = LdapConnAsync::new("ldap://localhost:2389").await?;
//!     ldap3::drive!(conn);
//!     let (rs, _res) = ldap.search(
//!         "ou=Places,dc=example,dc=org",
//!         Scope::Subtree,
//!         "(&(objectClass=locality)(l=ma*))",
//!         vec!["l"]
//!     ).await?.success()?;
//!     for entry in rs {
//!         println!("{:?}", SearchEntry::construct(entry));
//!     }
//!     Ok(ldap.unbind().await?)
//! }
//! ```

#[macro_use]
extern crate nom;
#[macro_use]
pub extern crate log;

/// Type alias for the LDAP message ID.
pub type RequestId = i32;

pub mod adapters;
pub mod asn1 {
    //! ASN.1 structure construction and parsing.
    //!
    //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
    //! be extensively overhauled in the future. If you need examples of using the present interface
    //! for, e.g., implementing a new extended operation or a control, consult the source of existing
    //! exops/controls.
    pub use lber::common::TagClass;
    pub use lber::parse::{parse_tag, parse_uint};
    pub use lber::structure::{StructureTag, PL};
    pub use lber::structures::{
        ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
    };
    pub use lber::universal::Types;
    pub use lber::write;
    pub use lber::IResult;
}
mod conn;
pub mod controls {
    //! Control construction and parsing.
    //!
    //! A control can be associated with a request or a response. Several common
    //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
    //! directly by this library. If an implemented control has the same form for
    //! the request and the response, there will be a single structure for both.
    //! (This is the case for `PagedResults`.) If the response control is different,
    //! its name will consist of the request control name with the `Resp` suffix.
    //!
    //! A request control can be created by instantiating its structure and converting
    //! it to ASN.1 with `into()` when passing the instance or constructing the request
    //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
    //! A third-party control must implement the conversion from an instance
    //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
    //!
    //! `RawControl`, together with an optional instance of [`ControlType`](enum.ControlType.html),
    //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
    //! of the result of all LDAP operation which return one.
    //!
    //! The first element of `Control` will have a value if the parser recognizes
    //! the control's OID as one that is implemented by the library itself. Since the
    //! list of implemented controls is expected to grow, the `ControlType` enum cannot
    //! be exhaustively matched.
    //!
    //! A recognized response control can be parsed by calling
    //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
    //! representing it. A third-party control must implement the
    //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
    //!
    //! ### Example
    //!
    //! With an `LdapResult` in `res`, iterating through controls and matching the desired ones
    //! could be done like this:
    //!
    //! ```rust,no_run
    //! # use ldap3::controls::{Control, ControlType, PagedResults};
    //! # use ldap3::result::Result;
    //! # use ldap3::LdapConn;
    //! # fn main() -> Result<()> {
    //! # let mut ldap = LdapConn::new("ldap://localhost")?;
    //! # let res = ldap.simple_bind("", "")?.success()?;
    //! for ctrl in res.ctrls {
    //!     match ctrl {
    //!         // matching a control implemented by the library
    //!         Control(Some(ControlType::PagedResults), ref raw) => {
    //!             dbg!(raw.parse::<PagedResults>());
    //!         },
    //!         // matching a control unknown to the library
    //!         // the OID is actually that of PagedResults
    //!         Control(None, ref raw) if raw.ctype == "1.2.840.113556.1.4.319" => {
    //!             dbg!(raw.parse::<PagedResults>());
    //!         },
    //!         _ => (),
    //!     }
    //! }
    //! # Ok(())
    //! # }
    pub use crate::controls_impl::parse_syncinfo;
    pub use crate::controls_impl::{
        Assertion, ManageDsaIt, MatchedValues, PagedResults, ProxyAuth, RelaxRules,
    };
    pub use crate::controls_impl::{
        Control, ControlParser, ControlType, CriticalControl, MakeCritical, RawControl,
    };
    pub use crate::controls_impl::{
        EntryState, RefreshMode, SyncDone, SyncInfo, SyncRequest, SyncState,
    };
    pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
}
mod controls_impl;
mod exop_impl;
pub mod exop {
    //! Extended operation construction and parsing.
    //!
    //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
    //! exop is implemented by this library, it may have one or two associated structs;
    //! one for constructing requests, and another for parsing responses. If request and
    //! response are the same, there is only the request struct; if they are different,
    //! the response struct's name will consist of the request struct name with the
    //! `Resp` suffix.
    //!
    //! A request struct must implement the `From` conversion of itself into `Exop`.
    //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
    //! trait.
    pub use crate::exop_impl::{
        Exop, ExopParser, PasswordModify, PasswordModifyResp, WhoAmI, WhoAmIResp,
    };
}
mod filter;
mod ldap;
mod protocol;
pub mod result;
mod search;
#[cfg(feature = "sync")]
mod sync;
mod util;

pub use conn::{LdapConnAsync, LdapConnSettings};
pub use filter::parse as parse_filter;
pub use ldap::{Ldap, Mod};
pub use result::{LdapError, LdapResult, SearchResult};
pub use search::parse_refs;
pub use search::{
    DerefAliases, ResultEntry, Scope, SearchEntry, SearchOptions, SearchStream, StreamState,
};
#[cfg(feature = "sync")]
pub use sync::{EntryStream, LdapConn};
pub use util::{dn_escape, get_url_params, ldap_escape, ldap_str_unescape, LdapUrlExt, LdapUrlParams};
<commit_msg>Cargo fmt<commit_after>//! A pure-Rust LDAP client library using the Tokio stack.
//!
//! ## Usage
//!
//! In `Cargo.toml`:
//!
//! ```toml
//! [dependencies.ldap3]
//! version = "0.8"
//! ```
//!
//! ## Summary
//!
//! The library provides both synchronous and asynchronous interfaces. The [`LdapConn`](struct.LdapConn.html)
//! structure is the starting point for all synchronous operations. [`LdapConnAsync`](struct.LdapConnAsync.html)
//! is its asynchronous analogue, and [`Ldap`](struct.Ldap.html) is the low-level asynchronous handle used
//! internally by `LdapConn`, and explicitly by the users of the asynchronous interface.
//!
//! In the [struct list](#structs), async-related structs have an asterisk (__*__) after
//! the short description.
//!
//! The documentation is written for readers familiar with LDAP concepts and terminology,
//! which it won't attempt to explain.
//!
//! ## Compile-time features
//!
//! The following features are available at compile time:
//!
//! * __sync__ (enabled by default): Synchronous API support.
//!
//! * __tls__ (enabled by default): TLS support, backed by the `native-tls` crate, which uses
//!  a platform-specific TLS backend. This is an alias for __tls-native__.
//!
//! * __tls-rustls__ (disabled by default): TLS support, backed by the Rustls library.
//!
//! Without any features, only plain TCP connections (and Unix domain sockets on Unix-like
//! platforms) are available. For TLS support, __tls__ and __tls-rustls__ are mutually
//! exclusive: choosing both will produce a compile-time error.
//!
//! ## Examples
//!
//! The following two examples perform exactly the same operation and should produce identical
//! results. They should be run against the example server in the `data` subdirectory of the crate source.
//! Other sample programs expecting the same server setup can be found in the `examples` subdirectory.
//!
//! ### Synchronous search
//!
//! ```rust,no_run
//! use ldap3::{LdapConn, Scope, SearchEntry};
//! use ldap3::result::Result;
//!
//! fn main() -> Result<()> {
//!     let mut ldap = LdapConn::new("ldap://localhost:2389")?;
//!     let (rs, _res) = ldap.search(
//!         "ou=Places,dc=example,dc=org",
//!         Scope::Subtree,
//!         "(&(objectClass=locality)(l=ma*))",
//!         vec!["l"]
//!     )?.success()?;
//!     for entry in rs {
//!         println!("{:?}", SearchEntry::construct(entry));
//!     }
//!     Ok(ldap.unbind()?)
//! }
//! ```
//!
//! ### Asynchronous search
//!
//! ```rust,no_run
//! use ldap3::{LdapConnAsync, Scope, SearchEntry};
//! use ldap3::result::Result;
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let (conn, mut ldap) = LdapConnAsync::new("ldap://localhost:2389").await?;
//!     ldap3::drive!(conn);
//!     let (rs, _res) = ldap.search(
//!         "ou=Places,dc=example,dc=org",
//!         Scope::Subtree,
//!         "(&(objectClass=locality)(l=ma*))",
//!         vec!["l"]
//!     ).await?.success()?;
//!     for entry in rs {
//!         println!("{:?}", SearchEntry::construct(entry));
//!     }
//!     Ok(ldap.unbind().await?)
//! }
//! ```

#[macro_use]
extern crate nom;
#[macro_use]
pub extern crate log;

/// Type alias for the LDAP message ID.
pub type RequestId = i32;

pub mod adapters;
pub mod asn1 {
    //! ASN.1 structure construction and parsing.
    //!
    //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
    //! be extensively overhauled in the future. If you need examples of using the present interface
    //! for, e.g., implementing a new extended operation or a control, consult the source of existing
    //! exops/controls.
    pub use lber::common::TagClass;
    pub use lber::parse::{parse_tag, parse_uint};
    pub use lber::structure::{StructureTag, PL};
    pub use lber::structures::{
        ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
    };
    pub use lber::universal::Types;
    pub use lber::write;
    pub use lber::IResult;
}
mod conn;
pub mod controls {
    //! Control construction and parsing.
    //!
    //! A control can be associated with a request or a response. Several common
    //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
    //! directly by this library. If an implemented control has the same form for
    //! the request and the response, there will be a single structure for both.
    //! (This is the case for `PagedResults`.) If the response control is different,
    //! its name will consist of the request control name with the `Resp` suffix.
    //!
    //! A request control can be created by instantiating its structure and converting
    //! it to ASN.1 with `into()` when passing the instance or constructing the request
    //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
    //! A third-party control must implement the conversion from an instance
    //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
    //!
    //! `RawControl`, together with an optional instance of [`ControlType`](enum.ControlType.html),
    //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
    //! of the result of all LDAP operation which return one.
    //!
    //! The first element of `Control` will have a value if the parser recognizes
    //! the control's OID as one that is implemented by the library itself. Since the
    //! list of implemented controls is expected to grow, the `ControlType` enum cannot
    //! be exhaustively matched.
    //!
    //! A recognized response control can be parsed by calling
    //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
    //! representing it. A third-party control must implement the
    //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
    //!
    //! ### Example
    //!
    //! With an `LdapResult` in `res`, iterating through controls and matching the desired ones
    //! could be done like this:
    //!
    //! ```rust,no_run
    //! # use ldap3::controls::{Control, ControlType, PagedResults};
    //! # use ldap3::result::Result;
    //! # use ldap3::LdapConn;
    //! # fn main() -> Result<()> {
    //! # let mut ldap = LdapConn::new("ldap://localhost")?;
    //! # let res = ldap.simple_bind("", "")?.success()?;
    //! for ctrl in res.ctrls {
    //!     match ctrl {
    //!         // matching a control implemented by the library
    //!         Control(Some(ControlType::PagedResults), ref raw) => {
    //!             dbg!(raw.parse::<PagedResults>());
    //!         },
    //!         // matching a control unknown to the library
    //!         // the OID is actually that of PagedResults
    //!         Control(None, ref raw) if raw.ctype == "1.2.840.113556.1.4.319" => {
    //!             dbg!(raw.parse::<PagedResults>());
    //!         },
    //!         _ => (),
    //!     }
    //! }
    //! # Ok(())
    //! # }
    pub use crate::controls_impl::parse_syncinfo;
    pub use crate::controls_impl::{
        Assertion, ManageDsaIt, MatchedValues, PagedResults, ProxyAuth, RelaxRules,
    };
    pub use crate::controls_impl::{
        Control, ControlParser, ControlType, CriticalControl, MakeCritical, RawControl,
    };
    pub use crate::controls_impl::{
        EntryState, RefreshMode, SyncDone, SyncInfo, SyncRequest, SyncState,
    };
    pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
}
mod controls_impl;
mod exop_impl;
pub mod exop {
    //! Extended operation construction and parsing.
    //!
    //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
    //! exop is implemented by this library, it may have one or two associated structs;
    //! one for constructing requests, and another for parsing responses. If request and
    //! response are the same, there is only the request struct; if they are different,
    //! the response struct's name will consist of the request struct name with the
    //! `Resp` suffix.
    //!
    //! A request struct must implement the `From` conversion of itself into `Exop`.
    //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
    //! trait.
    pub use crate::exop_impl::{
        Exop, ExopParser, PasswordModify, PasswordModifyResp, WhoAmI, WhoAmIResp,
    };
}
mod filter;
mod ldap;
mod protocol;
pub mod result;
mod search;
#[cfg(feature = "sync")]
mod sync;
mod util;

pub use conn::{LdapConnAsync, LdapConnSettings};
pub use filter::parse as parse_filter;
pub use ldap::{Ldap, Mod};
pub use result::{LdapError, LdapResult, SearchResult};
pub use search::parse_refs;
pub use search::{
    DerefAliases, ResultEntry, Scope, SearchEntry, SearchOptions, SearchStream, StreamState,
};
#[cfg(feature = "sync")]
pub use sync::{EntryStream, LdapConn};
pub use util::{
    dn_escape, get_url_params, ldap_escape, ldap_str_unescape, LdapUrlExt, LdapUrlParams,
};
<|endoftext|>


<commit_before>#![allow(unstable)]
#![feature(plugin_registrar, quote)]
#![deny(missing_docs, warnings)]

//! Stainless is a lightweight, flexible, unopinionated testing framework.
//!
//! ## Example
//!
//! ```ignore
//! describe! stainless {
//!     before_each {
//!         // Start up a test.
//!         let mut stainless = true;
//!     }
//!
//!     it "makes organizing tests easy" {
//!         // Do the test.
//!         assert!(stainless);
//!     }
//!
//!     after_each {
//!         // End the test.
//!         stainless = false;
//!     }
//!
//!     describe! nesting {
//!         it "makes it simple to categorize tests" {
//!             // It even generates submodules!
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Expands to (roughly):
//!
//! ```rust
//! mod stainless {
//!     #[test]
//!     fn makes_organizing_tests_easy() {
//!         let mut stainless = true;
//!         assert!(stainless);
//!         stainless = false;
//!     }
//!
//!     mod nesting {
//!         #[test]
//!         fn makes_it_simple_to_categorize_tests() {
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Stainless exports the `describe!` syntax extension, which allows
//! you to quickly generate complex testing hierarchies and reduce
//! boilerplate through `before_each` and `after_each`.
//!
//! Stainless currently supports 4 types of subblocks:
//!  - `before_each` and `after_each`,
//!  - `it` and `failing`
//!  - `bench`
//!  - nested `describe!`
//!
//! `before_each` and `after_each` allow you to group common initialization
//! and teardown for a group of tests into a single block, shortening your
//! tests.
//!
//! `it` generates tests which use `before_each` and `after_each`. `failing`
//! does the same, except the generated tests are marked with `#[should_fail]`.
//!
//! `bench` allows you to generate benchmarks in the same fashion, though
//! `before_each` and `after_each` blocks do not affect `bench` blocks.
//!
//! Nested `describe!` blocks allow you to better organize your tests into
//! small units and gives you granular control over where `before_each` and
//! `after_each` apply.
//!
//! Together, these 3 types of subblocks give you more flexibility and control
//! than the built in testing infrastructure.
//!

extern crate syntax;
extern crate rustc;

use self::describe::describe;
use rustc::plugin;
use syntax::parse::token;

mod describe;
mod parse;
mod test;
mod bench;
mod generate;

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut plugin::Registry) {
    reg.register_syntax_extension(
        token::intern("describe"),
        syntax::ext::base::IdentTT(Box::new(describe), None)
    );
}

<commit_msg>(fix) Add necessary features.<commit_after>#![feature(plugin_registrar, quote, rustc_private, core, collections)]
#![deny(missing_docs, warnings)]

//! Stainless is a lightweight, flexible, unopinionated testing framework.
//!
//! ## Example
//!
//! ```ignore
//! describe! stainless {
//!     before_each {
//!         // Start up a test.
//!         let mut stainless = true;
//!     }
//!
//!     it "makes organizing tests easy" {
//!         // Do the test.
//!         assert!(stainless);
//!     }
//!
//!     after_each {
//!         // End the test.
//!         stainless = false;
//!     }
//!
//!     describe! nesting {
//!         it "makes it simple to categorize tests" {
//!             // It even generates submodules!
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Expands to (roughly):
//!
//! ```rust
//! mod stainless {
//!     #[test]
//!     fn makes_organizing_tests_easy() {
//!         let mut stainless = true;
//!         assert!(stainless);
//!         stainless = false;
//!     }
//!
//!     mod nesting {
//!         #[test]
//!         fn makes_it_simple_to_categorize_tests() {
//!             assert_eq!(2u, 2u);
//!         }
//!     }
//! }
//! ```
//!
//! Stainless exports the `describe!` syntax extension, which allows
//! you to quickly generate complex testing hierarchies and reduce
//! boilerplate through `before_each` and `after_each`.
//!
//! Stainless currently supports 4 types of subblocks:
//!  - `before_each` and `after_each`,
//!  - `it` and `failing`
//!  - `bench`
//!  - nested `describe!`
//!
//! `before_each` and `after_each` allow you to group common initialization
//! and teardown for a group of tests into a single block, shortening your
//! tests.
//!
//! `it` generates tests which use `before_each` and `after_each`. `failing`
//! does the same, except the generated tests are marked with `#[should_fail]`.
//!
//! `bench` allows you to generate benchmarks in the same fashion, though
//! `before_each` and `after_each` blocks do not affect `bench` blocks.
//!
//! Nested `describe!` blocks allow you to better organize your tests into
//! small units and gives you granular control over where `before_each` and
//! `after_each` apply.
//!
//! Together, these 3 types of subblocks give you more flexibility and control
//! than the built in testing infrastructure.
//!

extern crate syntax;
extern crate rustc;

use self::describe::describe;
use rustc::plugin;
use syntax::parse::token;

mod describe;
mod parse;
mod test;
mod bench;
mod generate;

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut plugin::Registry) {
    reg.register_syntax_extension(
        token::intern("describe"),
        syntax::ext::base::IdentTT(Box::new(describe), None)
    );
}

<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! SOS: the Stupid Operating System
//!
//! SOS is a simple, tiny toy OS implemented in Rust.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel //! hacking, so don't expect anything new or exciting out of this project.

#![crate_name = "sos_kernel"]
#![crate_type = "staticlib"]
#![feature( no_std
          , lang_items
          , asm )]
#![feature( const_fn
          , core_slice_ext
          , slice_patterns
          , iter_cmp
          )]
#![feature(collections)]

#![no_std]

extern crate collections;
extern crate rlibc;
extern crate spin;

extern crate sos_multiboot2 as multiboot;
extern crate sos_alloc as alloc;

#[macro_use] extern crate sos_vga as vga;
#[macro_use] extern crate bitflags;

pub mod arch;
#[macro_use] pub mod io;
pub mod util;
pub mod panic;
pub mod memory;

use arch::cpu;

/// Kernel main loop
pub fn kernel_main() {
    loop { }
}

/// Kernel initialization function called from ASM
///
/// The kernel main loop expects to be passed the address of a valid
/// Multiboot 2 info struct. It's the bootloader's responsibility to ensure
/// that this is passed in the correct register as expected by the calling
/// convention (`edi` on x86). If this isn't there, you can expect to have a
/// bad problem and not go to space today.
#[no_mangle]
pub extern fn kernel_start(multiboot_addr: usize) {
    io::term::CONSOLE.lock().clear();

    println!("Hello from the kernel!");

    // Unpack multiboot tag
    let boot_info = unsafe { multiboot::Info::from(multiboot_addr) };
    let mmap_tag // Extract the memory map tag from the multiboot info
        = boot_info.mem_map()
                   .expect("Memory map tag required!");

    println!("Detected memory areas:");
    for a in mmap_tag.areas() {
        println!("     start: {:#08x}, end: {:#08x}"
                , a.base, a.length );
    }

    let elf_sections_tag // Extract ELF sections tag from the multiboot info
        = boot_info.elf64_sections()
                   .expect("ELF sections tag required!");

    println!("Detecting kernel ELF sections:");
    // for section in elf_sections_tag.sections() {
    //
    // }

    let kernel_begin
        = elf_sections_tag.sections()
            .map(|s| {
                println!("     address: {:#08x}, size: {:#08x}, flags: {:#08x}"
                        , s.address
                        , s.length
                        , s.flags );
                s.address })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let mut n_elf_sections = 0;
    let kernel_end
        = elf_sections_tag.sections()
            .map(|s| { n_elf_sections += 1;
                     s.address })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    println!( "Detected {} kernel ELF sections.", n_elf_sections);
    println!( "Kernel begins at {:#x} and ends at {:#x}."
             , kernel_begin, kernel_end );

    let multiboot_end = multiboot_addr + boot_info.length as usize;

    println!( "Multiboot info begins at {:#x} and ends at {:#x}."
             , multiboot_addr, multiboot_end);
    //
    // let mut alloc
    //     = SimpleAreaAllocator::new( kernel_begin as usize
    //                               , kernel_end as usize
    //                               , multiboot_addr, multiboot_end
    //                               , mmap_tag.areas());

    // alloc.allocate(0,0);

    // let heap_area
    //     = mmap_tag.areas()
    //             //   .filter(|area| area.base > kernel_end &&
    //             //                  area.base > multiboot_end as u64 )
    //               .max_by(|area| area.length )
    //               .expect("Couldn't find a suitable memory area for heap!");
    //
    // println!( "Heap begins at {:#x} and ends at {:#x}."
    //         , heap_area.base
    //         , heap_area.base + heap_area.length );
    print!("Intializing heap...    ");
    unsafe { memory::init_heap() };
    println!( "[DONE]\nHeap begins at {:#x} and ends at {:#x}."
            , memory::heap_base_addr(), memory::heap_top_addr() );

    // let mut a_vec = collections::vec::Vec::<usize>::new();
    // println!( "TEST: Created a vector in kernel space! {:?}", a_vec);
    // a_vec.push(1);
    // println!( "TEST: pushed to vec: {:?}", a_vec);
    // a_vec.push(2);
    // println!( "TEST: pushed to vec: {:?}", a_vec);
    //

    // println!( "Created initial allocator." );

    // for i in 0.. {
    //     if let None = alloc.allocate() {
    //         println!("Allocated {} frames", i);
    //         break;
    //     }
    // }
    println!("Intializing interrupts...");
    unsafe { cpu::interrupts::initialize(); };
    println!("Intializing interrupts...    [DONE]");

    kernel_main()
}
<commit_msg>Kernel main loop made prettier<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! SOS: the Stupid Operating System
//!
//! SOS is a simple, tiny toy OS implemented in Rust.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel //! hacking, so don't expect anything new or exciting out of this project.

#![crate_name = "sos_kernel"]
#![crate_type = "staticlib"]
#![feature( no_std
          , lang_items
          , asm )]
#![feature( const_fn
          , core_slice_ext
          , slice_patterns
          , iter_cmp
          )]
#![feature(collections)]

#![no_std]

extern crate collections;
extern crate rlibc;
extern crate spin;

extern crate sos_multiboot2 as multiboot;
extern crate sos_alloc as alloc;

#[macro_use] extern crate sos_vga as vga;
#[macro_use] extern crate bitflags;

pub mod arch;
#[macro_use] pub mod io;
pub mod util;
pub mod panic;
pub mod memory;

use arch::cpu;

/// Kernel main loop
pub fn kernel_main() {
    loop { }
}

/// Kernel initialization function called from ASM
///
/// The kernel main loop expects to be passed the address of a valid
/// Multiboot 2 info struct. It's the bootloader's responsibility to ensure
/// that this is passed in the correct register as expected by the calling
/// convention (`edi` on x86). If this isn't there, you can expect to have a
/// bad problem and not go to space today.
#[no_mangle]
pub extern fn kernel_start(multiboot_addr: usize) {
    io::term::CONSOLE.lock().clear();

    println!("Hello from the kernel!");

    // -- Unpack multiboot tag ------------------------------------------------
    let boot_info = unsafe { multiboot::Info::from(multiboot_addr) };

    let mmap_tag // Extract the memory map tag from the multiboot info
        = boot_info.mem_map()
                   .expect("Memory map tag required!");

    println!("Detected memory areas:");
    for a in mmap_tag.areas() {
        println!("     start: {:#08x}, end: {:#08x}"
                , a.base, a.length );
    }

    let elf_sections_tag // Extract ELF sections tag from the multiboot info
        = boot_info.elf64_sections()
                   .expect("ELF sections tag required!");

    println!("Detecting kernel ELF sections:");

    let kernel_begin    // Extract kernel ELF sections from  multiboot info
        = elf_sections_tag.sections()
            .map(|s| {
                println!("     address: {:#08x}, size: {:#08x}, flags: {:#08x}"
                        , s.address
                        , s.length
                        , s.flags );
                s.address })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let mut n_elf_sections = 0;
    let kernel_end
        = elf_sections_tag.sections()
            .map(|s| { n_elf_sections += 1;
                     s.address })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    println!( "Detected {} kernel ELF sections.", n_elf_sections);
    println!( "Kernel begins at {:#x} and ends at {:#x}."
             , kernel_begin, kernel_end );

    let multiboot_end = multiboot_addr + boot_info.length as usize;

    println!( "Multiboot info begins at {:#x} and ends at {:#x}."
             , multiboot_addr, multiboot_end);

    // -- initialize interrupts ----------------------------------------------
    unsafe {
        println!("Intializing interrupts...");
        cpu::interrupts::initialize();
        println!("Intializing interrupts...    [DONE]" );
    };

    // -- initialize the heap ------------------------------------------------
    unsafe {
        print!("Intializing heap...    ");
        memory::init_heap();
        println!( "[DONE]\nHeap begins at {:#x} and ends at {:#x}."
                , memory::heap_base_addr(), memory::heap_top_addr() );
    };

    // let mut a_vec = collections::vec::Vec::<usize>::new();
    // println!( "TEST: Created a vector in kernel space! {:?}", a_vec);
    // a_vec.push(1);
    // println!( "TEST: pushed to vec: {:?}", a_vec);
    // a_vec.push(2);
    // println!( "TEST: pushed to vec: {:?}", a_vec);

    // -- call into kernel main loop ------------------------------------------
    // (currently, this does nothing)
    kernel_main()
}
<|endoftext|>


<commit_before>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(plugin)]
#![feature(io)]
#![feature(core)]
#![feature(ip)]
#![feature(tcp)]
#![feature(collections)]
#![feature(std_misc)]
#![feature(convert)]
#![feature(slice_patterns)]
#![cfg_attr(test, feature(test))]

#![plugin(regex_macros)]

#[cfg(test)]
extern crate test;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate unix_socket;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<commit_msg>Remove unneeded features<commit_after>//! ### rust-mysql-simple
//! Mysql client library implemented in rust nightly.
//!
//! #### Install
//! Just include another `[dependencies.*]` section into your Cargo.toml:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! ```
//!
//! rust-mysql-simple offer support of SSL via `ssl` cargo feature which is enabled by default. If you have no plans to use SSL, then you should disable that feature to not to depend on rust-openssl:
//!
//! ```toml
//! [dependencies.mysql]
//! git = "https://github.com/blackbeam/rust-mysql-simple"
//! default-features = false
//! ```
//!
//! #### Use
//! You should start by creating [`MyOpts`](conn/struct.MyOpts.html) struct.
//!
//! Then you can create [`MyPool`](conn/pool/struct.MyPool.html) which should be
//! enough to work with mysql server.
#![crate_name="mysql"]
#![crate_type="rlib"]
#![crate_type="dylib"]

#![feature(unsafe_destructor)]
#![feature(plugin)]
#![feature(core)]
#![feature(ip)]
#![feature(tcp)]
#![feature(collections)]
#![feature(std_misc)]
#![feature(slice_patterns)]
#![cfg_attr(test, feature(test))]

#![plugin(regex_macros)]

#[cfg(test)]
extern crate test;

extern crate core;
extern crate time;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate regex;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate unix_socket;

mod scramble;
pub mod consts;
pub mod error;
mod packet;
mod io;
pub mod value;
pub mod conn;
<|endoftext|>


<commit_before>extern crate hyper;
extern crate rustc_serialize;

mod rep;

use hyper::Client;
use hyper::method::Method;
use hyper::header::ContentType;
use hyper::header::Authorization;
use rustc_serialize::json;
pub use rep::*;
use std::io::{Read, Result};

/// reference point for creating new posts
pub struct UserRef<'a> {
    medium: &'a Medium<'a>,
    id: &'a str
}

impl<'a> UserRef<'a> {
    pub fn new(medium: &'a Medium<'a>, id: &'a str) -> UserRef<'a> {
        UserRef {
            medium: medium,
            id: id
        }
    }

    /// posts a new story
    pub fn post(&self, post: &NewPost) -> Result<Post> {
        let data = json::encode(&post).unwrap();
        let body = try!(
            self.medium.post(
                &format!("/v1/users/{}/posts", self.id),
                data.as_bytes()
            )
        );
        let post: Data<Post> = json::decode(&body).unwrap();
        Ok(post.data)
    }
}

/// Entry point for access to medium.com api
pub struct Medium<'a> {
    client: &'a Client,
    token: Option<&'a str>,
    host: &'a str
}

impl<'a> Medium <'a> {
    /// creates a new instance of a Medium client
    /// token can be acquired [here](https://medium.com/me/settings)
    pub fn new(
        client: &'a Client,
        token: Option<&'a str>
    ) -> Medium<'a> {
        Self::host(
            client, token, "https://api.medium.com"
        )
    }

    /// creates an instance of a Medium client for a specific host
    pub fn host(
        client: &'a Client,
        token: Option<&'a str>,
        host: &'a str
    ) -> Medium<'a> {
        Medium {
            client: client,
            token: token,
            host: host
        }
    }

    /// access to the authentied members user info
    pub fn me(&self) -> Result<User> {
        let body = try!(self.get("/v1/me"));
        let data: Data<User> = json::decode(&body).unwrap();
        Ok(data.data)
    }

    /// access to a user reference
    pub fn users(&self, id: &'a str) -> UserRef {
        UserRef::new(self, id)
    }

    fn request(
        &self,
        method: Method,
        uri: &str,
        body: Option<(ContentType, &'a [u8])>
     ) -> Result<String> {
        let url = format!("{}{}", self.host, uri);
        let request_builder = self.client.request(
            method,
            &url
        );
        let authenticated = match self.token {
            Some(token) =>
                request_builder.header(
                    Authorization(format!("Bearer {}", token))
                ),
            _ => request_builder
        };
        let mut res = match body {
            Some((typ, body)) => {
                authenticated.header(
                    typ
                    )
                    .body(body)
                    .send()
                    .unwrap()
            }, _ => authenticated.send().unwrap()
        };
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();
        Ok(body)
    }

    fn post(&self, uri: &str, message: &[u8]) -> Result<String> {
        self.request(
            Method::Post,
            uri,
            Some((ContentType::json(), message))
        )
    }

    fn get(&self, uri: &str) -> Result<String> {
        self.request(
            Method::Get,
            uri,
            None
        )
    }
}
<commit_msg>cleaner<commit_after>extern crate hyper;
extern crate rustc_serialize;

mod rep;

use hyper::Client;
use hyper::method::Method;
use hyper::header::ContentType;
use hyper::header::Authorization;
use rustc_serialize::{Decodable, json};
pub use rep::*;
use std::io::{Read, Result};

/// reference point for creating new posts
pub struct UserRef<'a> {
    medium: &'a Medium<'a>,
    id: &'a str
}

impl<'a> UserRef<'a> {
    pub fn new(medium: &'a Medium<'a>, id: &'a str) -> UserRef<'a> {
        UserRef {
            medium: medium,
            id: id
        }
    }

    /// posts a new story
    pub fn post(&self, post: &NewPost) -> Result<Post> {
        let data = json::encode(&post).unwrap();
        self.medium.post::<Data<Post>>(
            &format!("/v1/users/{}/posts", self.id),
            data.as_bytes()
        ).map(|d| d.data)
    }
}

/// Entry point for access to medium.com api
pub struct Medium<'a> {
    client: &'a Client,
    token: Option<&'a str>,
    host: &'a str
}

impl<'a> Medium <'a> {
    /// creates a new instance of a Medium client
    /// token can be acquired [here](https://medium.com/me/settings)
    pub fn new(
        client: &'a Client,
        token: Option<&'a str>
    ) -> Medium<'a> {
        Self::host(
            client, token, "https://api.medium.com"
        )
    }

    /// creates an instance of a Medium client for a specific host
    pub fn host(
        client: &'a Client,
        token: Option<&'a str>,
        host: &'a str
    ) -> Medium<'a> {
        Medium {
            client: client,
            token: token,
            host: host
        }
    }

    /// access to the authentied members user info
    pub fn me(&self) -> Result<User> {
        self.get::<Data<User>>("/v1/me").map(|d| d.data)
    }

    /// access to a user reference
    pub fn users(&self, id: &'a str) -> UserRef {
        UserRef::new(self, id)
    }

    fn request<T>(
        &self,
        method: Method,
        uri: &str,
        body: Option<(ContentType, &'a [u8])>
     ) -> Result<T> where T: Decodable {
        let url = format!("{}{}", self.host, uri);
        let request_builder = self.client.request(
            method,
            &url
        );
        let authenticated = match self.token {
            Some(token) =>
                request_builder.header(
                    Authorization(format!("Bearer {}", token))
                ),
            _ => request_builder
        };
        let mut res = match body {
            Some((typ, body)) => {
                authenticated.header(
                    typ
                    )
                    .body(body)
                    .send()
                    .unwrap()
            }, _ => authenticated.send().unwrap()
        };
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();
        Ok(json::decode::<T>(&body).unwrap())
    }

    fn post<T>(
        &self, uri: &str, message: &[u8]
    ) -> Result<T> where T: Decodable {
        self.request(
            Method::Post,
            uri,
            Some((ContentType::json(), message))
        )
    }

    fn get<T>(
        &self, uri: &str
    ) -> Result<T> where T: Decodable {
        self.request(
            Method::Get,
            uri,
            None
        )
    }
}
<|endoftext|>