<commit_before>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
}

// FIXME: With default methods, we won't need this anymore
trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
}

impl<ADDR: Int+Copy, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let d: T = num::cast(self.get(addr + num::cast(i)));
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let d: T = num::cast(self.get(addr + num::cast(i)));
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			val = val + (d << shift);
		}
		val
	}
}

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

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}
}
<commit_msg>Added set methods to addressable trait<commit_after>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
	pub fn set (&mut self, addr: ADDR, data: DATA);
}

// FIXME: With default methods, we won't need this anymore
trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int+Copy, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

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

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x12, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<|endoftext|>


<commit_before>//! An enum mapping type.
//!
//! It is implemented using an array type, so using it is as fast as using Rust
//! arrays.
//!
//! # Examples
//!
//! ```
//! #[macro_use]
//! extern crate enum_map;
//!
//! use enum_map::EnumMap;
//!
//! #[derive(Debug, EnumMap)]
//! enum Example {
//!     A,
//!     B,
//!     C,
//! }
//!
//! fn main() {
//!     let mut map = enum_map! {
//!         Example::A => 1,
//!         Example::B => 2,
//!         Example::C => 3,
//!     };
//!     map[Example::C] = 4;
//!
//!     assert_eq!(map[Example::A], 1);
//!
//!     for (key, &value) in &map {
//!         println!("{:?} has {} as value.", key, value);
//!     }
//! }
//! ```

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

#[macro_use]
extern crate array_macro;
// This allows to quiet "proc macro crates and `#[no_link]` crates have no
// effect without `#[macro_use]`" warning. Just using extern DOES have
// an effect of letting me export the macro.
#[allow(unused_imports)]
#[macro_use]
extern crate enum_map_derive;

/// Enum map constructor.
///
/// This macro allows to create a new enum map in a type safe way. It takes
/// a list of `,` separated pairs separated by `=>`. Left side is `|`
/// separated list of enum keys, or `_` to match all unmatched enum keys,
/// while right side is a value.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
///     D,
/// }
///
/// fn main() {
///     let enum_map = enum_map! {
///         Example::A | Example::B => 1,
///         Example::C => 2,
///         _ => 3,
///     };
///     assert_eq!(enum_map[Example::A], 1);
///     assert_eq!(enum_map[Example::B], 1);
///     assert_eq!(enum_map[Example::C], 2);
///     assert_eq!(enum_map[Example::D], 3);
/// }
/// ```
#[macro_export]
macro_rules! enum_map {
    {$($t:tt)*} => {
        $crate::EnumMap::from(|k| match k { $($t)* })
    };
}

mod enummap_impls;
mod internal;
mod iter;
mod serde;

pub use internal::Internal;
pub use iter::{Iter, IterMut};
// `*` here means re-exporting a derive procedural macro.
pub use enum_map_derive::*;

use core::slice;

/// An enum mapping.
///
/// This internally uses an array which stores a value for each possible
/// enum value. To work, it requires implementation of internal (private,
/// although public due to macro limitations) trait which allows extracting
/// information about an enum, which can be automatically generated using
/// `#[derive(EnumMap)]` from `enum_map_derive` crate.
///
/// Additionally, `bool` and `u8` automatically derives from `EnumMap`. While
/// `u8` is not technically an enum, it's convenient to consider it like one.
/// In particular, [reverse-complement in benchmark game] could be using `u8`
/// as an enum.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// use enum_map::EnumMap;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = EnumMap::new();
///     // new initializes map with default values
///     assert_eq!(map[Example::A], 0);
///     map[Example::A] = 3;
///     assert_eq!(map[Example::A], 3);
/// }
/// ```
///
/// [reverse-complement in benchmark game]:
///     http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=rust&id=2
#[derive(Debug)]
pub struct EnumMap<K: Internal<V>, V> {
    array: K::Array,
}

impl<K: Internal<V>, V: Default> EnumMap<K, V>
where
    K::Array: Default,
{
    /// Creates an enum map with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// #[derive(EnumMap)]
    /// enum Example {
    ///     A,
    /// }
    ///
    /// fn main() {
    ///     let enum_map = EnumMap::<_, i32>::new();
    ///     assert_eq!(enum_map[Example::A], 0);
    /// }
    /// ```
    pub fn new() -> Self {
        EnumMap::default()
    }
}

impl<K: Internal<V>, V> EnumMap<K, V> {
    /// Returns an iterator over enum map.
    pub fn iter(&self) -> Iter<K, V> {
        self.into_iter()
    }

    /// Returns a mutable iterator over enum map.
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        self.into_iter()
    }

    /// Returns number of elements in enum map.
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }

    /// Returns whether the enum variant set is empty.
    ///
    /// This isn't particularly useful, as there is no real reason to use
    /// enum map for enums without variants. However, it is provided for
    /// consistency with data structures providing len method (and I will
    /// admit, to avoid clippy warnings).
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// #[derive(EnumMap)]
    /// enum Void {}
    ///
    /// #[derive(EnumMap)]
    /// enum SingleVariant {
    ///     Variant,
    /// }
    ///
    /// fn main() {
    ///     assert!(EnumMap::<Void, ()>::new().is_empty());
    ///     assert!(!EnumMap::<SingleVariant, ()>::new().is_empty());
    /// }
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Swaps two indexes.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { false => 0, true => 1 };
    ///     map.swap(false, true);
    ///     assert_eq!(map[false], 1);
    ///     assert_eq!(map[true], 0);
    /// }
    /// ```
    pub fn swap(&mut self, a: K, b: K) {
        self.as_mut_slice().swap(a.to_usize(), b.to_usize())
    }

    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> slice::Iter<V> {
        self.as_slice().iter()
    }

    /// Converts an enum map to a slice representing values.
    pub fn as_slice(&self) -> &[V] {
        K::slice(&self.array)
    }

    /// Converts a mutable enum map to a mutable slice representing values.
    pub fn as_mut_slice(&mut self) -> &mut [V] {
        K::slice_mut(&mut self.array)
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> slice::IterMut<V> {
        self.as_mut_slice().iter_mut()
    }

    /// Returns a raw pointer to the enum map's buffer.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// Modifying the container referenced by this slice may cause its buffer
    /// to be reallocated, which would also make any pointers to it invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let map = enum_map! { 5 => 42, _ => 0 };
    ///     assert_eq!(unsafe { *map.as_ptr().offset(5) }, 42);
    /// }
    /// ```
    pub fn as_ptr(&self) -> *const V {
        self.as_slice().as_ptr()
    }

    /// Returns an unsafe mutable pointer to the enum map's buffer.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// Modifying the container referenced by this slice may cause its buffer
    /// to be reallocated, which would also make any pointers to it invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 0 };
    ///     unsafe {
    ///         *map.as_mut_ptr().offset(11) = 23
    ///     };
    ///     assert_eq!(map[11], 23);
    /// }
    /// ```
    pub fn as_mut_ptr(&mut self) -> *mut V {
        self.as_mut_slice().as_mut_ptr()
    }
}

impl<F: FnMut(K) -> V, K: Internal<V>, V> From<F> for EnumMap<K, V> {
    fn from(f: F) -> Self {
        EnumMap { array: K::from_function(f) }
    }
}
<commit_msg>Remove K::Array: Default bound from EnumMap::new<commit_after>//! An enum mapping type.
//!
//! It is implemented using an array type, so using it is as fast as using Rust
//! arrays.
//!
//! # Examples
//!
//! ```
//! #[macro_use]
//! extern crate enum_map;
//!
//! use enum_map::EnumMap;
//!
//! #[derive(Debug, EnumMap)]
//! enum Example {
//!     A,
//!     B,
//!     C,
//! }
//!
//! fn main() {
//!     let mut map = enum_map! {
//!         Example::A => 1,
//!         Example::B => 2,
//!         Example::C => 3,
//!     };
//!     map[Example::C] = 4;
//!
//!     assert_eq!(map[Example::A], 1);
//!
//!     for (key, &value) in &map {
//!         println!("{:?} has {} as value.", key, value);
//!     }
//! }
//! ```

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

#[macro_use]
extern crate array_macro;
// This allows to quiet "proc macro crates and `#[no_link]` crates have no
// effect without `#[macro_use]`" warning. Just using extern DOES have
// an effect of letting me export the macro.
#[allow(unused_imports)]
#[macro_use]
extern crate enum_map_derive;

/// Enum map constructor.
///
/// This macro allows to create a new enum map in a type safe way. It takes
/// a list of `,` separated pairs separated by `=>`. Left side is `|`
/// separated list of enum keys, or `_` to match all unmatched enum keys,
/// while right side is a value.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
///     D,
/// }
///
/// fn main() {
///     let enum_map = enum_map! {
///         Example::A | Example::B => 1,
///         Example::C => 2,
///         _ => 3,
///     };
///     assert_eq!(enum_map[Example::A], 1);
///     assert_eq!(enum_map[Example::B], 1);
///     assert_eq!(enum_map[Example::C], 2);
///     assert_eq!(enum_map[Example::D], 3);
/// }
/// ```
#[macro_export]
macro_rules! enum_map {
    {$($t:tt)*} => {
        $crate::EnumMap::from(|k| match k { $($t)* })
    };
}

mod enummap_impls;
mod internal;
mod iter;
mod serde;

