<commit_before>// Copyright 2016 Luis Casillas. See the COPYRIGHT file at the
// top-level directory of this distribution
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate rand;

pub mod splittable {
    //! Traits to support splittable random number generators.
    //! References:
    //!
    //! * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
    //!   Pseudorandom Number Generators using Cryptographic
    //!   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
    //!   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium
    //!   on Haskell*, pp. 47-58.
    //! * Schaathun, Hans Georg.  2015.  ["Evaluation of Splittable
    //!   Pseudo-Random
    //!   Generators."](http://www.hg.schaathun.net/research/Papers/hgs2015jfp.pdf)
    //!   *Journal of Functional Programming*, Vol. 25.

    //! * The Haskell [`tf-random` library](https://hackage.haskell.org/package/tf-random).

    use rand::Rng;

    /// A trait for **splittable** pseudo random generators.  These
    /// are genertors that support a "split" operation that produces
    /// two or more "child" generators whose initial state depends on
    /// the source RNG's state, but produce outputs that are
    /// uncorrelated to each other.
    pub trait SplittableRng : Rng + Sized {

        /// The type of "splits" produced off a `SplittableRng`
        /// instance.  A split is an immutable object that captures
        /// the state of the RNG at the branching point, and serves as
        /// a factory for constructing RNGs for the "branches."
        type Split : SplitRng<Self>;

        /// Split this generator into branches.  Each branch is
        /// accessible from the resulting "split" object as a unique
        /// `usize` index.
        ///
        /// The original generator is moved into this function, and
        /// can then no longer be reused.  This is deliberate; the
        /// Claessen & Pałka construction requires this.
        ///
        /// But note that the `Split` object returned from here
        /// supports instantiating the same branch multiple times.
        /// This is also deliberate.
        fn splitn(self) -> Self::Split;

        /// Split this random number generator into two branches.
        /// This has a default implementation in terms of `splitn`.
        fn split(self) -> (Self, Self) {
            let splits: Self::Split = self.splitn();
            (splits.branch(0), splits.branch(1))
        }

    }

    /// The trait implemented by the "splits" of a `SplittableRng`.
    /// These objects act as immutable factories for `SplittableRng`
    /// instances, accessed by supplying an `usize` index.
    pub trait SplitRng<R> {
        /// Instantiate the `i`th branch of the captured
        /// `SplittableRng`.
        ///
        /// Note that instantiating the same `i` multiple times is
        /// allowed, and they all start from the same state.  This is
        /// useful in some cases; for example, random generation of
        /// deterministic functions (like Haskell's QuickCheck library
        /// does).
        fn branch(&self, i: usize) -> R;
    }

}

pub mod siprng {

    use rand::{Rand, Rng, SeedableRng};
    use splittable::{SplittableRng, SplitRng};
    use std::mem;

    /// A splittable pseudo-random number generator based on the
    /// SipHash-1-3 function.  **This is not intended to be a
    /// cryptographically secure PRNG.**
    ///
    /// This generator is broadly modeled after Claessen and Pałka's,
    /// a version of which is implemented in the Haskell [`tf-random`
    /// library](https://hackage.haskell.org/package/tf-random).
    /// Instead of the Skein hash function, however, we use
    /// SipHash-1-3 as the pseudo-random function.
    ///
    /// References:
    ///
    /// * Aumasson, Jean-Philippe and Daniel J. Bernstein.  2012.
    ///   ["SipHash: a fast short-input
    ///   PRF."](https://eprint.iacr.org/2012/351) Cryptology ePrint
    ///   Archive, Report 2012/351.
    /// * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
    ///   Pseudorandom Number Generators using Cryptographic
    ///   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
    ///   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium
    ///   on Haskell*, pp. 47-58.
    /// * The Haskell [`tf-random` library](https://hackage.haskell.org/package/tf-random).
    #[derive(Clone)]
    pub struct SipRng {
        v0:  u64,
        v1:  u64,
        v2:  u64,
        v3:  u64,
        ctr: u64,
        len: usize
    }

    /// A "split" of a `SipRng`.
    pub struct SipRngSplit(SipRng);

    macro_rules! sipround {
        ($v0: expr, $v1: expr, $v2: expr, $v3: expr) => {
            $v0 = $v0.wrapping_add($v1); $v2 = $v2.wrapping_add($v3);
            $v1 = $v1.rotate_left(13);   $v3 = $v3.rotate_left(16);
            $v1 ^= $v0;                  $v3 ^= $v2;
            $v0 = $v0.rotate_left(32);

            $v2 = $v2.wrapping_add($v1); $v0 = $v0.wrapping_add($v3);
            $v1 = $v1.rotate_left(17);   $v3 = $v3.rotate_left(21);
            $v1 ^= $v2;                  $v3 ^= $v0;
            $v2 = $v0.rotate_left(32);
        }
    }

    const C0: u64 = 0x736f6d6570736575;
    const C1: u64 = 0x646f72616e646f6d;
    const C2: u64 = 0x6c7967656e657261;
    const C3: u64 = 0x7465646279746573;

    impl SipRng {
        /// Create a `SipRng` generator from two `u64`s given as seed.
        pub fn new(k0: u64, k1: u64) -> SipRng {
            SipRng {
                v0:  k0 ^ C0,
                v1:  k1 ^ C1,
                v2:  k0 ^ C2,
                v3:  k1 ^ C3,
                ctr: 0,
                len: 1
            }
        }

        #[inline]
        fn advance(&mut self) {
            self.v3 ^= self.ctr;
            sipround!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= self.ctr;
            self.ctr.wrapping_add(1);
            // TODO: should we do something here if we hit zero again?
        }

        #[inline]
        fn descend(&mut self, branch: u64) {
            self.v3 ^= branch;
            sipround!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= branch;
            self.len.wrapping_add(1);
        }

    }

    impl SplitRng<SipRng> for SipRngSplit {
        fn branch(&self, i: usize) -> SipRng {
            let mut r = self.0.clone();
            r.descend(i as u64);
            r
        }
    }

    impl SplittableRng for SipRng {
        type Split = SipRngSplit;

        fn splitn(self) -> SipRngSplit {
            SipRngSplit(self)
        }

    }

    impl Rng for SipRng {
        #[inline]
        fn next_u64(&mut self) -> u64 {
            self.advance();
            let (mut v0, mut v1, mut v2, mut v3) =
                (self.v0, self.v1, self.v2, self.v3);

            let len = (self.len as u64).wrapping_shl(56);
            v3 ^= len;
            sipround!(v0, v1, v2, v3);
            v0 ^= len;

            v2 ^= 0xff;
            sipround!(v0, v1, v2, v3);
            sipround!(v0, v1, v2, v3);
            sipround!(v0, v1, v2, v3);
            v0 ^ v1 ^ v2 ^ v3
        }

        #[inline]
        fn next_u32(&mut self) -> u32 {
            self.next_u64() as u32
        }

        #[inline]
        fn fill_bytes(&mut self, dest: &mut [u8]) {
            for chunk in dest.chunks_mut(8) {
                let block = unsafe {
                    mem::transmute::<u64, [u8; 8]>(self.next_u64())
                };
                for i in 0..chunk.len() {
                    chunk[i] = block[i];
                }
            }
        }
    }

    impl SeedableRng<(u64, u64)> for SipRng {

        fn reseed(&mut self, seed: (u64, u64)) {
            self.v0 = seed.0 ^ C0;
            self.v1 = seed.1 ^ C1;
            self.v2 = seed.0 ^ C2;
            self.v3 = seed.1 ^ C3;
            self.len = 1;
            self.ctr = 0;
        }

        fn from_seed(seed: (u64, u64)) -> SipRng {
            let (k0, k1) = seed;
            SipRng::new(k0, k1)
        }
    }

    impl Rand for SipRng {
        fn rand<R: Rng>(other: &mut R) -> SipRng {
            let (k0, k1) = other.gen::<(u64, u64)>();
            SipRng::new(k0, k1)
        }
    }

}

#[cfg(test)]
mod tests {
    /*
     * I have shamelessly lifted a lot of these tests from the `rand`
     * crate.
     */

    use rand::{Rng, SeedableRng};
    use rand::os::OsRng;
    use siprng::SipRng;
    use splittable::SplittableRng;

    #[test]
    fn test_rng_rand_split() {
        let seed : (u64, u64) = gen_seed();

        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);

        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));

        let (mut ra0, mut ra1) = ra.split();
        let (mut rb0, mut rb1) = rb.split();

        assert!(iter_eq(ra0.gen_ascii_chars().take(100),
                        rb0.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra1.gen_ascii_chars().take(100),
                        rb1.gen_ascii_chars().take(100)));

        let (mut ra00, mut ra01) = ra0.split();
        let (mut ra10, mut ra11) = ra1.split();
        let (mut rb00, mut rb01) = rb0.split();
        let (mut rb10, mut rb11) = rb1.split();

        assert!(iter_eq(ra00.gen_ascii_chars().take(100),
                        rb00.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra01.gen_ascii_chars().take(100),
                        rb01.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra10.gen_ascii_chars().take(100),
                        rb10.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra11.gen_ascii_chars().take(100),
                        rb11.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_rand_seeded() {
        let seed : (u64, u64) = gen_seed();

        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);

        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_seeded() {
        let seed : (u64, u64) = gen_seed();
        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);
        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_reseed() {
        let seed : (u64, u64) = (1234567890, 987654321);
        let mut r: SipRng = SeedableRng::from_seed(seed);
        let string1: String = r.gen_ascii_chars().take(100).collect();

        r.reseed(seed);

        let string2: String = r.gen_ascii_chars().take(100).collect();
        assert_eq!(string1, string2);
    }

    #[test]
    fn test_rng_clone() {
        let seed : (u64, u64) = (0, 0);
        let mut rng: SipRng = SeedableRng::from_seed(seed);
        let mut clone = rng.clone();
        for _ in 0..16 {
            assert_eq!(rng.next_u64(), clone.next_u64());
        }
    }

    /*
     * Utility functions
     */

    fn gen_seed() -> (u64, u64) {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    fn iter_eq<I, J>(i: I, j: J) -> bool
        where I: IntoIterator,
              J: IntoIterator<Item=I::Item>,
              I::Item: Eq
    {
        // make sure the iterators have equal length
        let mut i = i.into_iter();
        let mut j = j.into_iter();
        loop {
            match (i.next(), j.next()) {
                (Some(ref ei), Some(ref ej)) if ei == ej => { }
                (None, None) => return true,
                _ => return false,
            }
        }
    }
}
<commit_msg>Reset counter to 0 on `descend`.<commit_after>// Copyright 2016 Luis Casillas. See the COPYRIGHT file at the
// top-level directory of this distribution
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate rand;

pub mod splittable {
    //! Traits to support splittable random number generators.
    //! References:
    //!
    //! * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
    //!   Pseudorandom Number Generators using Cryptographic
    //!   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
    //!   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium
    //!   on Haskell*, pp. 47-58.
    //! * Schaathun, Hans Georg.  2015.  ["Evaluation of Splittable
    //!   Pseudo-Random
    //!   Generators."](http://www.hg.schaathun.net/research/Papers/hgs2015jfp.pdf)
    //!   *Journal of Functional Programming*, Vol. 25.

    //! * The Haskell [`tf-random` library](https://hackage.haskell.org/package/tf-random).

    use rand::Rng;

    /// A trait for **splittable** pseudo random generators.  These
    /// are genertors that support a "split" operation that produces
    /// two or more "child" generators whose initial state depends on
    /// the source RNG's state, but produce outputs that are
    /// uncorrelated to each other.
    pub trait SplittableRng : Rng + Sized {

        /// The type of "splits" produced off a `SplittableRng`
        /// instance.  A split is an immutable object that captures
        /// the state of the RNG at the branching point, and serves as
        /// a factory for constructing RNGs for the "branches."
        type Split : SplitRng<Self>;

        /// Split this generator into branches.  Each branch is
        /// accessible from the resulting "split" object as a unique
        /// `usize` index.
        ///
        /// The original generator is moved into this function, and
        /// can then no longer be reused.  This is deliberate; the
        /// Claessen & Pałka construction requires this.
        ///
        /// But note that the `Split` object returned from here
        /// supports instantiating the same branch multiple times.
        /// This is also deliberate.
        fn splitn(self) -> Self::Split;

        /// Split this random number generator into two branches.
        /// This has a default implementation in terms of `splitn`.
        fn split(self) -> (Self, Self) {
            let splits: Self::Split = self.splitn();
            (splits.branch(0), splits.branch(1))
        }

    }

    /// The trait implemented by the "splits" of a `SplittableRng`.
    /// These objects act as immutable factories for `SplittableRng`
    /// instances, accessed by supplying an `usize` index.
    pub trait SplitRng<R> {
        /// Instantiate the `i`th branch of the captured
        /// `SplittableRng`.
        ///
        /// Note that instantiating the same `i` multiple times is
        /// allowed, and they all start from the same state.  This is
        /// useful in some cases; for example, random generation of
        /// deterministic functions (like Haskell's QuickCheck library
        /// does).
        fn branch(&self, i: usize) -> R;
    }

}

pub mod siprng {

    use rand::{Rand, Rng, SeedableRng};
    use splittable::{SplittableRng, SplitRng};
    use std::mem;

    /// A splittable pseudo-random number generator based on the
    /// SipHash-1-3 function.  **This is not intended to be a
    /// cryptographically secure PRNG.**
    ///
    /// This generator is broadly modeled after Claessen and Pałka's,
    /// a version of which is implemented in the Haskell [`tf-random`
    /// library](https://hackage.haskell.org/package/tf-random).
    /// Instead of the Skein hash function, however, we use
    /// SipHash-1-3 as the pseudo-random function.
    ///
    /// References:
    ///
    /// * Aumasson, Jean-Philippe and Daniel J. Bernstein.  2012.
    ///   ["SipHash: a fast short-input
    ///   PRF."](https://eprint.iacr.org/2012/351) Cryptology ePrint
    ///   Archive, Report 2012/351.
    /// * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
    ///   Pseudorandom Number Generators using Cryptographic
    ///   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
    ///   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium
    ///   on Haskell*, pp. 47-58.
    /// * The Haskell [`tf-random` library](https://hackage.haskell.org/package/tf-random).
    #[derive(Clone)]
    pub struct SipRng {
        v0:  u64,
        v1:  u64,
        v2:  u64,
        v3:  u64,
        ctr: u64,
        len: usize
    }

    /// A "split" of a `SipRng`.
    pub struct SipRngSplit(SipRng);

    macro_rules! sipround {
        ($v0: expr, $v1: expr, $v2: expr, $v3: expr) => {
            $v0 = $v0.wrapping_add($v1); $v2 = $v2.wrapping_add($v3);
            $v1 = $v1.rotate_left(13);   $v3 = $v3.rotate_left(16);
            $v1 ^= $v0;                  $v3 ^= $v2;
            $v0 = $v0.rotate_left(32);

            $v2 = $v2.wrapping_add($v1); $v0 = $v0.wrapping_add($v3);
            $v1 = $v1.rotate_left(17);   $v3 = $v3.rotate_left(21);
            $v1 ^= $v2;                  $v3 ^= $v0;
            $v2 = $v0.rotate_left(32);
        }
    }

    const C0: u64 = 0x736f6d6570736575;
    const C1: u64 = 0x646f72616e646f6d;
    const C2: u64 = 0x6c7967656e657261;
    const C3: u64 = 0x7465646279746573;

    impl SipRng {
        /// Create a `SipRng` generator from two `u64`s given as seed.
        pub fn new(k0: u64, k1: u64) -> SipRng {
            SipRng {
                v0:  k0 ^ C0,
                v1:  k1 ^ C1,
                v2:  k0 ^ C2,
                v3:  k1 ^ C3,
                ctr: 0,
                len: 1
            }
        }

        #[inline]
        fn advance(&mut self) {
            self.v3 ^= self.ctr;
            sipround!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= self.ctr;
            self.ctr.wrapping_add(1);
            // TODO: should we do something here if we hit zero again?
        }

        #[inline]
        fn descend(&mut self, branch: u64) {
            self.v3 ^= branch;
            sipround!(self.v0, self.v1, self.v2, self.v3);
            self.v0 ^= branch;
            self.len.wrapping_add(1);
            self.ctr = 0;
        }

    }

    impl SplitRng<SipRng> for SipRngSplit {
        fn branch(&self, i: usize) -> SipRng {
            let mut r = self.0.clone();
            r.descend(i as u64);
            r
        }
    }

    impl SplittableRng for SipRng {
        type Split = SipRngSplit;

        fn splitn(self) -> SipRngSplit {
            SipRngSplit(self)
        }

    }

    impl Rng for SipRng {
        #[inline]
        fn next_u64(&mut self) -> u64 {
            self.advance();
            let (mut v0, mut v1, mut v2, mut v3) =
                (self.v0, self.v1, self.v2, self.v3);

            let len = (self.len as u64).wrapping_shl(56);
            v3 ^= len;
            sipround!(v0, v1, v2, v3);
            v0 ^= len;

            v2 ^= 0xff;
            sipround!(v0, v1, v2, v3);
            sipround!(v0, v1, v2, v3);
            sipround!(v0, v1, v2, v3);
            v0 ^ v1 ^ v2 ^ v3
        }

        #[inline]
        fn next_u32(&mut self) -> u32 {
            self.next_u64() as u32
        }

        #[inline]
        fn fill_bytes(&mut self, dest: &mut [u8]) {
            for chunk in dest.chunks_mut(8) {
                let block = unsafe {
                    mem::transmute::<u64, [u8; 8]>(self.next_u64())
                };
                for i in 0..chunk.len() {
                    chunk[i] = block[i];
                }
            }
        }
    }

    impl SeedableRng<(u64, u64)> for SipRng {

        fn reseed(&mut self, seed: (u64, u64)) {
            self.v0 = seed.0 ^ C0;
            self.v1 = seed.1 ^ C1;
            self.v2 = seed.0 ^ C2;
            self.v3 = seed.1 ^ C3;
            self.len = 1;
            self.ctr = 0;
        }

        fn from_seed(seed: (u64, u64)) -> SipRng {
            let (k0, k1) = seed;
            SipRng::new(k0, k1)
        }
    }

    impl Rand for SipRng {
        fn rand<R: Rng>(other: &mut R) -> SipRng {
            let (k0, k1) = other.gen::<(u64, u64)>();
            SipRng::new(k0, k1)
        }
    }

}

#[cfg(test)]
mod tests {
    /*
     * I have shamelessly lifted a lot of these tests from the `rand`
     * crate.
     */

    use rand::{Rng, SeedableRng};
    use rand::os::OsRng;
    use siprng::SipRng;
    use splittable::SplittableRng;

    #[test]
    fn test_rng_rand_split() {
        let seed : (u64, u64) = gen_seed();

        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);

        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));

        let (mut ra0, mut ra1) = ra.split();
        let (mut rb0, mut rb1) = rb.split();

        assert!(iter_eq(ra0.gen_ascii_chars().take(100),
                        rb0.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra1.gen_ascii_chars().take(100),
                        rb1.gen_ascii_chars().take(100)));

        let (mut ra00, mut ra01) = ra0.split();
        let (mut ra10, mut ra11) = ra1.split();
        let (mut rb00, mut rb01) = rb0.split();
        let (mut rb10, mut rb11) = rb1.split();

        assert!(iter_eq(ra00.gen_ascii_chars().take(100),
                        rb00.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra01.gen_ascii_chars().take(100),
                        rb01.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra10.gen_ascii_chars().take(100),
                        rb10.gen_ascii_chars().take(100)));
        assert!(iter_eq(ra11.gen_ascii_chars().take(100),
                        rb11.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_rand_seeded() {
        let seed : (u64, u64) = gen_seed();

        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);

        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_seeded() {
        let seed : (u64, u64) = gen_seed();
        let mut ra: SipRng = SeedableRng::from_seed(seed);
        let mut rb: SipRng = SeedableRng::from_seed(seed);
        assert!(iter_eq(ra.gen_ascii_chars().take(100),
                        rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_reseed() {
        let seed : (u64, u64) = (1234567890, 987654321);
        let mut r: SipRng = SeedableRng::from_seed(seed);
        let string1: String = r.gen_ascii_chars().take(100).collect();

        r.reseed(seed);

        let string2: String = r.gen_ascii_chars().take(100).collect();
        assert_eq!(string1, string2);
    }

    #[test]
    fn test_rng_clone() {
        let seed : (u64, u64) = (0, 0);
        let mut rng: SipRng = SeedableRng::from_seed(seed);
        let mut clone = rng.clone();
        for _ in 0..16 {
            assert_eq!(rng.next_u64(), clone.next_u64());
        }
    }

    /*
     * Utility functions
     */

    fn gen_seed() -> (u64, u64) {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    fn iter_eq<I, J>(i: I, j: J) -> bool
        where I: IntoIterator,
              J: IntoIterator<Item=I::Item>,
              I::Item: Eq
    {
        // make sure the iterators have equal length
        let mut i = i.into_iter();
        let mut j = j.into_iter();
        loop {
            match (i.next(), j.next()) {
                (Some(ref ei), Some(ref ej)) if ei == ej => { }
                (None, None) => return true,
                _ => return false,
            }
        }
    }
}
<|endoftext|>


<commit_before>
//! Hubcaps wraps hyper with an interface for interacting with the Github API

extern crate hyper;
extern crate rustc_serialize;
extern crate url;

pub mod keys;
pub mod gists;
pub mod deployments;
pub mod errors;
pub mod issues;
pub mod labels;
pub mod rep;
pub mod releases;
pub mod repository;
pub mod statuses;
pub mod pullrequests;

use errors::Error;
use gists::{Gists, UserGists};
use hyper::Client;
use hyper::method::Method;
use hyper::header::{Authorization, UserAgent};
use hyper::status::StatusCode;
use repository::Repository;
use std::default::Default;
use std::fmt;
use std::io::Read;

/// alias for Result that infers hubcaps::Error as Err
pub type Result<T> = std::result::Result<T, Error>;

/// enum representation of github pulls and issues
pub enum State {
  Open,
  Closed,
  All
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            State::Open   => "open",
            State::Closed => "closed",
            State::All    => "all"
        })
    }
}

impl Default for State {
    fn default() -> State {
        State::Open
    }
}

/// enum representation of Github list sorting options
pub enum SortDirection {
    Asc,
    Desc
}

impl fmt::Display for SortDirection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            SortDirection::Asc => "asc",
            SortDirection::Desc => "desc"
        })
    }
}