pub use internal::Internal;
pub use iter::{Iter, IterMut};
// `*` here means re-exporting a derive procedural macro.
pub use enum_map_derive::*;

use core::slice;

/// An enum mapping.
///
/// This internally uses an array which stores a value for each possible
/// enum value. To work, it requires implementation of internal (private,
/// although public due to macro limitations) trait which allows extracting
/// information about an enum, which can be automatically generated using
/// `#[derive(EnumMap)]` from `enum_map_derive` crate.
///
/// Additionally, `bool` and `u8` automatically derives from `EnumMap`. While
/// `u8` is not technically an enum, it's convenient to consider it like one.
/// In particular, [reverse-complement in benchmark game] could be using `u8`
/// as an enum.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// use enum_map::EnumMap;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = EnumMap::new();
///     // new initializes map with default values
///     assert_eq!(map[Example::A], 0);
///     map[Example::A] = 3;
///     assert_eq!(map[Example::A], 3);
/// }
/// ```
///
/// [reverse-complement in benchmark game]:
///     http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=rust&id=2
#[derive(Debug)]
pub struct EnumMap<K: Internal<V>, V> {
    array: K::Array,
}

impl<K: Internal<V>, V: Default> EnumMap<K, V> {
    /// Creates an enum map with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// #[derive(EnumMap)]
    /// enum Example {
    ///     A,
    /// }
    ///
    /// fn main() {
    ///     let enum_map = EnumMap::<_, i32>::new();
    ///     assert_eq!(enum_map[Example::A], 0);
    /// }
    /// ```
    pub fn new() -> Self {
        enum_map! { _ => V::default() }
    }
}

impl<K: Internal<V>, V> EnumMap<K, V> {
    /// Returns an iterator over enum map.
    pub fn iter(&self) -> Iter<K, V> {
        self.into_iter()
    }

    /// Returns a mutable iterator over enum map.
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        self.into_iter()
    }

    /// Returns number of elements in enum map.
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }

    /// Returns whether the enum variant set is empty.
    ///
    /// This isn't particularly useful, as there is no real reason to use
    /// enum map for enums without variants. However, it is provided for
    /// consistency with data structures providing len method (and I will
    /// admit, to avoid clippy warnings).
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// #[derive(EnumMap)]
    /// enum Void {}
    ///
    /// #[derive(EnumMap)]
    /// enum SingleVariant {
    ///     Variant,
    /// }
    ///
    /// fn main() {
    ///     assert!(EnumMap::<Void, ()>::new().is_empty());
    ///     assert!(!EnumMap::<SingleVariant, ()>::new().is_empty());
    /// }
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Swaps two indexes.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { false => 0, true => 1 };
    ///     map.swap(false, true);
    ///     assert_eq!(map[false], 1);
    ///     assert_eq!(map[true], 0);
    /// }
    /// ```
    pub fn swap(&mut self, a: K, b: K) {
        self.as_mut_slice().swap(a.to_usize(), b.to_usize())
    }

    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> slice::Iter<V> {
        self.as_slice().iter()
    }

    /// Converts an enum map to a slice representing values.
    pub fn as_slice(&self) -> &[V] {
        K::slice(&self.array)
    }

    /// Converts a mutable enum map to a mutable slice representing values.
    pub fn as_mut_slice(&mut self) -> &mut [V] {
        K::slice_mut(&mut self.array)
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> slice::IterMut<V> {
        self.as_mut_slice().iter_mut()
    }

    /// Returns a raw pointer to the enum map's buffer.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// Modifying the container referenced by this slice may cause its buffer
    /// to be reallocated, which would also make any pointers to it invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let map = enum_map! { 5 => 42, _ => 0 };
    ///     assert_eq!(unsafe { *map.as_ptr().offset(5) }, 42);
    /// }
    /// ```
    pub fn as_ptr(&self) -> *const V {
        self.as_slice().as_ptr()
    }

    /// Returns an unsafe mutable pointer to the enum map's buffer.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// Modifying the container referenced by this slice may cause its buffer
    /// to be reallocated, which would also make any pointers to it invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 0 };
    ///     unsafe {
    ///         *map.as_mut_ptr().offset(11) = 23
    ///     };
    ///     assert_eq!(map[11], 23);
    /// }
    /// ```
    pub fn as_mut_ptr(&mut self) -> *mut V {
        self.as_mut_slice().as_mut_ptr()
    }
}

impl<F: FnMut(K) -> V, K: Internal<V>, V> From<F> for EnumMap<K, V> {
    fn from(f: F) -> Self {
        EnumMap { array: K::from_function(f) }
    }
}
<|endoftext|>


<commit_before>
use std::fs;
use std::path::{Path, PathBuf};
use std::io;
use std::char::from_u32;
use std::io::Write;
use std::process::{Command, Stdio, ExitStatus};
use std::ffi::{OsStr, OsString};
use hyper::{self, Client};
use openssl::crypto::hash::Hasher;

use rand::random;

pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> {
	if !is_directory(path.as_ref()) {
		callback(path.as_ref());
		fs::create_dir_all(path.as_ref()).map(|()| true)
	} else {
		Ok(false)
	}
}

pub fn is_directory<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_dir) == Some(true)
}

pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_file) == Some(true)
}

pub fn path_exists<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).is_ok()
}

pub fn random_string(length: usize) -> String {
	let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
	(0..length).map(|_| from_u32(chars[random::<usize>() % chars.len()] as u32).unwrap()).collect()
}

pub fn if_not_empty<S: PartialEq<str>>(s: S) -> Option<S> {
	if s == *"" {
		None
	} else {
		Some(s)
	}
}

pub fn write_file(path: &Path, contents: &str) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.write(true)
		.truncate(true)
		.create(true)
		.open(path));

	try!(io::Write::write_all(&mut file, contents.as_bytes()));

	try!(file.sync_data());

	Ok(())
}

pub fn read_file(path: &Path) -> io::Result<String> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let mut contents = String::new();

	try!(io::Read::read_to_string(&mut file, &mut contents));

	Ok(contents)
}

pub fn filter_file<F: FnMut(&str) -> bool>(src: &Path, dest: &Path, mut filter: F) -> io::Result<usize> {
	let src_file = try!(fs::File::open(src));
	let dest_file = try!(fs::File::create(dest));

	let mut reader = io::BufReader::new(src_file);
	let mut writer = io::BufWriter::new(dest_file);
	let mut removed = 0;

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if filter(&line) {
			try!(writeln!(&mut writer, "{}", &line));
		} else {
			removed += 1;
		}
	}

	try!(writer.flush());

	Ok(removed)
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(src: &Path, mut f: F) -> io::Result<Option<T>> {
	let src_file = try!(fs::File::open(src));

	let mut reader = io::BufReader::new(src_file);

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if let Some(r) = f(&line) {
			return Ok(Some(r));
		}
	}

	Ok(None)
}

pub fn append_file(dest: &Path, line: &str) -> io::Result<()> {
	let mut dest_file = try!(fs::OpenOptions::new()
		.write(true)
		.append(true)
		.create(true)
		.open(dest)
		);

	try!(writeln!(&mut dest_file, "{}", line));

	try!(dest_file.sync_data());

	Ok(())
}

pub fn tee_file<W: io::Write>(path: &Path, mut w: &mut W) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	loop {
		let bytes_read = try!(io::Read::read(&mut file, &mut buffer));

		if bytes_read != 0 {
			try!(io::Write::write_all(w, &mut buffer[0..bytes_read]));
		} else {
			return Ok(());
		}
	}
}

#[derive(Debug)]
pub enum DownloadError {
	Status(hyper::status::StatusCode),
	Network(hyper::Error),
	File(io::Error),
}
pub type DownloadResult<T> = Result<T, DownloadError>;

pub fn download_file<P: AsRef<Path>>(url: hyper::Url, path: P, mut hasher: Option<&mut Hasher>) -> DownloadResult<()> {
	let client = Client::new();

	let mut res = try!(client.get(url).send().map_err(DownloadError::Network));
	if res.status != hyper::Ok { return Err(DownloadError::Status(res.status)); }

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	let mut file = try!(fs::File::create(path).map_err(DownloadError::File));

	loop {
		let bytes_read = try!(io::Read::read(&mut res, &mut buffer)
			.map_err(hyper::Error::Io)
			.map_err(DownloadError::Network)
			);

		if bytes_read != 0 {
			if let Some(ref mut h) = hasher {
				try!(io::Write::write_all(*h, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
			}
			try!(io::Write::write_all(&mut file, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
		} else {
			try!(file.sync_data().map_err(DownloadError::File));
			return Ok(());
		}
	}
}

pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_dir(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = remove_dir(dest);
	symlink_dir_inner(src, dest)
}

pub fn symlink_file(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_file(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_file(dest);
	symlink_file_inner(src, dest)
}

pub fn hardlink(src: &Path, dest: &Path) -> io::Result<()> {
	let _ = fs::remove_file(dest);
	fs::hard_link(src, dest)
}

#[derive(Debug)]
pub enum CommandError {
	Io(io::Error),
	Status(ExitStatus),
}

pub type CommandResult<T> = Result<T, CommandError>;

pub fn cmd_status(cmd: &mut Command) -> CommandResult<()> {
	cmd.status().map_err(CommandError::Io).and_then(|s| {
		if s.success() {
			Ok(())
		} else {
			Err(CommandError::Status(s))
		}
	})
}

pub fn remove_dir(path: &Path) -> io::Result<()> {
	if try!(fs::metadata(path)).file_type().is_symlink() {
		if cfg!(windows) {
			fs::remove_dir(path)
		} else {
			fs::remove_file(path)
		}
	} else {
		fs::remove_dir_all(path)
	}
}

pub fn copy_dir(src: &Path, dest: &Path) -> CommandResult<()> {
	#[cfg(windows)]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("robocopy").arg(src).arg(dest).arg("/E"))
	}
	#[cfg(not(windows))]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("cp").arg("-R").arg(src).arg(dest))
	}

	let _ = remove_dir(dest);
	copy_dir_inner(src, dest)
}

pub fn prefix_arg<S: AsRef<OsStr>>(name: &str, s: S) -> OsString {
	let mut arg = OsString::from(name);
	arg.push(s);
	arg
}

pub fn open_browser(path: &Path) -> io::Result<bool> {
	#[cfg(not(windows))]
	fn has_cmd(cmd: &&str) -> bool {
		cmd_status(Command::new("which")
			.arg(cmd)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())).is_ok()
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> io::Result<bool> {
		let commands = ["xdg-open", "open", "firefox", "chromium"];
		if let Some(cmd) = commands.iter().map(|s| *s).filter(has_cmd).next() {
			Command::new(cmd)
				.arg(path)
				.stdin(Stdio::null())
				.stdout(Stdio::null())
				.stderr(Stdio::null())
				.spawn()
				.map(|_| true)
		} else {
			Ok(false)
		}
	}
	#[cfg(windows)]
	fn inner(path: &Path) -> io::Result<bool> {
		Command::new("cmd")
			.arg("/C")
			.arg("start")
			.arg(path)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())
			.spawn()
			.map(|_| true)
	}
	inner(path)
}
pub fn home_dir() -> Option<PathBuf> {
	#[cfg(not(windows))]
	fn inner() -> Option<PathBuf> {
		::std::env::home_dir()
	}
	#[cfg(windows)]
	fn inner() -> Option<PathBuf> {
		windows::get_special_folder(&windows::FOLDERID_Profile).ok()
	}

	inner()
}

#[cfg(windows)]
pub mod windows {
	use winapi::*;
	use std::io;
	use std::path::PathBuf;
	use std::ptr;
	use std::slice;
	use std::ffi::OsString;
	use std::os::windows::ffi::OsStringExt;
	use shell32;
	use ole32;

	#[allow(non_upper_case_globals)]
	pub const FOLDERID_LocalAppData: GUID = GUID {
		Data1: 0xF1B32785,
		Data2: 0x6FBA,
		Data3: 0x4FCF,
		Data4: [0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91],
	};
	#[allow(non_upper_case_globals)]
	pub const FOLDERID_Profile: GUID = GUID {
		Data1: 0x5E6C858F,
		Data2: 0x0E22,
		Data3: 0x4760,
		Data4: [0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73],
	};

	pub fn get_special_folder(id: &shtypes::KNOWNFOLDERID) -> io::Result<PathBuf> {

		let mut path = ptr::null_mut();
		let result;

		unsafe {
			let code = shell32::SHGetKnownFolderPath(id, 0, ptr::null_mut(), &mut path);
			if code == 0 {
				let mut length = 0usize;
				while *path.offset(length as isize) != 0 {
					length += 1;
				}
				let slice = slice::from_raw_parts(path, length);
				result = Ok(OsString::from_wide(slice).into());
			} else {
				result = Err(io::Error::from_raw_os_error(code));
			}
			ole32::CoTaskMemFree(path as *mut _);
		}
		result
	}
}
<commit_msg>is_symlink is broken, so work-around it<commit_after>
use std::fs;
use std::path::{Path, PathBuf};
use std::io;
use std::char::from_u32;
use std::io::Write;
use std::process::{Command, Stdio, ExitStatus};
use std::ffi::{OsStr, OsString};
use hyper::{self, Client};
use openssl::crypto::hash::Hasher;

use rand::random;

pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> {
	if !is_directory(path.as_ref()) {
		callback(path.as_ref());
		fs::create_dir_all(path.as_ref()).map(|()| true)
	} else {
		Ok(false)
	}
}

pub fn is_directory<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_dir) == Some(true)
}

pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_file) == Some(true)
}

pub fn path_exists<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).is_ok()
}

pub fn random_string(length: usize) -> String {
	let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
	(0..length).map(|_| from_u32(chars[random::<usize>() % chars.len()] as u32).unwrap()).collect()
}

pub fn if_not_empty<S: PartialEq<str>>(s: S) -> Option<S> {
	if s == *"" {
		None
	} else {
		Some(s)
	}
}

pub fn write_file(path: &Path, contents: &str) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.write(true)
		.truncate(true)
		.create(true)
		.open(path));

	try!(io::Write::write_all(&mut file, contents.as_bytes()));

	try!(file.sync_data());

	Ok(())
}

pub fn read_file(path: &Path) -> io::Result<String> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let mut contents = String::new();

	try!(io::Read::read_to_string(&mut file, &mut contents));

	Ok(contents)
}

pub fn filter_file<F: FnMut(&str) -> bool>(src: &Path, dest: &Path, mut filter: F) -> io::Result<usize> {
	let src_file = try!(fs::File::open(src));
	let dest_file = try!(fs::File::create(dest));

	let mut reader = io::BufReader::new(src_file);
	let mut writer = io::BufWriter::new(dest_file);
	let mut removed = 0;

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if filter(&line) {
			try!(writeln!(&mut writer, "{}", &line));
		} else {
			removed += 1;
		}
	}

	try!(writer.flush());

	Ok(removed)
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(src: &Path, mut f: F) -> io::Result<Option<T>> {
	let src_file = try!(fs::File::open(src));

	let mut reader = io::BufReader::new(src_file);

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if let Some(r) = f(&line) {
			return Ok(Some(r));
		}
	}

	Ok(None)
}

pub fn append_file(dest: &Path, line: &str) -> io::Result<()> {
	let mut dest_file = try!(fs::OpenOptions::new()
		.write(true)
		.append(true)
		.create(true)
		.open(dest)
		);

	try!(writeln!(&mut dest_file, "{}", line));

	try!(dest_file.sync_data());

	Ok(())
}

pub fn tee_file<W: io::Write>(path: &Path, mut w: &mut W) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	loop {
		let bytes_read = try!(io::Read::read(&mut file, &mut buffer));

		if bytes_read != 0 {
			try!(io::Write::write_all(w, &mut buffer[0..bytes_read]));
		} else {
			return Ok(());
		}
	}
}

#[derive(Debug)]
pub enum DownloadError {
	Status(hyper::status::StatusCode),
	Network(hyper::Error),
	File(io::Error),
}
pub type DownloadResult<T> = Result<T, DownloadError>;