impl Default for SortDirection {
    fn default() -> SortDirection {
        SortDirection::Asc
    }
}

/// Entry point interface for interacting with Github API
pub struct Github<'a> {
    host: &'static str,
    agent: &'static str,
    client: &'a Client,
    token: Option<&'static str>
}

impl<'a> Github<'a> {
    /// Create a new Github instance
    pub fn new(
        agent: &'static str, client: &'a Client, token: Option<&'static str>) -> Github<'a> {
        Github::host("https://api.github.com", agent, client, token)
    }

    /// Create a new Github instance hosted at a custom location
    pub fn host(
        host: &'static str, agent: &'static str,
        client: &'a Client, token: Option<&'static str>) -> Github<'a> {
        Github {
            host: host,
            agent: agent,
            client: client,
            token: token
        }
    }

    /// Return a reference to a Github reposistory
    pub fn repo(&self, owner: &'static str, repo: &'static str) -> Repository {
        Repository::new(self, owner, repo)
    }

    /// Return a reference to an interface that provides access to a user's gists
    pub fn user_gists(&self, owner: &'static str) -> UserGists {
        UserGists::new(self, owner)
    }

    /// Return a reference to an interface that provides access to the
    /// gists belonging to the owner of the token used to configure this client
    pub fn gists(&self) -> Gists {
        Gists::new(self)
    }

    fn request(
        &self, method: Method, uri: &str, body: Option<&'a [u8]>) -> Result<String> {
        let url = format!("{}{}", self.host, uri);
        let builder = self.client.request(method, &url).header(
            UserAgent(self.agent.to_owned())
        );
        let authenticated = match self.token {
            Some(token) =>
                builder.header(
                    Authorization(format!("token {}", token))
               ),
            _ =>
                builder
        };
        let mut res = match body {
            Some(ref bod) => authenticated.body(*bod).send().unwrap(),
            _ => authenticated.send().unwrap()
        };
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();
        match res.status {
            StatusCode::BadRequest
            | StatusCode::UnprocessableEntity
            | StatusCode::Unauthorized
            | StatusCode::NotFound
            | StatusCode::Forbidden => Err(
                Error::Fault { code: res.status, body: body }
            ),
            _ => Ok(body)
        }
    }

    fn get(&self, uri: &str) -> Result<String> {
        self.request(
            Method::Get,
            uri,
            None
        )
    }

    fn delete(&self, uri: &str) -> Result<()> {
        self.request(
            Method::Delete,
            uri,
            None
        ).map(|_| ())
    }

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

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

    fn put(&self, uri: &str, message: &[u8]) -> Result<String> {
        self.request(
            Method::Put,
            uri,
            Some(message)
        )
    }
}
<commit_msg>clarify<commit_after>
//! Hubcaps wraps hyper with an interface for interacting with the Github API

extern crate hyper;
extern crate rustc_serialize;
extern crate url;

pub mod keys;
pub mod gists;
pub mod deployments;
pub mod errors;
pub mod issues;
pub mod labels;
pub mod rep;
pub mod releases;
pub mod repository;
pub mod statuses;
pub mod pullrequests;

use errors::Error;
use gists::{Gists, UserGists};
use hyper::Client;
use hyper::method::Method;
use hyper::header::{Authorization, UserAgent};
use hyper::status::StatusCode;
use repository::Repository;
use std::default::Default;
use std::fmt;
use std::io::Read;

/// alias for Result that infers hubcaps::Error as Err
pub type Result<T> = std::result::Result<T, Error>;

/// enum representation of github pull and issue state
pub enum State {
  Open,
  Closed,
  All
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            State::Open   => "open",
            State::Closed => "closed",
            State::All    => "all"
        })
    }
}

impl Default for State {
    fn default() -> State {
        State::Open
    }
}

/// enum representation of Github list sorting options
pub enum SortDirection {
    Asc,
    Desc
}

impl fmt::Display for SortDirection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", match *self {
            SortDirection::Asc => "asc",
            SortDirection::Desc => "desc"
        })
    }
}

impl Default for SortDirection {
    fn default() -> SortDirection {
        SortDirection::Asc
    }
}

/// Entry point interface for interacting with Github API
pub struct Github<'a> {
    host: &'static str,
    agent: &'static str,
    client: &'a Client,
    token: Option<&'static str>
}

impl<'a> Github<'a> {
    /// Create a new Github instance
    pub fn new(
        agent: &'static str, client: &'a Client, token: Option<&'static str>) -> Github<'a> {
        Github::host("https://api.github.com", agent, client, token)
    }

    /// Create a new Github instance hosted at a custom location
    pub fn host(
        host: &'static str, agent: &'static str,
        client: &'a Client, token: Option<&'static str>) -> Github<'a> {
        Github {
            host: host,
            agent: agent,
            client: client,
            token: token
        }
    }

    /// Return a reference to a Github reposistory
    pub fn repo(&self, owner: &'static str, repo: &'static str) -> Repository {
        Repository::new(self, owner, repo)
    }

    /// Return a reference to an interface that provides access to a user's gists
    pub fn user_gists(&self, owner: &'static str) -> UserGists {
        UserGists::new(self, owner)
    }

    /// Return a reference to an interface that provides access to the
    /// gists belonging to the owner of the token used to configure this client
    pub fn gists(&self) -> Gists {
        Gists::new(self)
    }

    fn request(
        &self, method: Method, uri: &str, body: Option<&'a [u8]>) -> Result<String> {
        let url = format!("{}{}", self.host, uri);
        let builder = self.client.request(method, &url).header(
            UserAgent(self.agent.to_owned())
        );
        let authenticated = match self.token {
            Some(token) =>
                builder.header(
                    Authorization(format!("token {}", token))
               ),
            _ =>
                builder
        };
        let mut res = match body {
            Some(ref bod) => authenticated.body(*bod).send().unwrap(),
            _ => authenticated.send().unwrap()
        };
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();
        match res.status {
            StatusCode::BadRequest
            | StatusCode::UnprocessableEntity
            | StatusCode::Unauthorized
            | StatusCode::NotFound
            | StatusCode::Forbidden => Err(
                Error::Fault { code: res.status, body: body }
            ),
            _ => Ok(body)
        }
    }

    fn get(&self, uri: &str) -> Result<String> {
        self.request(
            Method::Get,
            uri,
            None
        )
    }

    fn delete(&self, uri: &str) -> Result<()> {
        self.request(
            Method::Delete,
            uri,
            None
        ).map(|_| ())
    }

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

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