pub fn download_file<P: AsRef<Path>>(url: hyper::Url, path: P, mut hasher: Option<&mut Hasher>) -> DownloadResult<()> {
	let client = Client::new();

	let mut res = try!(client.get(url).send().map_err(DownloadError::Network));
	if res.status != hyper::Ok { return Err(DownloadError::Status(res.status)); }

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	let mut file = try!(fs::File::create(path).map_err(DownloadError::File));

	loop {
		let bytes_read = try!(io::Read::read(&mut res, &mut buffer)
			.map_err(hyper::Error::Io)
			.map_err(DownloadError::Network)
			);

		if bytes_read != 0 {
			if let Some(ref mut h) = hasher {
				try!(io::Write::write_all(*h, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
			}
			try!(io::Write::write_all(&mut file, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
		} else {
			try!(file.sync_data().map_err(DownloadError::File));
			return Ok(());
		}
	}
}

pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_dir(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = remove_dir(dest);
	symlink_dir_inner(src, dest)
}

pub fn symlink_file(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_file(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_file(dest);
	symlink_file_inner(src, dest)
}

pub fn hardlink(src: &Path, dest: &Path) -> io::Result<()> {
	let _ = fs::remove_file(dest);
	fs::hard_link(src, dest)
}

#[derive(Debug)]
pub enum CommandError {
	Io(io::Error),
	Status(ExitStatus),
}

pub type CommandResult<T> = Result<T, CommandError>;

pub fn cmd_status(cmd: &mut Command) -> CommandResult<()> {
	cmd.status().map_err(CommandError::Io).and_then(|s| {
		if s.success() {
			Ok(())
		} else {
			Err(CommandError::Status(s))
		}
	})
}

pub fn remove_dir(path: &Path) -> io::Result<()> {
	// is_symlink is broken, so just try treating it as a symlink first
	if let Err(_) = if cfg!(windows) {
		fs::remove_dir(path)
	} else {
		fs::remove_file(path)
	} {
		fs::remove_dir_all(path)
	} else {
		Ok(())
	}
}

pub fn copy_dir(src: &Path, dest: &Path) -> CommandResult<()> {
	#[cfg(windows)]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("robocopy").arg(src).arg(dest).arg("/E"))
	}
	#[cfg(not(windows))]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("cp").arg("-R").arg(src).arg(dest))
	}

	let _ = remove_dir(dest);
	copy_dir_inner(src, dest)
}

pub fn prefix_arg<S: AsRef<OsStr>>(name: &str, s: S) -> OsString {
	let mut arg = OsString::from(name);
	arg.push(s);
	arg
}

pub fn open_browser(path: &Path) -> io::Result<bool> {
	#[cfg(not(windows))]
	fn has_cmd(cmd: &&str) -> bool {
		cmd_status(Command::new("which")
			.arg(cmd)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())).is_ok()
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> io::Result<bool> {
		let commands = ["xdg-open", "open", "firefox", "chromium"];
		if let Some(cmd) = commands.iter().map(|s| *s).filter(has_cmd).next() {
			Command::new(cmd)
				.arg(path)
				.stdin(Stdio::null())
				.stdout(Stdio::null())
				.stderr(Stdio::null())
				.spawn()
				.map(|_| true)
		} else {
			Ok(false)
		}
	}
	#[cfg(windows)]
	fn inner(path: &Path) -> io::Result<bool> {
		Command::new("cmd")
			.arg("/C")
			.arg("start")
			.arg(path)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())
			.spawn()
			.map(|_| true)
	}
	inner(path)
}
pub fn home_dir() -> Option<PathBuf> {
	#[cfg(not(windows))]
	fn inner() -> Option<PathBuf> {
		::std::env::home_dir()
	}
	#[cfg(windows)]
	fn inner() -> Option<PathBuf> {
		windows::get_special_folder(&windows::FOLDERID_Profile).ok()
	}

	inner()
}

#[cfg(windows)]
pub mod windows {
	use winapi::*;
	use std::io;
	use std::path::PathBuf;
	use std::ptr;
	use std::slice;
	use std::ffi::OsString;
	use std::os::windows::ffi::OsStringExt;
	use shell32;
	use ole32;

	#[allow(non_upper_case_globals)]
	pub const FOLDERID_LocalAppData: GUID = GUID {
		Data1: 0xF1B32785,
		Data2: 0x6FBA,
		Data3: 0x4FCF,
		Data4: [0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91],
	};
	#[allow(non_upper_case_globals)]
	pub const FOLDERID_Profile: GUID = GUID {
		Data1: 0x5E6C858F,
		Data2: 0x0E22,
		Data3: 0x4760,
		Data4: [0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73],
	};

	pub fn get_special_folder(id: &shtypes::KNOWNFOLDERID) -> io::Result<PathBuf> {

		let mut path = ptr::null_mut();
		let result;

		unsafe {
			let code = shell32::SHGetKnownFolderPath(id, 0, ptr::null_mut(), &mut path);
			if code == 0 {
				let mut length = 0usize;
				while *path.offset(length as isize) != 0 {
					length += 1;
				}
				let slice = slice::from_raw_parts(path, length);
				result = Ok(OsString::from_wide(slice).into());
			} else {
				result = Err(io::Error::from_raw_os_error(code));
			}
			ole32::CoTaskMemFree(path as *mut _);
		}
		result
	}
}
<|endoftext|>


<commit_before>use std::sync::atomic::{AtomicU32, Ordering};

/// Simple atomic floating point variable with relaxed ordering.
///
/// Designed for the common case of sharing VST parameters between
/// multiple threads when no synchronization or change notification
/// is needed.
pub struct AtomicFloat {
    atomic: AtomicU32,
}

impl AtomicFloat {
    /// New atomic float with initial value `value`.
    pub fn new(value: f32) -> AtomicFloat {
        AtomicFloat {
            atomic: AtomicU32::new(value.to_bits()),
        }
    }

    /// Get the current value of the atomic float.
    pub fn get(&self) -> f32 {
        f32::from_bits(self.atomic.load(Ordering::Relaxed))
    }

    /// Set the value of the atomic float to `value`.
    pub fn set(&self, value: f32) {
        self.atomic.store(value.to_bits(), Ordering::Relaxed)
    }
}

impl Default for AtomicFloat {
    fn default() -> Self {
        AtomicFloat::new(0.0)
    }
}
<commit_msg>Implement Debug/Display and Into/From<f32> for AtomicFloat (#150)<commit_after>use std::sync::atomic::{AtomicU32, Ordering};

/// Simple atomic floating point variable with relaxed ordering.
///
/// Designed for the common case of sharing VST parameters between
/// multiple threads when no synchronization or change notification
/// is needed.
pub struct AtomicFloat {
    atomic: AtomicU32,
}

impl AtomicFloat {
    /// New atomic float with initial value `value`.
    pub fn new(value: f32) -> AtomicFloat {
        AtomicFloat {
            atomic: AtomicU32::new(value.to_bits()),
        }
    }

    /// Get the current value of the atomic float.
    pub fn get(&self) -> f32 {
        f32::from_bits(self.atomic.load(Ordering::Relaxed))
    }

    /// Set the value of the atomic float to `value`.
    pub fn set(&self, value: f32) {
        self.atomic.store(value.to_bits(), Ordering::Relaxed)
    }
}

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

impl std::fmt::Debug for AtomicFloat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.get(), f)
    }
}

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

impl From<f32> for AtomicFloat {
    fn from(value: f32) -> Self {
        AtomicFloat::new(value)
    }
}

impl From<AtomicFloat> for f32 {
    fn from(value: AtomicFloat) -> Self {
        value.get()
    }
}
<|endoftext|>


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

/// General actor system infrastructure.

use std::any::{Any, AnyRefExt, AnyMutRefExt};
use std::collections::hashmap::HashMap;
use std::cell::{Cell, RefCell};
use std::io::TcpStream;
use std::mem::{transmute, transmute_copy, replace};
use std::raw::TraitObject;
use serialize::json;

/// A common trait for all devtools actors that encompasses an immutable name
/// and the ability to process messages that are directed to particular actors.
/// TODO: ensure the name is immutable
pub trait Actor: Any {
    fn handle_message(&self,
                      registry: &ActorRegistry,
                      msg_type: &String,
                      msg: &json::JsonObject,
                      stream: &mut TcpStream) -> bool;
    fn name(&self) -> String;
}

impl<'a> AnyMutRefExt<'a> for &'a mut Actor + 'a {
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

impl<'a> AnyRefExt<'a> for &'a Actor + 'a {
    fn is<T: 'static>(self) -> bool {
        //FIXME: This implementation is bogus since get_type_id is private now.
        //       However, this implementation is only needed so long as there's a Rust bug
        //       that prevents downcast_ref from giving realistic return values, and this is
        //       ok since we're careful with the types we pull out of the hashmap.
        /*let t = TypeId::of::<T>();
        let boxed = self.get_type_id();
        t == boxed*/
        true
    }

    fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

/// A list of known, owned actors.
pub struct ActorRegistry {
    actors: HashMap<String, Box<Actor+Send+Sized>>,
    new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>,
    script_actors: RefCell<HashMap<String, String>>,
    next: Cell<u32>,
}

impl ActorRegistry {
    /// Create an empty registry.
    pub fn new() -> ActorRegistry {
        ActorRegistry {
            actors: HashMap::new(),
            new_actors: RefCell::new(vec!()),
            script_actors: RefCell::new(HashMap::new()),
            next: Cell::new(0),
        }
    }

    pub fn register_script_actor(&self, script_id: String, actor: String) {
        println!("registering {:s} ({:s})", actor.as_slice(), script_id.as_slice());
        let mut script_actors = self.script_actors.borrow_mut();
        script_actors.insert(script_id, actor);
    }

    pub fn script_to_actor(&self, script_id: String) -> String {
        if script_id.as_slice() == "" {
            return "".to_string();
        }
        self.script_actors.borrow().find(&script_id).unwrap().to_string()
    }

    pub fn script_actor_registered(&self, script_id: String) -> bool {
        self.script_actors.borrow().contains_key(&script_id)
    }

    pub fn actor_to_script(&self, actor: String) -> String {
        for (key, value) in self.script_actors.borrow().iter() {
            println!("checking {:s}", value.as_slice());
            if value.as_slice() == actor.as_slice() {
                return key.to_string();
            }
        }
        fail!("couldn't find actor named {:s}", actor)
    }

    /// Create a unique name based on a monotonically increasing suffix
    pub fn new_name(&self, prefix: &str) -> String {
        let suffix = self.next.get();
        self.next.set(suffix + 1);
        format!("{:s}{:u}", prefix, suffix)
    }

    /// Add an actor to the registry of known actors that can receive messages.
    pub fn register(&mut self, actor: Box<Actor+Send+Sized>) {
        self.actors.insert(actor.name().to_string(), actor);
    }

    pub fn register_later(&self, actor: Box<Actor+Send+Sized>) {
        let mut actors = self.new_actors.borrow_mut();
        actors.push(actor);
    }

    /// Find an actor by registered name
    pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
        //       fails for unknown reasons.
        /*let actor: &Actor+Send+Sized = *self.actors.find(&name.to_string()).unwrap();
        (actor as &Any).downcast_ref::<T>().unwrap()*/
        self.actors.find(&name.to_string()).unwrap().downcast_ref::<T>().unwrap()
    }

    /// Find an actor by registered name
    pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T {
        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
        //       fails for unknown reasons.
        /*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap();
        (actor as &mut Any).downcast_mut::<T>().unwrap()*/
        self.actors.find_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap()
    }

    /// Attempt to process a message as directed by its `to` property. If the actor is not
    /// found or does not indicate that it knew how to process the message, ignore the failure.
    pub fn handle_message(&mut self, msg: &json::JsonObject, stream: &mut TcpStream) {
        let to = msg.find(&"to".to_string()).unwrap().as_string().unwrap();
        match self.actors.find(&to.to_string()) {
            None => println!("message received for unknown actor \"{:s}\"", to),
            Some(actor) => {
                let msg_type = msg.find(&"type".to_string()).unwrap().as_string().unwrap();
                if !actor.handle_message(self, &msg_type.to_string(), msg, stream) {
                    println!("unexpected message type \"{:s}\" found for actor \"{:s}\"",
                             msg_type, to);
                }
            }
        }
        let new_actors = replace(&mut *self.new_actors.borrow_mut(), vec!());
        for actor in new_actors.into_iter() {
            self.actors.insert(actor.name().to_string(), actor);
        }
    }
}
<commit_msg>Use std::intrinsics::TypeId<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/// General actor system infrastructure.

use std::any::{AnyPrivate, AnyRefExt, AnyMutRefExt};
use std::collections::hashmap::HashMap;
use std::cell::{Cell, RefCell};
use std::intrinsics::TypeId;
use std::io::TcpStream;
use std::mem::{transmute, transmute_copy, replace};
use std::raw::TraitObject;
use serialize::json;

/// A common trait for all devtools actors that encompasses an immutable name
/// and the ability to process messages that are directed to particular actors.
/// TODO: ensure the name is immutable
pub trait Actor: AnyPrivate {
    fn handle_message(&self,
                      registry: &ActorRegistry,
                      msg_type: &String,
                      msg: &json::JsonObject,
                      stream: &mut TcpStream) -> bool;
    fn name(&self) -> String;
}

impl<'a> AnyMutRefExt<'a> for &'a mut Actor + 'a {
    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

impl<'a> AnyRefExt<'a> for &'a Actor + 'a {
    fn is<T: 'static>(self) -> bool {
        // This implementation is only needed so long as there's a Rust bug that
        // prevents downcast_ref from giving realistic return values.
        let t = TypeId::of::<T>();
        let boxed = self.get_type_id();
        t == boxed
    }

    fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute_copy(&self);

                // Extract the data pointer
                Some(transmute(to.data))
            }
        } else {
            None
        }
    }
}

/// A list of known, owned actors.
pub struct ActorRegistry {
    actors: HashMap<String, Box<Actor+Send+Sized>>,
    new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>,
    script_actors: RefCell<HashMap<String, String>>,
    next: Cell<u32>,
}

impl ActorRegistry {
    /// Create an empty registry.
    pub fn new() -> ActorRegistry {
        ActorRegistry {
            actors: HashMap::new(),
            new_actors: RefCell::new(vec!()),
            script_actors: RefCell::new(HashMap::new()),
            next: Cell::new(0),
        }
    }

    pub fn register_script_actor(&self, script_id: String, actor: String) {
        println!("registering {:s} ({:s})", actor.as_slice(), script_id.as_slice());
        let mut script_actors = self.script_actors.borrow_mut();
        script_actors.insert(script_id, actor);
    }

    pub fn script_to_actor(&self, script_id: String) -> String {
        if script_id.as_slice() == "" {
            return "".to_string();
        }
        self.script_actors.borrow().find(&script_id).unwrap().to_string()
    }

    pub fn script_actor_registered(&self, script_id: String) -> bool {
        self.script_actors.borrow().contains_key(&script_id)
    }

    pub fn actor_to_script(&self, actor: String) -> String {
        for (key, value) in self.script_actors.borrow().iter() {
            println!("checking {:s}", value.as_slice());
            if value.as_slice() == actor.as_slice() {
                return key.to_string();
            }
        }
        fail!("couldn't find actor named {:s}", actor)
    }

    /// Create a unique name based on a monotonically increasing suffix
    pub fn new_name(&self, prefix: &str) -> String {
        let suffix = self.next.get();
        self.next.set(suffix + 1);
        format!("{:s}{:u}", prefix, suffix)
    }

    /// Add an actor to the registry of known actors that can receive messages.
    pub fn register(&mut self, actor: Box<Actor+Send+Sized>) {
        self.actors.insert(actor.name().to_string(), actor);
    }

    pub fn register_later(&self, actor: Box<Actor+Send+Sized>) {
        let mut actors = self.new_actors.borrow_mut();
        actors.push(actor);
    }

    /// Find an actor by registered name
    pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
        //       fails for unknown reasons.
        /*let actor: &Actor+Send+Sized = *self.actors.find(&name.to_string()).unwrap();
        (actor as &Any).downcast_ref::<T>().unwrap()*/
        self.actors.find(&name.to_string()).unwrap().downcast_ref::<T>().unwrap()
    }

    /// Find an actor by registered name
    pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T {
        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
        //       fails for unknown reasons.
        /*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap();
        (actor as &mut Any).downcast_mut::<T>().unwrap()*/
        self.actors.find_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap()
    }

    /// Attempt to process a message as directed by its `to` property. If the actor is not
    /// found or does not indicate that it knew how to process the message, ignore the failure.
    pub fn handle_message(&mut self, msg: &json::JsonObject, stream: &mut TcpStream) {
        let to = msg.find(&"to".to_string()).unwrap().as_string().unwrap();
        match self.actors.find(&to.to_string()) {
            None => println!("message received for unknown actor \"{:s}\"", to),
            Some(actor) => {
                let msg_type = msg.find(&"type".to_string()).unwrap().as_string().unwrap();
                if !actor.handle_message(self, &msg_type.to_string(), msg, stream) {
                    println!("unexpected message type \"{:s}\" found for actor \"{:s}\"",
                             msg_type, to);
                }
            }
        }
        let new_actors = replace(&mut *self.new_actors.borrow_mut(), vec!());
        for actor in new_actors.into_iter() {
            self.actors.insert(actor.name().to_string(), actor);
        }
    }
}
<|endoftext|>


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

use hcore::crypto::SymKey;

use error::Result;

pub fn send_rumors_to_peers(peer_listeners: &Vec<String>,
                            ring_key: Option<&SymKey>,
                            rumor_list: &hab_gossip::RumorList)
                            -> Result<()> {
    let fail_after = 10;
    let mut count = 0;

    if peer_listeners.len() > 0 {
        while count < fail_after {
            if try_peers(peer_listeners, ring_key, rumor_list) {
                return Ok(());
            } else {
                count = count + 1;
                println!("Could not connect to any initial peers; attempt {} of {}.",
                         count,
                         fail_after);
            }
        }
    }
    Ok(())
}

fn try_peers(peer_listeners: &Vec<String>,
             ring_key: Option<&SymKey>,
             rumor_list: &hab_gossip::RumorList)
             -> bool {
    let mut initialized = false;
    for to in peer_listeners {
        println!("Joining peer: {}", to);
        let mut c = match hab_gossip::Client::new(&to[..], ring_key.clone()) {
            Ok(c) => c,
            Err(e) => {
                debug!("Error creating gossip client - {:?}", e);
                println!("Failed to create a gossip client for {}", to);
                continue;
            }
        };

        match c.inject(rumor_list.clone()) {
            Ok(_) => println!("Configuration applied to: {}", to),
            Err(e) => {
                println!("Failed to ping {:?}: {:?}", to, e);
                continue;
            }
        }
        initialized = true;
    }
    initialized
}

pub mod hab_gossip {
    //! **Note** that this is a temporary measure. In order to implement the `rumor inject`
    //! subcommand in a codebase independent of the Supervisor, it was quickest to copy a minimal
    //! implementation of the Gossip subsystem suitable enough to "blind inject" a particular
    //! message type and terminate.  The Supervisor Gossip code needs some further refactoring for
    //! generic and minimal reuse. Until then, enjoy Fletcher's minimal Gossip port - FIN

    use std::collections::HashMap;
    use std::error;
    use std::fmt;
    use std::net::ToSocketAddrs;
    use std::io;
    use std::result;

    use common;
    use common::gossip_file::GossipFile;
    use common::wire_message::WireMessage;
    use hcore::crypto::SymKey;
    use rustc_serialize::json;
    use utp::UtpSocket;
    use uuid::Uuid;

    /// The default port for the Gossip protocol
    pub static GOSSIP_DEFAULT_PORT: usize = 9634;

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

    #[derive(Debug)]
    pub enum Error {
        HabitatCommon(common::Error),
        IO(io::Error),
        JsonEncode(json::EncoderError),
    }