    fn put(&self, uri: &str, message: &[u8]) -> Result<String> {
        self.request(
            Method::Put,
            uri,
            Some(message)
        )
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![feature(globs)]
#![feature(default_type_params)]

//! Window abstraction

extern crate input;
extern crate current;
extern crate event_loop;

use input::InputEvent;
use current::{ Get, Modifier, Set };

// Reexport everything from event_loop.
pub use event_loop::*;

/// The title of the window.
pub struct Title(pub String);

/// Work-around trait for `Get<Title>`.
/// Used to support generic constraints.
pub trait GetTitle: Get<Title> {
    /// Returns the title of the window.
    fn get_title(&self) -> Title {
        self.get()
    }
}

impl<T: Get<Title>> GetTitle for T {}

/// Work-around trait for `Set<Title>`.
/// Used to support generic constraints.
pub trait SetTitle: Set<Title> {
    /// Sets title of window.
    fn set_title(&mut self, val: Title) {
        self.set_mut(val);
    }
}

impl<T: Set<Title>> SetTitle for T {}

/// The anti-aliasing samples when rendering.
pub struct Samples(pub u8);

/// Work-around trait for `Get<Samples>`.
/// Used to support generic constraints.
pub trait GetSamples: Get<Samples> {
    /// Returns the antialiasing samples when rendering.
    fn get_samples(&self) -> Samples {
        self.get()
    }
}

impl<T: Get<Samples>> GetSamples for T {}

/// Work-around trait for `Set<Samples>`.
/// Used to support generic constraints.
pub trait SetSamples: Set<Samples> {
    /// Sets antialiasing samples of window.
    fn set_samples(&mut self, val: Samples) {
        self.set_mut(val);
    }
}

impl<T: Set<Samples>> SetSamples for T {}

/// Whether window is opened in full screen mode.
pub struct Fullscreen(pub bool);

/// Work-around trait for `Get<Fullscreen>`.
/// Used to support generic constraints.
pub trait GetFullscreen: Get<Fullscreen> {
    /// Returns whether window is in full screen mode.
    fn get_fullscreen(&self) -> Fullscreen {
        self.get()
    }
}

impl<T: Get<Fullscreen>> GetFullscreen for T {}

/// Work-around trait for `Set<Fullscreen>`.
/// Used to support generic constraints.
pub trait SetFullscreen: Set<Fullscreen> {
    /// Sets window to fullscreen mode.
    fn set_fullscreen(&mut self, val: Fullscreen) {
        self.set_mut(val);
    }
}

impl<T: Set<Fullscreen>> SetFullscreen for T {}

/// Whether to exit when pressing the Esc keyboard button.
pub struct ExitOnEsc(pub bool);

/// Work-around trait for `Get<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait GetExitOnEsc: Get<ExitOnEsc> {
    /// Returns whether window exits when pressing Esc.
    fn get_exit_on_esc(&self) -> ExitOnEsc {
        self.get()
    }
}

impl<T: Get<ExitOnEsc>> GetExitOnEsc for T {}

/// Work-around trait for `Set<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait SetExitOnEsc: Set<ExitOnEsc> {
    /// Sets exit when pressing Esc.
    fn set_exit_on_esc(&mut self, val: ExitOnEsc) {
        self.set_mut(val);
    }
}

impl<T: Set<ExitOnEsc>> SetExitOnEsc for T {}

/// Whether to capture the mouse cursor.
pub struct CaptureCursor(pub bool);

/// Work-around trait for `Get<CaptureCursor>`.
/// Used to support generic constraints.
pub trait GetCaptureCursor: Get<CaptureCursor> {
    /// Returns whether window captures cursor.
    fn get_capture_cursor(&self) -> CaptureCursor {
        self.get()
    }
}

impl<T: Get<CaptureCursor>> GetCaptureCursor for T {}

/// Work-around trait for `Set<CaptureCursor>`.
/// Used to support generic constraints.
pub trait SetCaptureCursor: Set<CaptureCursor> {
    /// Sets capture cursor.
    fn set_capture_cursor(&mut self, val: CaptureCursor) {
        self.set_mut(val);
    }
}

impl<T: Set<CaptureCursor>> SetCaptureCursor for T {}

/// The draw size of the window.
pub struct DrawSize(pub [u32, ..2]);

/// Work-around trait for `Get<DrawSize>`.
/// Used to support generic constraints.
pub trait GetDrawSize: Get<DrawSize> {
    /// Returns the draw size of window.
    fn get_draw_size(&self) -> DrawSize {
        self.get()
    }
}

impl<T: Get<DrawSize>> GetDrawSize for T {}

/// Work-around trait for `Set<DrawSize>`.
/// Used to support generic constraints.
pub trait SetDrawSize: Set<DrawSize> {
    /// Sets draw size.
    fn set_draw_size(&mut self, val: DrawSize) {
        self.set_mut(val);
    }
}

impl<T: Set<DrawSize>> SetDrawSize for T {}

#[test]
fn test_methods() {
    use current::Modifier;

    struct Obj;

    impl Get<ShouldClose> for Obj {
        fn get(&self) -> ShouldClose { ShouldClose(false) }
    }

    impl Modifier<Obj> for ShouldClose {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Size> for Obj {
        fn get(&self) -> Size { Size([0, 0]) }
    }

    impl Modifier<Obj> for Size {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Title> for Obj {
        fn get(&self) -> Title { Title("hello".to_string()) }
    }

    impl Modifier<Obj> for Title {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Samples> for Obj {
        fn get(&self) -> Samples { Samples(0) }
    }

    impl Modifier<Obj> for Samples {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Fullscreen> for Obj {
        fn get(&self) -> Fullscreen { Fullscreen(false) }
    }

    impl Modifier<Obj> for Fullscreen {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<ExitOnEsc> for Obj {
        fn get(&self) -> ExitOnEsc { ExitOnEsc(true) }
    }

    impl Modifier<Obj> for ExitOnEsc {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<CaptureCursor> for Obj {
        fn get(&self) -> CaptureCursor { CaptureCursor(false) }
    }

    impl Modifier<Obj> for CaptureCursor {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<DrawSize> for Obj {
        fn get(&self) -> DrawSize { DrawSize([0, 0]) }
    }

    impl Modifier<Obj> for DrawSize {
        fn modify(self, _obj: &mut Obj) {}
    }

    fn foo<T: GetShouldClose + SetShouldClose
            + GetSize + SetSize
            + GetTitle + SetTitle
            + GetSamples + SetSamples
            + GetFullscreen + SetFullscreen
            + GetExitOnEsc + SetExitOnEsc
            + GetCaptureCursor + SetCaptureCursor
            + GetDrawSize + SetDrawSize>(_obj: T) {}

    foo(Obj);
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait Window<E = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose + SetShouldClose
  + GetSize
  + SetCaptureCursor
  + GetDrawSize
  + GetTitle + SetTitle
  + GetExitOnEsc + SetExitOnEsc {}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Modifier<NoWindow> for CaptureCursor {
    fn modify(self, _window: &mut NoWindow) {}
}

impl Modifier<NoWindow> for ShouldClose {
    fn modify(self, window: &mut NoWindow) {
        let ShouldClose(val) = self;
        window.should_close = val;
    }
}

impl Get<DrawSize> for NoWindow {
    fn get(&self) -> DrawSize {
        let Size(val) = self.get();
        DrawSize(val)
    }
}

impl Window<InputEvent> for NoWindow {}

impl Get<Title> for NoWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<NoWindow> for Title {
    fn modify(self, window: &mut NoWindow) {
        let Title(val) = self;
        window.title = val;
    }
}

impl Get<ExitOnEsc> for NoWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(false)
    }
}

impl Modifier<NoWindow> for ExitOnEsc {
    // Ignore attempt to exit by pressing Esc.
    fn modify(self, _window: &mut NoWindow) {}
}
<commit_msg>Auto implement Window trait<commit_after>#![deny(missing_docs)]
#![feature(globs)]
#![feature(default_type_params)]

//! Window abstraction

extern crate input;
extern crate current;
extern crate event_loop;

use input::InputEvent;
use current::{ Get, Modifier, Set };

// Reexport everything from event_loop.
pub use event_loop::*;

/// The title of the window.
pub struct Title(pub String);

/// Work-around trait for `Get<Title>`.
/// Used to support generic constraints.
pub trait GetTitle: Get<Title> {
    /// Returns the title of the window.
    fn get_title(&self) -> Title {
        self.get()
    }
}

impl<T: Get<Title>> GetTitle for T {}

/// Work-around trait for `Set<Title>`.
/// Used to support generic constraints.
pub trait SetTitle: Set<Title> {
    /// Sets title of window.
    fn set_title(&mut self, val: Title) {
        self.set_mut(val);
    }
}

impl<T: Set<Title>> SetTitle for T {}

/// The anti-aliasing samples when rendering.
pub struct Samples(pub u8);

/// Work-around trait for `Get<Samples>`.
/// Used to support generic constraints.
pub trait GetSamples: Get<Samples> {
    /// Returns the antialiasing samples when rendering.
    fn get_samples(&self) -> Samples {
        self.get()
    }
}

impl<T: Get<Samples>> GetSamples for T {}

/// Work-around trait for `Set<Samples>`.
/// Used to support generic constraints.
pub trait SetSamples: Set<Samples> {
    /// Sets antialiasing samples of window.
    fn set_samples(&mut self, val: Samples) {
        self.set_mut(val);
    }
}

impl<T: Set<Samples>> SetSamples for T {}

/// Whether window is opened in full screen mode.
pub struct Fullscreen(pub bool);

/// Work-around trait for `Get<Fullscreen>`.
/// Used to support generic constraints.
pub trait GetFullscreen: Get<Fullscreen> {
    /// Returns whether window is in full screen mode.
    fn get_fullscreen(&self) -> Fullscreen {
        self.get()
    }
}

impl<T: Get<Fullscreen>> GetFullscreen for T {}

/// Work-around trait for `Set<Fullscreen>`.
/// Used to support generic constraints.
pub trait SetFullscreen: Set<Fullscreen> {
    /// Sets window to fullscreen mode.
    fn set_fullscreen(&mut self, val: Fullscreen) {
        self.set_mut(val);
    }
}

impl<T: Set<Fullscreen>> SetFullscreen for T {}

/// Whether to exit when pressing the Esc keyboard button.
pub struct ExitOnEsc(pub bool);

/// Work-around trait for `Get<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait GetExitOnEsc: Get<ExitOnEsc> {
    /// Returns whether window exits when pressing Esc.
    fn get_exit_on_esc(&self) -> ExitOnEsc {
        self.get()
    }
}

impl<T: Get<ExitOnEsc>> GetExitOnEsc for T {}

/// Work-around trait for `Set<ExitOnEsc>`.
/// Used to support generic constraints.
pub trait SetExitOnEsc: Set<ExitOnEsc> {
    /// Sets exit when pressing Esc.
    fn set_exit_on_esc(&mut self, val: ExitOnEsc) {
        self.set_mut(val);
    }
}

impl<T: Set<ExitOnEsc>> SetExitOnEsc for T {}

/// Whether to capture the mouse cursor.
pub struct CaptureCursor(pub bool);

/// Work-around trait for `Get<CaptureCursor>`.
/// Used to support generic constraints.
pub trait GetCaptureCursor: Get<CaptureCursor> {
    /// Returns whether window captures cursor.
    fn get_capture_cursor(&self) -> CaptureCursor {
        self.get()
    }
}

impl<T: Get<CaptureCursor>> GetCaptureCursor for T {}

/// Work-around trait for `Set<CaptureCursor>`.
/// Used to support generic constraints.
pub trait SetCaptureCursor: Set<CaptureCursor> {
    /// Sets capture cursor.
    fn set_capture_cursor(&mut self, val: CaptureCursor) {
        self.set_mut(val);
    }
}

impl<T: Set<CaptureCursor>> SetCaptureCursor for T {}

/// The draw size of the window.
pub struct DrawSize(pub [u32, ..2]);

/// Work-around trait for `Get<DrawSize>`.
/// Used to support generic constraints.
pub trait GetDrawSize: Get<DrawSize> {
    /// Returns the draw size of window.
    fn get_draw_size(&self) -> DrawSize {
        self.get()
    }
}

impl<T: Get<DrawSize>> GetDrawSize for T {}

/// Work-around trait for `Set<DrawSize>`.
/// Used to support generic constraints.
pub trait SetDrawSize: Set<DrawSize> {
    /// Sets draw size.
    fn set_draw_size(&mut self, val: DrawSize) {
        self.set_mut(val);
    }
}

impl<T: Set<DrawSize>> SetDrawSize for T {}

#[test]
fn test_methods() {
    use current::Modifier;

    struct Obj;

    impl Get<ShouldClose> for Obj {
        fn get(&self) -> ShouldClose { ShouldClose(false) }
    }

    impl Modifier<Obj> for ShouldClose {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Size> for Obj {
        fn get(&self) -> Size { Size([0, 0]) }
    }

    impl Modifier<Obj> for Size {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Title> for Obj {
        fn get(&self) -> Title { Title("hello".to_string()) }
    }

    impl Modifier<Obj> for Title {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Samples> for Obj {
        fn get(&self) -> Samples { Samples(0) }
    }

    impl Modifier<Obj> for Samples {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<Fullscreen> for Obj {
        fn get(&self) -> Fullscreen { Fullscreen(false) }
    }

    impl Modifier<Obj> for Fullscreen {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<ExitOnEsc> for Obj {
        fn get(&self) -> ExitOnEsc { ExitOnEsc(true) }
    }

    impl Modifier<Obj> for ExitOnEsc {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<CaptureCursor> for Obj {
        fn get(&self) -> CaptureCursor { CaptureCursor(false) }
    }

    impl Modifier<Obj> for CaptureCursor {
        fn modify(self, _obj: &mut Obj) {}
    }

    impl Get<DrawSize> for Obj {
        fn get(&self) -> DrawSize { DrawSize([0, 0]) }
    }

    impl Modifier<Obj> for DrawSize {
        fn modify(self, _obj: &mut Obj) {}
    }

    fn foo<T: GetShouldClose + SetShouldClose
            + GetSize + SetSize
            + GetTitle + SetTitle
            + GetSamples + SetSamples
            + GetFullscreen + SetFullscreen
            + GetExitOnEsc + SetExitOnEsc
            + GetCaptureCursor + SetCaptureCursor
            + GetDrawSize + SetDrawSize>(_obj: T) {}

    foo(Obj);
}

/// Settings for window behavior.
pub struct WindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window.
    pub size: [u32, ..2],
    /// Number samples per pixel (anti-aliasing).
    pub samples: u8,
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl WindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> WindowSettings {
        WindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            samples: 0,
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait Window<E = InputEvent>:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose + SetShouldClose
  + GetSize
  + SetCaptureCursor
  + GetDrawSize
  + GetTitle + SetTitle
  + GetExitOnEsc + SetExitOnEsc {}

impl<T:
    SwapBuffers
  + PollEvent<E>
  + GetShouldClose + SetShouldClose
  + GetSize
  + SetCaptureCursor
  + GetDrawSize
  + GetTitle + SetTitle
  + GetExitOnEsc + SetExitOnEsc,
    E> Window<E> for T {}

/// An implementation of Window that runs without a window at all.
pub struct NoWindow {
    should_close: bool,
    title: String,
}

#[test]
fn test_no_window() {
    fn foo<T: Window>() {}

    foo::<NoWindow>();
}

impl NoWindow {
    /// Returns a new `NoWindow`.
    pub fn new(settings: WindowSettings) -> NoWindow {
        let title = settings.title.clone();
        NoWindow {
            should_close: false,
            title: title,
        }
    }
}

impl SwapBuffers for NoWindow {
    fn swap_buffers(&mut self) {}
}

impl PollEvent<InputEvent> for NoWindow {
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

impl Get<ShouldClose> for NoWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.should_close)
    }
}

impl Get<Size> for NoWindow {
    fn get(&self) -> Size {
        Size([0, 0])
    }
}

impl Modifier<NoWindow> for CaptureCursor {
    fn modify(self, _window: &mut NoWindow) {}
}

impl Modifier<NoWindow> for ShouldClose {
    fn modify(self, window: &mut NoWindow) {
        let ShouldClose(val) = self;
        window.should_close = val;
    }
}

impl Get<DrawSize> for NoWindow {
    fn get(&self) -> DrawSize {
        let Size(val) = self.get();
        DrawSize(val)
    }
}

impl Get<Title> for NoWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<NoWindow> for Title {
    fn modify(self, window: &mut NoWindow) {
        let Title(val) = self;
        window.title = val;
    }
}

impl Get<ExitOnEsc> for NoWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(false)
    }
}

impl Modifier<NoWindow> for ExitOnEsc {
    // Ignore attempt to exit by pressing Esc.
    fn modify(self, _window: &mut NoWindow) {}
}
<|endoftext|>


<commit_before>#![feature(test)]

#![feature(plugin)]
#![plugin(clippy)]

extern crate test;
extern crate rand;

use rand::distributions::{IndependentSample, Range};

pub struct Settings<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    pub min_max_pos: Vec<(f32, f32)>,

    pub cr_min: f32,
    pub cr_max: f32,
    pub cr_change_probability: f32,

    pub f_min: f32,
    pub f_max: f32,
    pub f_change_probability: f32,

    pub pop_size: usize,
    pub rng: R,

    pub cost_function: F,
}

impl<F, R> Settings<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    pub fn min_max_rng(min_max_pos: Vec<(f32, f32)>, cost_function: F, rng: R) -> Settings<F, R> {
        // create settings for the algorithm
        Settings {
            min_max_pos: min_max_pos,

            cr_min: 0.0,
            cr_max: 1.0,
            cr_change_probability: 0.1,

            f_min: 0.1,
            f_max: 1.0,
            f_change_probability: 0.1,

            pop_size: 50,
            rng: rng,

            cost_function: cost_function,
        }
    }
}

impl<F> Settings<F, rand::XorShiftRng>
    where F: Fn(&[f32]) -> f32
{
    pub fn new(min_max_pos: Vec<(f32, f32)>, cost_function: F) -> Settings<F, rand::XorShiftRng> {
        Settings::min_max_rng(min_max_pos, cost_function, rand::weak_rng())
    }
}

#[derive(Clone,Debug)]
pub struct Individual {
    pos: Vec<f32>,
    // the lower, the better.
    cost: Option<f32>,

    // control parameters
    cr: f32,
    f: f32,
}

pub struct Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    // TODO use a single vector for curr and best and controlparameters?
    curr: Vec<Individual>,
    best: Vec<Individual>,

    settings: Settings<F, R>,

    // index of global best individual. Might be in best or in curr.
    best_idx: Option<usize>,

    // cost value of the global best individual, for quick access
    best_cost_cache: Option<f32>,
    dim: usize,
    between_popsize: Range<usize>,
    between_dim: Range<usize>,
    between_cr: Range<f32>,
    between_f: Range<f32>,

    pop_countdown: usize,
}

impl<F, R> Iterator for Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    type Item = f32;

    /// Returns the cost value of the current best
    fn next(&mut self) -> Option<f32> {
        if 0 == self.pop_countdown {
            // if the whole pop has been evaluated, evolve it to update positions.
            // this also copies curr to best, if better.
            self.update_best();
            self.update_positions();
            self.pop_countdown = self.curr.len();
        }

        // perform a single fitness evaluation
        self.pop_countdown -= 1;
        let curr = &mut self.curr[self.pop_countdown];

        let cost = (self.settings.cost_function)(&curr.pos);
        curr.cost = Some(cost);

        // see if we have improved the global best
        if self.best_cost_cache.is_none() || cost < self.best_cost_cache.unwrap() {
            self.best_cost_cache = Some(cost);
            self.best_idx = Some(self.pop_countdown);
        }

        self.best_cost_cache
    }
}

impl<F> Population<F, rand::XorShiftRng>
    where F: Fn(&[f32]) -> f32
{
    pub fn new(min_max_pos: Vec<(f32, f32)>, cost_function: F) -> Population<F, rand::XorShiftRng> {
        Population::from_settings(Settings::new(min_max_pos, cost_function))
    }
}

impl<F, R> Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    // Creates a new population based on the given settings.
    pub fn from_settings(s: Settings<F, R>) -> Population<F, R> {
        assert!(s.min_max_pos.len() >= 1,
                "need at least one element to optimize");

        // create a vector of randomly initialized individuals for current.
        let dim = s.min_max_pos.len();

        // Empty individual, with no cost value (yet)
        let dummy_individual = Individual {
            pos: vec![0.0; dim],
            cost: None,
            cr: 0.0,
            f: 0.0,
        };

        // creates all the empty individuals
        let mut pop = Population {
            curr: vec![dummy_individual.clone(); s.pop_size],
            best: vec![dummy_individual; s.pop_size],
            best_idx: None,
            best_cost_cache: None,
            dim: dim,
            pop_countdown: s.pop_size,
            between_popsize: Range::new(0, s.pop_size),
            between_dim: Range::new(0, dim),
            between_cr: Range::new(s.cr_min, s.cr_max),
            between_f: Range::new(s.f_min, s.f_max),
            settings: s,
        };

        for ind in &mut pop.curr {
            // init control parameters
            ind.cr = pop.between_cr.ind_sample(&mut pop.settings.rng);
            ind.f = pop.between_f.ind_sample(&mut pop.settings.rng);

            // random range for each dimension
            for d in 0..dim {
                let between_min_max = Range::new(pop.settings.min_max_pos[d].0,
                                                 pop.settings.min_max_pos[d].1);
                ind.pos[d] = between_min_max.ind_sample(&mut pop.settings.rng);
            }
        }

        pop
    }

    fn update_best(&mut self) {
        for i in 0..self.curr.len() {
            let curr = &mut self.curr[i];
            let best = &mut self.best[i];

            // we use <= here, so that the individual moves even if the cost
            // stays the same.
            if best.cost.is_none() || curr.cost.unwrap() <= best.cost.unwrap() {
                // replace individual's best. swap is *much* faster than clone.
                std::mem::swap(curr, best);
            }
        }
    }

    fn update_positions(&mut self) {
        let global_best_pos = &self.best[self.best_idx.unwrap()].pos;
        let rng = &mut self.settings.rng;
        for i in 0..self.curr.len() {
            let mut id1 = self.between_popsize.ind_sample(rng);
            while id1 == i {
                id1 = self.between_popsize.ind_sample(rng);
            }

            let mut id2 = self.between_popsize.ind_sample(rng);
            while id2 == i || id2 == id1 {
                id2 = self.between_popsize.ind_sample(rng);
            }

            let curr = &mut self.curr[i];
            let best = &self.best[i];

            // see "Self-Adapting Control Parameters in Differential Evolution:
            // A Comparative Study on Numerical Benchmark Problems"
            if rng.gen::<f32>() < self.settings.cr_change_probability {
                curr.cr = self.between_cr.ind_sample(rng);
            } else {
                curr.cr = best.cr;
            }
            if rng.gen::<f32>() < self.settings.f_change_probability {
                curr.f = self.between_f.ind_sample(rng);
            } else {
                curr.f = best.f;
            }

            let curr_pos = &mut curr.pos;
            let best_pos = &best.pos;
            let best1_pos = &self.best[id1].pos;
            let best2_pos = &self.best[id2].pos;

            let forced_mutation_dim = self.between_dim.ind_sample(rng);

            // This implements the DE/1/best/bin algorithm.
            for d in 0..self.dim {
                if d == forced_mutation_dim || rng.gen::<f32>() < curr.cr {
                    curr_pos[d] = global_best_pos[d] + curr.f * (best1_pos[d] - best2_pos[d]);
                } else {
                    curr_pos[d] = best_pos[d];
                }
            }

            // reset cost, has to be updated by the user.
            curr.cost = None;
        }
    }

    pub fn best(&self) -> Option<(f32, &[f32])> {
        if let Some(bi) = self.best_idx {
            let curr = &self.curr[bi];
            let best = &self.best[bi];

            if curr.cost.is_none() {
                return Some((best.cost.unwrap(), &best.pos));
            }
            if best.cost.is_none() {
                return Some((curr.cost.unwrap(), &curr.pos));
            }
            if curr.cost.unwrap() < best.cost.unwrap() {
                return Some((curr.cost.unwrap(), &curr.pos));
            }
            return Some((best.cost.unwrap(), &best.pos));
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate rand;
    use super::*;
    use test::Bencher;
    use rand::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, ChaChaRng};
    use rand::{OsRng, weak_rng};

    fn setup<F: Fn(&[f32]) -> f32, R: rand::Rng>(dim: usize, cost_fn: F, rng: R) -> Population<F, R> {
        let s = Settings::min_max_rng(vec![(-100.0, 100.0); dim], cost_fn, rng);
        Population::from_settings(s)
    }

    #[bench]
    fn bench_square_fitness_opt(b: &mut Bencher) {
        let rng: XorShiftRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_thread_rng(b: &mut Bencher) {
        let mut pop = setup(5, |_| 1.234, rand::thread_rng());
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_xor_shift(b: &mut Bencher) {
        let rng: XorShiftRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_chacha(b: &mut Bencher) {
        let rng: ChaChaRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_isaac(b: &mut Bencher) {
        let rng: IsaacRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_isaac64(b: &mut Bencher) {
        let rng: Isaac64Rng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_std(b: &mut Bencher) {
        let rng: StdRng = StdRng::new().unwrap();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_osrng(b: &mut Bencher) {
        let rng: OsRng = OsRng::new().unwrap();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_weak_rng(b: &mut Bencher) {
        let rng = weak_rng();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }
}
<commit_msg>Individual is no more public<commit_after>#![feature(test)]

#![feature(plugin)]
#![plugin(clippy)]

extern crate test;
extern crate rand;

use rand::distributions::{IndependentSample, Range};

pub struct Settings<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    pub min_max_pos: Vec<(f32, f32)>,

    pub cr_min: f32,
    pub cr_max: f32,
    pub cr_change_probability: f32,

    pub f_min: f32,
    pub f_max: f32,
    pub f_change_probability: f32,

    pub pop_size: usize,
    pub rng: R,

    pub cost_function: F,
}

impl<F, R> Settings<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    pub fn min_max_rng(min_max_pos: Vec<(f32, f32)>, cost_function: F, rng: R) -> Settings<F, R> {
        // create settings for the algorithm
        Settings {
            min_max_pos: min_max_pos,

            cr_min: 0.0,
            cr_max: 1.0,
            cr_change_probability: 0.1,

            f_min: 0.1,
            f_max: 1.0,
            f_change_probability: 0.1,

            pop_size: 50,
            rng: rng,

            cost_function: cost_function,
        }
    }
}

impl<F> Settings<F, rand::XorShiftRng>
    where F: Fn(&[f32]) -> f32
{
    pub fn new(min_max_pos: Vec<(f32, f32)>, cost_function: F) -> Settings<F, rand::XorShiftRng> {
        Settings::min_max_rng(min_max_pos, cost_function, rand::weak_rng())
    }
}

#[derive(Clone,Debug)]
struct Individual {
    pos: Vec<f32>,
    // the lower, the better.
    cost: Option<f32>,

    // control parameters
    cr: f32,
    f: f32,
}

pub struct Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    // TODO use a single vector for curr and best and controlparameters?
    curr: Vec<Individual>,
    best: Vec<Individual>,

    settings: Settings<F, R>,

    // index of global best individual. Might be in best or in curr.
    best_idx: Option<usize>,

    // cost value of the global best individual, for quick access
    best_cost_cache: Option<f32>,
    dim: usize,
    between_popsize: Range<usize>,
    between_dim: Range<usize>,
    between_cr: Range<f32>,
    between_f: Range<f32>,

    pop_countdown: usize,
}

impl<F, R> Iterator for Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    type Item = f32;

    /// Returns the cost value of the current best
    fn next(&mut self) -> Option<f32> {
        if 0 == self.pop_countdown {
            // if the whole pop has been evaluated, evolve it to update positions.
            // this also copies curr to best, if better.
            self.update_best();
            self.update_positions();
            self.pop_countdown = self.curr.len();
        }

        // perform a single fitness evaluation
        self.pop_countdown -= 1;
        let curr = &mut self.curr[self.pop_countdown];

        let cost = (self.settings.cost_function)(&curr.pos);
        curr.cost = Some(cost);

        // see if we have improved the global best
        if self.best_cost_cache.is_none() || cost < self.best_cost_cache.unwrap() {
            self.best_cost_cache = Some(cost);
            self.best_idx = Some(self.pop_countdown);
        }

        self.best_cost_cache
    }
}

impl<F> Population<F, rand::XorShiftRng>
    where F: Fn(&[f32]) -> f32
{
    pub fn new(min_max_pos: Vec<(f32, f32)>, cost_function: F) -> Population<F, rand::XorShiftRng> {
        Population::from_settings(Settings::new(min_max_pos, cost_function))
    }
}

impl<F, R> Population<F, R>
    where F: Fn(&[f32]) -> f32,
          R: rand::Rng
{
    // Creates a new population based on the given settings.
    pub fn from_settings(s: Settings<F, R>) -> Population<F, R> {
        assert!(s.min_max_pos.len() >= 1,
                "need at least one element to optimize");

        // create a vector of randomly initialized individuals for current.
        let dim = s.min_max_pos.len();

        // Empty individual, with no cost value (yet)
        let dummy_individual = Individual {
            pos: vec![0.0; dim],
            cost: None,
            cr: 0.0,
            f: 0.0,
        };

        // creates all the empty individuals
        let mut pop = Population {
            curr: vec![dummy_individual.clone(); s.pop_size],
            best: vec![dummy_individual; s.pop_size],
            best_idx: None,
            best_cost_cache: None,
            dim: dim,
            pop_countdown: s.pop_size,
            between_popsize: Range::new(0, s.pop_size),
            between_dim: Range::new(0, dim),
            between_cr: Range::new(s.cr_min, s.cr_max),
            between_f: Range::new(s.f_min, s.f_max),
            settings: s,
        };

        for ind in &mut pop.curr {
            // init control parameters
            ind.cr = pop.between_cr.ind_sample(&mut pop.settings.rng);
            ind.f = pop.between_f.ind_sample(&mut pop.settings.rng);

            // random range for each dimension
            for d in 0..dim {
                let between_min_max = Range::new(pop.settings.min_max_pos[d].0,
                                                 pop.settings.min_max_pos[d].1);
                ind.pos[d] = between_min_max.ind_sample(&mut pop.settings.rng);
            }
        }

        pop
    }

    fn update_best(&mut self) {
        for i in 0..self.curr.len() {
            let curr = &mut self.curr[i];
            let best = &mut self.best[i];

            // we use <= here, so that the individual moves even if the cost
            // stays the same.
            if best.cost.is_none() || curr.cost.unwrap() <= best.cost.unwrap() {
                // replace individual's best. swap is *much* faster than clone.
                std::mem::swap(curr, best);
            }
        }
    }

    fn update_positions(&mut self) {
        let global_best_pos = &self.best[self.best_idx.unwrap()].pos;
        let rng = &mut self.settings.rng;
        for i in 0..self.curr.len() {
            let mut id1 = self.between_popsize.ind_sample(rng);
            while id1 == i {
                id1 = self.between_popsize.ind_sample(rng);
            }

            let mut id2 = self.between_popsize.ind_sample(rng);
            while id2 == i || id2 == id1 {
                id2 = self.between_popsize.ind_sample(rng);
            }

            let curr = &mut self.curr[i];
            let best = &self.best[i];

            // see "Self-Adapting Control Parameters in Differential Evolution:
            // A Comparative Study on Numerical Benchmark Problems"
            if rng.gen::<f32>() < self.settings.cr_change_probability {
                curr.cr = self.between_cr.ind_sample(rng);
            } else {
                curr.cr = best.cr;
            }
            if rng.gen::<f32>() < self.settings.f_change_probability {
                curr.f = self.between_f.ind_sample(rng);
            } else {
                curr.f = best.f;
            }

            let curr_pos = &mut curr.pos;
            let best_pos = &best.pos;
            let best1_pos = &self.best[id1].pos;
            let best2_pos = &self.best[id2].pos;

            let forced_mutation_dim = self.between_dim.ind_sample(rng);

            // This implements the DE/1/best/bin algorithm.
            for d in 0..self.dim {
                if d == forced_mutation_dim || rng.gen::<f32>() < curr.cr {
                    curr_pos[d] = global_best_pos[d] + curr.f * (best1_pos[d] - best2_pos[d]);
                } else {
                    curr_pos[d] = best_pos[d];
                }
            }

            // reset cost, has to be updated by the user.
            curr.cost = None;
        }
    }

    pub fn best(&self) -> Option<(f32, &[f32])> {
        if let Some(bi) = self.best_idx {
            let curr = &self.curr[bi];
            let best = &self.best[bi];

            if curr.cost.is_none() {
                return Some((best.cost.unwrap(), &best.pos));
            }
            if best.cost.is_none() {
                return Some((curr.cost.unwrap(), &curr.pos));
            }
            if curr.cost.unwrap() < best.cost.unwrap() {
                return Some((curr.cost.unwrap(), &curr.pos));
            }
            return Some((best.cost.unwrap(), &best.pos));
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate rand;
    use super::*;
    use test::Bencher;
    use rand::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, ChaChaRng};
    use rand::{OsRng, weak_rng};

    fn setup<F: Fn(&[f32]) -> f32, R: rand::Rng>(dim: usize,
                                                 cost_fn: F,
                                                 rng: R)
                                                 -> Population<F, R> {
        let s = Settings::min_max_rng(vec![(-100.0, 100.0); dim], cost_fn, rng);
        Population::from_settings(s)
    }

    #[bench]
    fn bench_square_fitness_opt(b: &mut Bencher) {
        let rng: XorShiftRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_thread_rng(b: &mut Bencher) {
        let mut pop = setup(5, |_| 1.234, rand::thread_rng());
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_xor_shift(b: &mut Bencher) {
        let rng: XorShiftRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_chacha(b: &mut Bencher) {
        let rng: ChaChaRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_isaac(b: &mut Bencher) {
        let rng: IsaacRng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_isaac64(b: &mut Bencher) {
        let rng: Isaac64Rng = OsRng::new().unwrap().gen();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_std(b: &mut Bencher) {
        let rng: StdRng = StdRng::new().unwrap();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_osrng(b: &mut Bencher) {
        let rng: OsRng = OsRng::new().unwrap();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }

    #[bench]
    fn rand_weak_rng(b: &mut Bencher) {
        let rng = weak_rng();
        let mut pop = setup(5, |_| 1.234, rng);
        b.iter(|| pop.next());
    }
}
<|endoftext|>


<commit_before>/*!
This crate defines two functions, `memchr` and `memrchr`, which expose a safe interface
to the corresponding functions in `libc`.
*/

#![deny(missing_docs)]

extern crate libc;

use libc::funcs::c95::string;
use libc::types::common::c95::c_void;
use libc::types::os::arch::c95::{c_int, size_t};

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    let p = unsafe {
        string::memchr(
            haystack.as_ptr() as *const c_void,
            needle as c_int,
            haystack.len() as size_t)
    };
    if p.is_null() {
        None
    } else {
        Some(p as usize - (haystack.as_ptr() as usize))
    }
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
    if haystack.is_empty() {return None}
    let p = unsafe {
        ffi::memrchr(
            haystack.as_ptr() as *const c_void,
            needle as c_int,
            haystack.len() as size_t)
    };
    if p.is_null() {
        None
    } else {
        Some(p as usize - (haystack.as_ptr() as usize))
    }
}

mod ffi {
    use libc::types::common::c95::c_void;
    use libc::types::os::arch::c95::{c_int, size_t};
    extern {
        pub fn memrchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
    }
}

#[cfg(test)]
mod tests {
    extern crate quickcheck;

    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn qc_never_fail() {
        fn prop(needle: u8, haystack: Vec<u8>) -> bool {
            memchr(needle, &haystack); true
        }
        quickcheck::quickcheck(prop as fn(u8, Vec<u8>) -> bool);
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }

    #[test]
    fn qc_never_fail_reversed() {
        fn prop(needle: u8, haystack: Vec<u8>) -> bool {
            memrchr(needle, &haystack); true
        }
        quickcheck::quickcheck(prop as fn(u8, Vec<u8>) -> bool);
    }
}
<commit_msg>Only compile optimized version of memrchr on linux.<commit_after>/*!
This crate defines two functions, `memchr` and `memrchr`, which expose a safe interface
to the corresponding functions in `libc`.
*/

#![deny(missing_docs)]

extern crate libc;

use libc::funcs::c95::string;
use libc::types::common::c95::c_void;
use libc::types::os::arch::c95::{c_int, size_t};

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    let p = unsafe {
        string::memchr(
            haystack.as_ptr() as *const c_void,
            needle as c_int,
            haystack.len() as size_t)
    };
    if p.is_null() {
        None
    } else {
        Some(p as usize - (haystack.as_ptr() as usize))
    }
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            ffi::memrchr(
                haystack.as_ptr() as *const c_void,
                needle as c_int,
                haystack.len() as size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        haystack.iter().rposition(|&b| b == needle)
    }

    memrchr_specific(needle, haystack)
}

#[cfg(target_os = "linux")]
mod ffi {
    use libc::types::common::c95::c_void;
    use libc::types::os::arch::c95::{c_int, size_t};
    extern {
        pub fn memrchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
    }
}

#[cfg(test)]
mod tests {
    extern crate quickcheck;

    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn qc_never_fail() {
        fn prop(needle: u8, haystack: Vec<u8>) -> bool {
            memchr(needle, &haystack); true
        }
        quickcheck::quickcheck(prop as fn(u8, Vec<u8>) -> bool);
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }

    #[test]
    fn qc_never_fail_reversed() {
        fn prop(needle: u8, haystack: Vec<u8>) -> bool {
            memrchr(needle, &haystack); true
        }
        quickcheck::quickcheck(prop as fn(u8, Vec<u8>) -> bool);
    }
}
<|endoftext|>


<commit_before>// (c) 2015-2016 Joost Yervante Damad <joost@damad.be>

use std::fmt;
use std::fs::File;
use std::io::Read;

extern crate rustysexp;
use rustysexp::Sexp;
use rustysexp::Atom;

type ERes<T> = Result<T, String>;

fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

pub struct Module {
    name: String,
    elements: Vec<Element>
}

impl Module {
    fn new(name: &String) -> Module {
        Module { name: name.clone(), elements: vec![] }
    }
    fn append(&mut self, e: Element) {
        self.elements.push(e)
    }
}

impl fmt::Display for Module {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(write!(f, "(module {}\n", self.name));
        for e in &self.elements {
            try!(write!(f, "{}\n", e))
        };
        write!(f, ")")
    }
}

pub enum Element {
    Layer(String),
    Descr(String),
    FpText(FpText),
    Pad,
    FpPoly,
    FpLine,
    FpCircle
}

impl fmt::Display for Element {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Element::Layer(ref s) => write!(f, "(layer {})", s),
            Element::Descr(ref s) => write!(f, "(descr \"{}\")", s),
            Element::FpText(ref p) => write!(f, "{}", p),
            Element::Pad => write!(f, "(pad)"),
            Element::FpPoly => write!(f, "(fp_poly)"),
            Element::FpLine => write!(f, "(fp_line)"),
            Element::FpCircle => write!(f, "(fp_circle)"),
        }
    }
}

pub struct FpText {
    name: String,
    value: String,
    at: At,
    layer: String,
    effects: Effects,
    hide: bool,
}

impl FpText {
    fn new(name: &String, value: &String) -> FpText {
        FpText {
            name: name.clone(),
            value: value.clone(),
            at: At::new(0.,0.,0.),
            layer: String::from("cow"),
            effects: Effects::new(),
            hide: false
        }
    }
}

impl fmt::Display for FpText {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(fp_text {} \"{}\" {} (layer {}) {})", self.name, self.value, self.at, self.layer, self.effects)
    }
}

pub struct At {
    x: f64,
    y: f64,
    rot: f64
}

impl At {
    fn new(x:f64 ,y:f64, rot:f64) -> At {
        At { x:x, y:y, rot:rot }
    }
}

impl fmt::Display for At {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(at {} {} {})", self.x, self.y, self.rot)
    }
}

pub struct Effects {
    todo: String
}

impl Effects {
    fn new() -> Effects {
        Effects { todo: String::from("todo") }
    }
}

impl fmt::Display for Effects {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(effects)")
    }
}

fn parse_layer(v: &Vec<Sexp>) -> ERes<Element> {
    match v[1] {
        Sexp::Atom(Atom::S(ref s)) => {
            Ok(Element::Layer(s.clone()))
        }
        ref x => Err(format!("unexpected element in layer: {}", x))
    }
}

fn parse_descr(v: &Vec<Sexp>) -> ERes<Element> {
    match v[1] {
        Sexp::Atom(Atom::Q(ref s)) => {
            Ok(Element::Descr(s.clone()))
        }
        ref x => Err(format!("unexpected element in descr: {}", x))
    }
}
fn parse_fp_text(v: &Vec<Sexp>) -> ERes<Element> {
    let name = try!(match v[1] {
        Sexp::Atom(Atom::S(ref s)) => Ok(s),
        ref x => err("expecting name for fp_text")
    });
    let value = try!(match v[2] {
        Sexp::Atom(Atom::Q(ref s)) => Ok(s),
        ref x => err("expecting value for fp_text")
    });
    let mut fp = FpText::new(name, value);
    for e in &v[3..] {
    }
    Ok(Element::FpText(fp))
}
fn parse_pad(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::Pad)
}
fn parse_fp_poly(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpPoly)
}
fn parse_fp_line(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpLine)
}
fn parse_fp_circle(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpCircle)
}

fn parse_element_list(v: &Vec<Sexp>) -> ERes<Element> {
    match v[0] {
        Sexp::Atom(Atom::S(ref s)) => {
            match &s[..] {
                "layer" => parse_layer(v),
                "descr" => parse_descr(v),
                "fp_text" => parse_fp_text(v),
                "pad" => parse_pad(v),
                "fp_poly" => parse_fp_poly(v),
                "fp_line" => parse_fp_line(v),
                "fp_circle" => parse_fp_circle(v),
                x => Err(format!("unknown element in module: {}", x))
            }
        }
        _ => err("expecting atom")
    }
}

fn parse_element(s: &Sexp) -> ERes<Element> {
    match *s {
        Sexp::List(ref v) => parse_element_list(&v),
        _ => err("expecting element list in module")
    }
}

fn parse_module_list(v: &Vec<Sexp>) -> ERes<Module> {
    let mut module = (match v[0] {
        Sexp::Atom(Atom::S(ref s)) if s == "module" => {
            match v[1] {
                Sexp::Atom(Atom::S(ref s)) => {
                    Ok(Module::new(s))
                }
                ref x => return Err(format!("expecting module name got {}", x))
            }
        }
        _ => err("expecting module")
    }).unwrap();
    for e in &v[2..] {
        let el = try!(parse_element(e));
        module.append(el)
    }
    Ok(module)
}

fn parse_module(s: Sexp) -> ERes<Module> {
    match s {
        Sexp::List(v) => parse_module_list(&v),
        _ => err("expecting top level list")
    }
}

fn parse(s: &str) -> ERes<Module> {
    match rustysexp::parse_str(s) {
        Ok(s) => parse_module(s),
        Err(x) => Err(format!("IOError: {}", x))
    }
}

fn read_file(name: &str) -> Result<String,std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> Module {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Module {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

<commit_msg>derive(Debug)<commit_after>// (c) 2015-2016 Joost Yervante Damad <joost@damad.be>

use std::fmt;
use std::fs::File;
use std::io::Read;

extern crate rustysexp;
use rustysexp::Sexp;
use rustysexp::Atom;

type ERes<T> = Result<T, String>;

fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

#[derive(Debug)]
pub struct Module {
    name: String,
    elements: Vec<Element>
}

impl Module {
    fn new(name: &String) -> Module {
        Module { name: name.clone(), elements: vec![] }
    }
    fn append(&mut self, e: Element) {
        self.elements.push(e)
    }
}

impl fmt::Display for Module {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        try!(write!(f, "(module {}\n", self.name));
        for e in &self.elements {
            try!(write!(f, "{}\n", e))
        };
        write!(f, ")")
    }
}

#[derive(Debug)]
pub enum Element {
    Layer(String),
    Descr(String),
    FpText(FpText),
    Pad,
    FpPoly,
    FpLine,
    FpCircle
}

impl fmt::Display for Element {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Element::Layer(ref s) => write!(f, "(layer {})", s),
            Element::Descr(ref s) => write!(f, "(descr \"{}\")", s),
            Element::FpText(ref p) => write!(f, "{}", p),
            Element::Pad => write!(f, "(pad)"),
            Element::FpPoly => write!(f, "(fp_poly)"),
            Element::FpLine => write!(f, "(fp_line)"),
            Element::FpCircle => write!(f, "(fp_circle)"),
        }
    }
}

#[derive(Debug)]
pub struct FpText {
    name: String,
    value: String,
    at: At,
    layer: String,
    effects: Effects,
    hide: bool,
}

impl FpText {
    fn new(name: &String, value: &String) -> FpText {
        FpText {
            name: name.clone(),
            value: value.clone(),
            at: At::new(0.,0.,0.),
            layer: String::from("cow"),
            effects: Effects::new(),
            hide: false
        }
    }
}

impl fmt::Display for FpText {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(fp_text {} \"{}\" {} (layer {}) {})", self.name, self.value, self.at, self.layer, self.effects)
    }
}

#[derive(Debug)]
pub struct At {
    x: f64,
    y: f64,
    rot: f64
}

impl At {
    fn new(x:f64 ,y:f64, rot:f64) -> At {
        At { x:x, y:y, rot:rot }
    }
}

impl fmt::Display for At {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(at {} {} {})", self.x, self.y, self.rot)
    }
}

#[derive(Debug)]
pub struct Effects {
    todo: String
}

impl Effects {
    fn new() -> Effects {
        Effects { todo: String::from("todo") }
    }
}

impl fmt::Display for Effects {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "(effects)")
    }
}