    impl fmt::Display for Error {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let msg = match *self {
                Error::HabitatCommon(ref e) => format!("{}", e),
                Error::IO(ref err) => format!("{}", err),
                Error::JsonEncode(ref e) => format!("JSON encoding error: {}", e),
            };
            write!(f, "{}", msg)
        }
    }

    impl error::Error for Error {
        fn description(&self) -> &str {
            match *self {
                Error::HabitatCommon(ref err) => err.description(),
                Error::IO(ref err) => err.description(),
                Error::JsonEncode(_) => "JSON encoding error",
            }
        }
    }

    impl From<common::Error> for Error {
        fn from(err: common::Error) -> Self {
            Error::HabitatCommon(err)
        }
    }

    impl From<io::Error> for Error {
        fn from(err: io::Error) -> Self {
            Error::IO(err)
        }
    }

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

    /// A Gossip Client.
    pub struct Client<'a> {
        pub socket: UtpSocket,
        ring_key: Option<&'a SymKey>,
    }

    impl<'a> Client<'a> {
        /// Create a new client from anything that can become a `SocketAddr`.
        ///
        /// # Errors
        ///
        /// * If we cannot connect the UTP socket
        pub fn new<A: ToSocketAddrs>(dst: A, ring_key: Option<&'a SymKey>) -> Result<Client> {
            let socket = try!(UtpSocket::connect(dst));
            Ok(Client {
                socket: socket,
                ring_key: ring_key,
            })
        }

        pub fn inject(&mut self, rumors_for_remote: RumorList) -> Result<()> {
            try!(self.send_message(Protocol::Inject(rumors_for_remote)));
            Ok(())
        }

        /// Send a message.
        ///
        /// # Errors
        ///
        /// * We cannot encode the `Message`
        /// * We fail to send the encoded buffer to the remote
        pub fn send_message(&mut self, msg: Protocol) -> Result<()> {
            let encoded = {
                let wire_msg = match self.ring_key.as_ref() {
                    Some(key) => try!(WireMessage::encrypted(&msg, &key)),
                    None => try!(WireMessage::plain(&msg)),
                };
                try!(json::encode(&wire_msg))
            };
            debug!("Encoded message {:#?}", encoded);
            try!(self.socket.send_to(encoded.as_bytes()));
            debug!("Sent protocol: {:?}", msg);
            Ok(())
        }
    }

    /// Each member has a Uuid.
    pub type MemberId = Uuid;

    /// A Peer is a representation of a member; it tracks how to contact the member, and whether
    /// this request is actually being proxied during a PingReq operation.
    #[derive(Clone, Debug, RustcEncodable)]
    pub struct Peer {
        pub member_id: MemberId,
        pub listening_on: String,
        pub proxy_through: Option<String>,
        pub proxy_to: Option<String>,
    }

    /// The SWIM Protocol.
    #[derive(Debug, RustcEncodable)]
    pub enum Protocol {
        Inject(RumorList),
    }

    /// Rumors contain Messages as their payload, which are then processed by the correct internal
    /// sub-system.
    #[derive(Debug, RustcEncodable, Clone, PartialEq, Eq)]
    pub enum Message {
        GossipFile(GossipFile),
    }

    /// A UUID for Rumors. In practice, always matches the UUID of a message payload.
    pub type RumorId = Uuid;

    /// A Rumor, which contains a Message.
    #[derive(Debug, RustcEncodable, PartialEq, Eq, Clone)]
    pub struct Rumor {
        pub id: RumorId,
        pub payload: Message,
    }

    impl Rumor {
        /// Create a new rumor with a `Message::GossipFile` payload.
        pub fn gossip_file(cf: GossipFile) -> Rumor {
            Rumor {
                id: Uuid::new_v4(),
                payload: Message::GossipFile(cf),
            }
        }
    }

    /// A list of rumors, and their corresponding heat. Heat determines whether we need to share the
    /// rumor with a given Member
    #[derive(Clone, Debug, RustcEncodable)]
    pub struct RumorList {
        pub rumors: HashMap<RumorId, Rumor>,
        pub heat: HashMap<MemberId, HashMap<RumorId, usize>>,
    }

    impl RumorList {
        /// Create a new RumorList.
        pub fn new() -> RumorList {
            RumorList {
                rumors: HashMap::new(),
                heat: HashMap::new(),
            }
        }

        /// Add a new rumor to the list.
        pub fn add_rumor(&mut self, rumor: Rumor) {
            debug!("Adding rumor {:?}", rumor);
            self.reset_heat_for(&rumor.id);
            self.rumors.insert(rumor.id, rumor);
        }

        /// Resets the heat for a rumor.
        pub fn reset_heat_for(&mut self, rumor_id: &RumorId) {
            for (_member_id, mut rumor_heat) in self.heat.iter_mut() {
                debug!("Reset heat for {:?}", rumor_id);
                if rumor_heat.contains_key(rumor_id) {
                    let mut count = rumor_heat.get_mut(rumor_id).unwrap();
                    *count = 0;
                } else {
                    rumor_heat.insert(rumor_id.clone(), 0);
                }
            }
        }
    }
}
<commit_msg>Utilize entry API in hab::gossip::reset_heat_for<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use hcore::crypto::SymKey;

use error::Result;

pub fn send_rumors_to_peers(peer_listeners: &Vec<String>,
                            ring_key: Option<&SymKey>,
                            rumor_list: &hab_gossip::RumorList)
                            -> Result<()> {
    let fail_after = 10;
    let mut count = 0;

    if peer_listeners.len() > 0 {
        while count < fail_after {
            if try_peers(peer_listeners, ring_key, rumor_list) {
                return Ok(());
            } else {
                count = count + 1;
                println!("Could not connect to any initial peers; attempt {} of {}.",
                         count,
                         fail_after);
            }
        }
    }
    Ok(())
}

fn try_peers(peer_listeners: &Vec<String>,
             ring_key: Option<&SymKey>,
             rumor_list: &hab_gossip::RumorList)
             -> bool {
    let mut initialized = false;
    for to in peer_listeners {
        println!("Joining peer: {}", to);
        let mut c = match hab_gossip::Client::new(&to[..], ring_key.clone()) {
            Ok(c) => c,
            Err(e) => {
                debug!("Error creating gossip client - {:?}", e);
                println!("Failed to create a gossip client for {}", to);
                continue;
            }
        };

        match c.inject(rumor_list.clone()) {
            Ok(_) => println!("Configuration applied to: {}", to),
            Err(e) => {
                println!("Failed to ping {:?}: {:?}", to, e);
                continue;
            }
        }
        initialized = true;
    }
    initialized
}

pub mod hab_gossip {
    //! **Note** that this is a temporary measure. In order to implement the `rumor inject`
    //! subcommand in a codebase independent of the Supervisor, it was quickest to copy a minimal
    //! implementation of the Gossip subsystem suitable enough to "blind inject" a particular
    //! message type and terminate.  The Supervisor Gossip code needs some further refactoring for
    //! generic and minimal reuse. Until then, enjoy Fletcher's minimal Gossip port - FIN

    use std::collections::HashMap;
    use std::error;
    use std::fmt;
    use std::net::ToSocketAddrs;
    use std::io;
    use std::result;

    use common;
    use common::gossip_file::GossipFile;
    use common::wire_message::WireMessage;
    use hcore::crypto::SymKey;
    use rustc_serialize::json;
    use utp::UtpSocket;
    use uuid::Uuid;

    /// The default port for the Gossip protocol
    pub static GOSSIP_DEFAULT_PORT: usize = 9634;

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

    #[derive(Debug)]
    pub enum Error {
        HabitatCommon(common::Error),
        IO(io::Error),
        JsonEncode(json::EncoderError),
    }