fn parse_layer(v: &Vec<Sexp>) -> ERes<Element> {
    match v[1] {
        Sexp::Atom(Atom::S(ref s)) => {
            Ok(Element::Layer(s.clone()))
        }
        ref x => Err(format!("unexpected element in layer: {}", x))
    }
}

fn parse_descr(v: &Vec<Sexp>) -> ERes<Element> {
    match v[1] {
        Sexp::Atom(Atom::Q(ref s)) => {
            Ok(Element::Descr(s.clone()))
        }
        ref x => Err(format!("unexpected element in descr: {}", x))
    }
}
fn parse_fp_text(v: &Vec<Sexp>) -> ERes<Element> {
    let name = try!(match v[1] {
        Sexp::Atom(Atom::S(ref s)) => Ok(s),
        ref x => err("expecting name for fp_text")
    });
    let value = try!(match v[2] {
        Sexp::Atom(Atom::Q(ref s)) => Ok(s),
        ref x => err("expecting value for fp_text")
    });
    let mut fp = FpText::new(name, value);
    for e in &v[3..] {
    }
    Ok(Element::FpText(fp))
}
fn parse_pad(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::Pad)
}
fn parse_fp_poly(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpPoly)
}
fn parse_fp_line(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpLine)
}
fn parse_fp_circle(v: &Vec<Sexp>) -> ERes<Element> {
    Ok(Element::FpCircle)
}

fn parse_element_list(v: &Vec<Sexp>) -> ERes<Element> {
    match v[0] {
        Sexp::Atom(Atom::S(ref s)) => {
            match &s[..] {
                "layer" => parse_layer(v),
                "descr" => parse_descr(v),
                "fp_text" => parse_fp_text(v),
                "pad" => parse_pad(v),
                "fp_poly" => parse_fp_poly(v),
                "fp_line" => parse_fp_line(v),
                "fp_circle" => parse_fp_circle(v),
                x => Err(format!("unknown element in module: {}", x))
            }
        }
        _ => err("expecting atom")
    }
}

fn parse_element(s: &Sexp) -> ERes<Element> {
    match *s {
        Sexp::List(ref v) => parse_element_list(&v),
        _ => err("expecting element list in module")
    }
}

fn parse_module_list(v: &Vec<Sexp>) -> ERes<Module> {
    let mut module = (match v[0] {
        Sexp::Atom(Atom::S(ref s)) if s == "module" => {
            match v[1] {
                Sexp::Atom(Atom::S(ref s)) => {
                    Ok(Module::new(s))
                }
                ref x => return Err(format!("expecting module name got {}", x))
            }
        }
        _ => err("expecting module")
    }).unwrap();
    for e in &v[2..] {
        let el = try!(parse_element(e));
        module.append(el)
    }
    Ok(module)
}

fn parse_module(s: Sexp) -> ERes<Module> {
    match s {
        Sexp::List(v) => parse_module_list(&v),
        _ => err("expecting top level list")
    }
}

fn parse(s: &str) -> ERes<Module> {
    match rustysexp::parse_str(s) {
        Ok(s) => parse_module(s),
        Err(x) => Err(format!("IOError: {}", x))
    }
}

fn read_file(name: &str) -> Result<String,std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> Module {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Module {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

<|endoftext|>