    impl fmt::Display for Error {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let msg = match *self {
                Error::HabitatCommon(ref e) => format!("{}", e),
                Error::IO(ref err) => format!("{}", err),
                Error::JsonEncode(ref e) => format!("JSON encoding error: {}", e),
            };
            write!(f, "{}", msg)
        }
    }

    impl error::Error for Error {
        fn description(&self) -> &str {
            match *self {
                Error::HabitatCommon(ref err) => err.description(),
                Error::IO(ref err) => err.description(),
                Error::JsonEncode(_) => "JSON encoding error",
            }
        }
    }

    impl From<common::Error> for Error {
        fn from(err: common::Error) -> Self {
            Error::HabitatCommon(err)
        }
    }

    impl From<io::Error> for Error {
        fn from(err: io::Error) -> Self {
            Error::IO(err)
        }
    }

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

    /// A Gossip Client.
    pub struct Client<'a> {
        pub socket: UtpSocket,
        ring_key: Option<&'a SymKey>,
    }

    impl<'a> Client<'a> {
        /// Create a new client from anything that can become a `SocketAddr`.
        ///
        /// # Errors
        ///
        /// * If we cannot connect the UTP socket
        pub fn new<A: ToSocketAddrs>(dst: A, ring_key: Option<&'a SymKey>) -> Result<Client> {
            let socket = try!(UtpSocket::connect(dst));
            Ok(Client {
                socket: socket,
                ring_key: ring_key,
            })
        }

        pub fn inject(&mut self, rumors_for_remote: RumorList) -> Result<()> {
            try!(self.send_message(Protocol::Inject(rumors_for_remote)));
            Ok(())
        }

        /// Send a message.
        ///
        /// # Errors
        ///
        /// * We cannot encode the `Message`
        /// * We fail to send the encoded buffer to the remote
        pub fn send_message(&mut self, msg: Protocol) -> Result<()> {
            let encoded = {
                let wire_msg = match self.ring_key.as_ref() {
                    Some(key) => try!(WireMessage::encrypted(&msg, &key)),
                    None => try!(WireMessage::plain(&msg)),
                };
                try!(json::encode(&wire_msg))
            };
            debug!("Encoded message {:#?}", encoded);
            try!(self.socket.send_to(encoded.as_bytes()));
            debug!("Sent protocol: {:?}", msg);
            Ok(())
        }
    }

    /// Each member has a Uuid.
    pub type MemberId = Uuid;

    /// A Peer is a representation of a member; it tracks how to contact the member, and whether
    /// this request is actually being proxied during a PingReq operation.
    #[derive(Clone, Debug, RustcEncodable)]
    pub struct Peer {
        pub member_id: MemberId,
        pub listening_on: String,
        pub proxy_through: Option<String>,
        pub proxy_to: Option<String>,
    }

    /// The SWIM Protocol.
    #[derive(Debug, RustcEncodable)]
    pub enum Protocol {
        Inject(RumorList),
    }

    /// Rumors contain Messages as their payload, which are then processed by the correct internal
    /// sub-system.
    #[derive(Debug, RustcEncodable, Clone, PartialEq, Eq)]
    pub enum Message {
        GossipFile(GossipFile),
    }

    /// A UUID for Rumors. In practice, always matches the UUID of a message payload.
    pub type RumorId = Uuid;

    /// A Rumor, which contains a Message.
    #[derive(Debug, RustcEncodable, PartialEq, Eq, Clone)]
    pub struct Rumor {
        pub id: RumorId,
        pub payload: Message,
    }

    impl Rumor {
        /// Create a new rumor with a `Message::GossipFile` payload.
        pub fn gossip_file(cf: GossipFile) -> Rumor {
            Rumor {
                id: Uuid::new_v4(),
                payload: Message::GossipFile(cf),
            }
        }
    }

    /// A list of rumors, and their corresponding heat. Heat determines whether we need to share the
    /// rumor with a given Member
    #[derive(Clone, Debug, RustcEncodable)]
    pub struct RumorList {
        pub rumors: HashMap<RumorId, Rumor>,
        pub heat: HashMap<MemberId, HashMap<RumorId, usize>>,
    }

    impl RumorList {
        /// Create a new RumorList.
        pub fn new() -> RumorList {
            RumorList {
                rumors: HashMap::new(),
                heat: HashMap::new(),
            }
        }

        /// Add a new rumor to the list.
        pub fn add_rumor(&mut self, rumor: Rumor) {
            debug!("Adding rumor {:?}", rumor);
            self.reset_heat_for(&rumor.id);
            self.rumors.insert(rumor.id, rumor);
        }

        /// Resets the heat for a rumor.
        pub fn reset_heat_for(&mut self, rumor_id: &RumorId) {
            for (_member_id, mut rumor_heat) in self.heat.iter_mut() {
                debug!("Reset heat for {:?}", rumor_id);
                *rumor_heat.entry(*rumor_id).or_insert(0) = 0;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add the ability to use numbers for indexing map types<commit_after><|endoftext|>


<commit_before>use std::mem;
use std::ptr;
use std::sync::{
    Arc,
    Mutex,
};
use std::thread;
use std::time::Duration;

use winapi::winsock2::{
    fd_set,
    FD_SETSIZE,
    SOCKET_ERROR,
    timeval,
    WSADATA,
};
use ws2_32::{
    select,
    WSACleanup,
    WSAStartup,
};

use c_ares;
use mio;

use error::ResolverError;
use eventloop::EventLoopHandle;

// The EventLoop will use select() to check on the status of file descriptors
// that c-ares cares about.
//
// It also waits for a message telling it to shut down.  We use a mio channel
// here only for consistency with the unix interface.
pub struct EventLoop {
    tx_msg_channel: mio::channel::Sender<Message>,
    rx_msg_channel: mio::channel::Receiver<Message>,
    pub ares_channel: Arc<Mutex<c_ares::Channel>>,
    quit: bool,
}

// Messages for the event loop.
#[derive(Debug)]
pub enum Message {
    // 'Shut down'.
    ShutDown,
}

impl EventLoop {
    // Create a new event loop.
    pub fn new(options: c_ares::Options) -> Result<EventLoop, ResolverError> {
        // Initialize sockets.
        unsafe {
            let mut wsadata: WSADATA = mem::uninitialized();
            WSAStartup(0x101, &mut wsadata);
        }

        // Create the message channel.
        let (tx, rx) = mio::channel::channel();

        // Create the c-ares channel.
        let mut ares_channel = try!(c_ares::Channel::new(options));
        ares_channel.set_servers(&["8.8.8.8"]).unwrap();
        let locked_channel = Arc::new(Mutex::new(ares_channel));

        // Create and return the event loop.
        let event_loop = EventLoop {
            tx_msg_channel: tx,
            rx_msg_channel: rx,
            ares_channel: locked_channel,
            quit: false,
        };
        Ok(event_loop)
    }

    // Run the event loop.
    pub fn run(self) -> EventLoopHandle {
        let tx_clone = self.tx_msg_channel.clone();
        let join_handle = thread::spawn(|| self.event_loop_thread());
        EventLoopHandle::new(join_handle, tx_clone)
    }

    // Event loop thread - waits for events, and handles them.
    fn event_loop_thread(mut self) {
        let timeout = timeval {
            tv_sec: 0,
            tv_usec: 200000,
        };
        let duration = Duration::from_millis(200);

        // Loop round, asking c-ares what it cares about and doing as asked.
        loop {
            let mut read_fds = fd_set {
                fd_count: 0,
                fd_array: [c_ares::SOCKET_BAD; FD_SETSIZE],
            };
            let mut write_fds = fd_set {
                fd_count: 0,
                fd_array: [c_ares::SOCKET_BAD; FD_SETSIZE],
            };
            let count = self.ares_channel.lock().unwrap().fds(&mut read_fds, &mut write_fds);

            // Wait for something to happen.
            let results = unsafe {
                if count == 0 {
                    thread::sleep(duration);
                    0
                } else {
                    select(0, &mut read_fds, &mut write_fds, ptr::null_mut(), &timeout)
                }
            };

            // Process whatever happened.
            match results {
                SOCKET_ERROR => panic!("Socket error"),
                _ => self.ares_channel.lock().unwrap().process(&mut read_fds, &mut write_fds),
            }

            // Check whether we're asked to quit.
            self.handle_messages();
            if self.quit { break }
        }
    }

    // Process messages incoming on the channel.
    fn handle_messages(&mut self) {
        loop {
            match self.rx_msg_channel.try_recv() {
                Ok(Message::ShutDown) => {
                    // Instruction to shut down.
                    self.quit = true;
                    break
                },

                // No more instructions.
                Err(_) => break,
            }
        }
    }
}

impl Drop for EventLoop {
    fn drop(&mut self) {
        unsafe { WSACleanup(); }
    }
}
<commit_msg>Remove temporary code<commit_after>use std::mem;
use std::ptr;
use std::sync::{
    Arc,
    Mutex,
};
use std::thread;
use std::time::Duration;

use winapi::winsock2::{
    fd_set,
    FD_SETSIZE,
    SOCKET_ERROR,
    timeval,
    WSADATA,
};
use ws2_32::{
    select,
    WSACleanup,
    WSAStartup,
};

use c_ares;
use mio;

use error::ResolverError;
use eventloop::EventLoopHandle;

// The EventLoop will use select() to check on the status of file descriptors
// that c-ares cares about.
//
// It also waits for a message telling it to shut down.  We use a mio channel
// here only for consistency with the unix interface.
pub struct EventLoop {
    tx_msg_channel: mio::channel::Sender<Message>,
    rx_msg_channel: mio::channel::Receiver<Message>,
    pub ares_channel: Arc<Mutex<c_ares::Channel>>,
    quit: bool,
}

// Messages for the event loop.
#[derive(Debug)]
pub enum Message {
    // 'Shut down'.
    ShutDown,
}

impl EventLoop {
    // Create a new event loop.
    pub fn new(options: c_ares::Options) -> Result<EventLoop, ResolverError> {
        // Initialize sockets.
        unsafe {
            let mut wsadata: WSADATA = mem::uninitialized();
            WSAStartup(0x101, &mut wsadata);
        }

        // Create the message channel.
        let (tx, rx) = mio::channel::channel();

        // Create the c-ares channel.
        let ares_channel = try!(c_ares::Channel::new(options));
        let locked_channel = Arc::new(Mutex::new(ares_channel));

        // Create and return the event loop.
        let event_loop = EventLoop {
            tx_msg_channel: tx,
            rx_msg_channel: rx,
            ares_channel: locked_channel,
            quit: false,
        };
        Ok(event_loop)
    }

    // Run the event loop.
    pub fn run(self) -> EventLoopHandle {
        let tx_clone = self.tx_msg_channel.clone();
        let join_handle = thread::spawn(|| self.event_loop_thread());
        EventLoopHandle::new(join_handle, tx_clone)
    }

    // Event loop thread - waits for events, and handles them.
    fn event_loop_thread(mut self) {
        let timeout = timeval {
            tv_sec: 0,
            tv_usec: 200000,
        };
        let duration = Duration::from_millis(200);

        // Loop round, asking c-ares what it cares about and doing as asked.
        loop {
            let mut read_fds = fd_set {
                fd_count: 0,
                fd_array: [c_ares::SOCKET_BAD; FD_SETSIZE],
            };
            let mut write_fds = fd_set {
                fd_count: 0,
                fd_array: [c_ares::SOCKET_BAD; FD_SETSIZE],
            };
            let count = self.ares_channel.lock().unwrap().fds(&mut read_fds, &mut write_fds);

            // Wait for something to happen.
            let results = unsafe {
                if count == 0 {
                    thread::sleep(duration);
                    0
                } else {
                    select(0, &mut read_fds, &mut write_fds, ptr::null_mut(), &timeout)
                }
            };

            // Process whatever happened.
            match results {
                SOCKET_ERROR => panic!("Socket error"),
                _ => self.ares_channel.lock().unwrap().process(&mut read_fds, &mut write_fds),
            }

            // Check whether we're asked to quit.
            self.handle_messages();
            if self.quit { break }
        }
    }

    // Process messages incoming on the channel.
    fn handle_messages(&mut self) {
        loop {
            match self.rx_msg_channel.try_recv() {
                Ok(Message::ShutDown) => {
                    // Instruction to shut down.
                    self.quit = true;
                    break
                },

                // No more instructions.
                Err(_) => break,
            }
        }
    }
}

impl Drop for EventLoop {
    fn drop(&mut self) {
        unsafe { WSACleanup(); }
    }
}
<|endoftext|>


<commit_before>

/* -*- mode: rust; indent-tabs-mode: nil -*-
 * Implementation of 'fasta' benchmark from
 * Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 */
use std;
import vec;
import uint;
import int;
import str;
import io::writer_util;

fn LINE_LENGTH() -> uint { ret 60u; }

type myrandom = @{mut last: u32};

fn myrandom_next(r: myrandom, mx: u32) -> u32 {
    r.last = (r.last * 3877u32 + 29573u32) % 139968u32;
    mx * r.last / 139968u32
}

type aminoacids = {ch: char, prob: u32};

fn make_cumulative(aa: [aminoacids]) -> [aminoacids] {
    let mut cp: u32 = 0u32;
    let mut ans: [aminoacids] = [];
    for aa.each {|a| cp += a.prob; ans += [{ch: a.ch, prob: cp}]; }
    ret ans;
}

fn select_random(r: u32, genelist: [aminoacids]) -> char {
    if r < genelist[0].prob { ret genelist[0].ch; }
    fn bisect(v: [aminoacids], lo: uint, hi: uint, target: u32) -> char {
        if hi > lo + 1u {
            let mid: uint = lo + (hi - lo) / 2u;
            if target < v[mid].prob {
                ret bisect(v, lo, mid, target);
            } else { ret bisect(v, mid, hi, target); }
        } else { ret v[hi].ch; }
    }
    ret bisect(genelist, 0u, vec::len::<aminoacids>(genelist) - 1u, r);
}

fn make_random_fasta(wr: io::writer, id: str, desc: str, genelist: [aminoacids], n: int) {
    wr.write_line(">" + id + " " + desc);
    let rng = @{mut last: std::rand::rng().next()};
    let mut op: str = "";
    for uint::range(0u, n as uint) {|_i|
        str::push_char(op, select_random(myrandom_next(rng, 100u32),
                                         genelist));
        if str::len(op) >= LINE_LENGTH() {
            wr.write_line(op);
            op = "";
        }
    }
    if str::len(op) > 0u { wr.write_line(op); }
}

fn make_repeat_fasta(wr: io::writer, id: str, desc: str, s: str, n: int) unsafe {
    wr.write_line(">" + id + " " + desc);
    let mut op: str = "";
    let sl: uint = str::len(s);
    for uint::range(0u, n as uint) {|i|
        str::unsafe::push_byte(op, s[i % sl]);
        if str::len(op) >= LINE_LENGTH() {
            wr.write_line(op);
            op = "";
        }
    }
    if str::len(op) > 0u { wr.write_line(op); }
}

fn acid(ch: char, prob: u32) -> aminoacids { ret {ch: ch, prob: prob}; }

fn main(args: [str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        // alioth tests k-nucleotide with this data at 25,000,000
        ["", "300000"]
    } else if args.len() <= 1u {
        ["", "1000"]
    } else {
        args
    };

    let writer = if os::getenv("RUST_BENCH").is_some() {
        result::get(io::file_writer("./shootout-fasta.data", [io::truncate, io::create]))
    } else {
        io::stdout()
    };

    let n = int::from_str(args[1]).get();

    let iub: [aminoacids] =
        make_cumulative([acid('a', 27u32), acid('c', 12u32), acid('g', 12u32),
                         acid('t', 27u32), acid('B', 2u32), acid('D', 2u32),
                         acid('H', 2u32), acid('K', 2u32), acid('M', 2u32),
                         acid('N', 2u32), acid('R', 2u32), acid('S', 2u32),
                         acid('V', 2u32), acid('W', 2u32), acid('Y', 2u32)]);
    let homosapiens: [aminoacids] =
        make_cumulative([acid('a', 30u32), acid('c', 20u32), acid('g', 20u32),
                         acid('t', 30u32)]);
    let alu: str =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
            "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
            "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
            "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
            "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
            "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
            "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    make_repeat_fasta(writer, "ONE", "Homo sapiens alu", alu, n * 2);
    make_random_fasta(writer, "TWO", "IUB ambiguity codes", iub, n * 3);
    make_random_fasta(writer, "THREE",
                      "Homo sapiens frequency", homosapiens, n * 5);
}
<commit_msg>bench: Increase the difficulty of fasta<commit_after>

/* -*- mode: rust; indent-tabs-mode: nil -*-
 * Implementation of 'fasta' benchmark from
 * Computer Language Benchmarks Game
 * http://shootout.alioth.debian.org/
 */
use std;
import vec;
import uint;
import int;
import str;
import io::writer_util;

fn LINE_LENGTH() -> uint { ret 60u; }

type myrandom = @{mut last: u32};

fn myrandom_next(r: myrandom, mx: u32) -> u32 {
    r.last = (r.last * 3877u32 + 29573u32) % 139968u32;
    mx * r.last / 139968u32
}

type aminoacids = {ch: char, prob: u32};

fn make_cumulative(aa: [aminoacids]) -> [aminoacids] {
    let mut cp: u32 = 0u32;
    let mut ans: [aminoacids] = [];
    for aa.each {|a| cp += a.prob; ans += [{ch: a.ch, prob: cp}]; }
    ret ans;
}

fn select_random(r: u32, genelist: [aminoacids]) -> char {
    if r < genelist[0].prob { ret genelist[0].ch; }
    fn bisect(v: [aminoacids], lo: uint, hi: uint, target: u32) -> char {
        if hi > lo + 1u {
            let mid: uint = lo + (hi - lo) / 2u;
            if target < v[mid].prob {
                ret bisect(v, lo, mid, target);
            } else { ret bisect(v, mid, hi, target); }
        } else { ret v[hi].ch; }
    }
    ret bisect(genelist, 0u, vec::len::<aminoacids>(genelist) - 1u, r);
}

fn make_random_fasta(wr: io::writer, id: str, desc: str, genelist: [aminoacids], n: int) {
    wr.write_line(">" + id + " " + desc);
    let rng = @{mut last: std::rand::rng().next()};
    let mut op: str = "";
    for uint::range(0u, n as uint) {|_i|
        str::push_char(op, select_random(myrandom_next(rng, 100u32),
                                         genelist));
        if str::len(op) >= LINE_LENGTH() {
            wr.write_line(op);
            op = "";
        }
    }
    if str::len(op) > 0u { wr.write_line(op); }
}

fn make_repeat_fasta(wr: io::writer, id: str, desc: str, s: str, n: int) unsafe {
    wr.write_line(">" + id + " " + desc);
    let mut op: str = "";
    let sl: uint = str::len(s);
    for uint::range(0u, n as uint) {|i|
        str::unsafe::push_byte(op, s[i % sl]);
        if str::len(op) >= LINE_LENGTH() {
            wr.write_line(op);
            op = "";
        }
    }
    if str::len(op) > 0u { wr.write_line(op); }
}

fn acid(ch: char, prob: u32) -> aminoacids { ret {ch: ch, prob: prob}; }

fn main(args: [str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        // alioth tests k-nucleotide with this data at 25,000,000
        ["", "5000000"]
    } else if args.len() <= 1u {
        ["", "1000"]
    } else {
        args
    };

    let writer = if os::getenv("RUST_BENCH").is_some() {
        result::get(io::file_writer("./shootout-fasta.data", [io::truncate, io::create]))
    } else {
        io::stdout()
    };

    let n = int::from_str(args[1]).get();

    let iub: [aminoacids] =
        make_cumulative([acid('a', 27u32), acid('c', 12u32), acid('g', 12u32),
                         acid('t', 27u32), acid('B', 2u32), acid('D', 2u32),
                         acid('H', 2u32), acid('K', 2u32), acid('M', 2u32),
                         acid('N', 2u32), acid('R', 2u32), acid('S', 2u32),
                         acid('V', 2u32), acid('W', 2u32), acid('Y', 2u32)]);
    let homosapiens: [aminoacids] =
        make_cumulative([acid('a', 30u32), acid('c', 20u32), acid('g', 20u32),
                         acid('t', 30u32)]);
    let alu: str =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
            "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
            "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
            "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
            "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
            "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
            "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    make_repeat_fasta(writer, "ONE", "Homo sapiens alu", alu, n * 2);
    make_random_fasta(writer, "TWO", "IUB ambiguity codes", iub, n * 3);
    make_random_fasta(writer, "THREE",
                      "Homo sapiens frequency", homosapiens, n * 5);
}
<|endoftext|>


<commit_before><commit_msg>fix: Simplify flag parsing<commit_after><|endoftext|>