<commit_before>extern crate bigint;
extern crate bn;
extern crate sputnikvm;

use std::rc::Rc;
use bigint::{Gas, U256};

use sputnikvm::Precompiled;
use sputnikvm::errors::{OnChainError, RuntimeError, NotSupportedError};

pub struct Bn128AddPrecompiled;
impl Precompiled for Bn128AddPrecompiled {
    fn gas_and_step(&self, data: &[u8], gas_limit: Gas) -> Result<(Gas, Rc<Vec<u8>>), RuntimeError> {
        use bn::{G1, AffineG1, Fq, Group};

        let gas = Gas::from(500usize);
        if gas > gas_limit {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        // Padding data to be at least 32 * 4 bytes.
        let mut data: Vec<u8> = data.into();
        while data.len() < 32 * 4 {
            data.push(0);
        }

        let px = Fq::from_slice(&data[0..32])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let py = Fq::from_slice(&data[32..64])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let qx = Fq::from_slice(&data[64..96])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let qy = Fq::from_slice(&data[96..128])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;

        let p = if px == Fq::zero() && py == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(px, py).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };
        let q = if qx == Fq::zero() && qy == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(qx, qy).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };

        let mut output = vec![0u8; 64];
        if let Some(ret) = AffineG1::from_jacobian(p + q) {
            ret.x().to_big_endian(&mut output[0..32]).unwrap();
            ret.y().to_big_endian(&mut output[32..64]).unwrap();
        }

        Ok((gas, Rc::new(output)))
    }
}

pub struct Bn128MulPrecompiled;
impl Precompiled for Bn128MulPrecompiled {
    fn gas_and_step(&self, data: &[u8], gas_limit: Gas) -> Result<(Gas, Rc<Vec<u8>>), RuntimeError> {
        use bn::{G1, AffineG1, Fq, Fr, Group};

        let gas = Gas::from(40000usize);
        if gas > gas_limit {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        // Padding data to be at least 32 * 4 bytes.
        let mut data: Vec<u8> = data.into();
        while data.len() < 32 * 3 {
            data.push(0);
        }

        let px = Fq::from_slice(&data[0..32])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let py = Fq::from_slice(&data[32..64])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let fr = Fr::from_slice(&data[64..96])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;

        let p = if px == Fq::zero() && py == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(px, py).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };

        let mut output = vec![0u8; 64];
        if let Some(ret) = AffineG1::from_jacobian(p * fr) {
            ret.x().to_big_endian(&mut output[0..32]).unwrap();
            ret.y().to_big_endian(&mut output[32..64]).unwrap();
        };

        Ok((gas, Rc::new(output)))
    }
}
<commit_msg>EIP197 implementation<commit_after>extern crate bigint;
extern crate bn;
extern crate sputnikvm;

use std::rc::Rc;
use bigint::{Gas, U256};

use sputnikvm::Precompiled;
use sputnikvm::errors::{OnChainError, RuntimeError, NotSupportedError};

pub struct Bn128AddPrecompiled;
impl Precompiled for Bn128AddPrecompiled {
    fn gas_and_step(&self, data: &[u8], gas_limit: Gas) -> Result<(Gas, Rc<Vec<u8>>), RuntimeError> {
        use bn::{G1, AffineG1, Fq, Group};

        let gas = Gas::from(500usize);
        if gas > gas_limit {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        // Padding data to be at least 32 * 4 bytes.
        let mut data: Vec<u8> = data.into();
        while data.len() < 32 * 4 {
            data.push(0);
        }

        let px = Fq::from_slice(&data[0..32])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let py = Fq::from_slice(&data[32..64])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let qx = Fq::from_slice(&data[64..96])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let qy = Fq::from_slice(&data[96..128])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;

        let p = if px == Fq::zero() && py == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(px, py).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };
        let q = if qx == Fq::zero() && qy == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(qx, qy).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };

        let mut output = vec![0u8; 64];
        if let Some(ret) = AffineG1::from_jacobian(p + q) {
            ret.x().to_big_endian(&mut output[0..32]).unwrap();
            ret.y().to_big_endian(&mut output[32..64]).unwrap();
        }

        Ok((gas, Rc::new(output)))
    }
}

pub struct Bn128MulPrecompiled;
impl Precompiled for Bn128MulPrecompiled {
    fn gas_and_step(&self, data: &[u8], gas_limit: Gas) -> Result<(Gas, Rc<Vec<u8>>), RuntimeError> {
        use bn::{G1, AffineG1, Fq, Fr, Group};

        let gas = Gas::from(40000usize);
        if gas > gas_limit {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        // Padding data to be at least 32 * 4 bytes.
        let mut data: Vec<u8> = data.into();
        while data.len() < 32 * 3 {
            data.push(0);
        }

        let px = Fq::from_slice(&data[0..32])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let py = Fq::from_slice(&data[32..64])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
        let fr = Fr::from_slice(&data[64..96])
            .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;

        let p = if px == Fq::zero() && py == Fq::zero() {
            G1::zero()
        } else {
            AffineG1::new(px, py).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
        };

        let mut output = vec![0u8; 64];
        if let Some(ret) = AffineG1::from_jacobian(p * fr) {
            ret.x().to_big_endian(&mut output[0..32]).unwrap();
            ret.y().to_big_endian(&mut output[32..64]).unwrap();
        };

        Ok((gas, Rc::new(output)))
    }
}

pub struct Bn128PairingPrecompiled;
impl Precompiled for Bn128PairingPrecompiled {
    fn gas_and_step(&self, data: &[u8], gas_limit: Gas) -> Result<(Gas, Rc<Vec<u8>>), RuntimeError> {
        use bn::{G1, AffineG1, Fq, Group, pairing, Gt, G2, Fq2, AffineG2};

        fn read_one(s: &[u8]) -> Result<(G1, G2), RuntimeError> {
            let ax = Fq::from_slice(&s[0..32])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
            let ay = Fq::from_slice(&s[32..64])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
            let bay = Fq::from_slice(&s[64..96])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
            let bax = Fq::from_slice(&s[96..128])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
            let bby = Fq::from_slice(&s[128..160])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;
            let bbx = Fq::from_slice(&s[160..192])
                .map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?;

            let ba = Fq2::new(bax, bay);
            let bb = Fq2::new(bbx, bby);

            let b = if ba.is_zero() && bb.is_zero() {
                G2::zero()
            } else {
                AffineG2::new(ba, bb).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
            };
            let a = if ax.is_zero() && ay.is_zero() {
                G1::zero()
            } else {
                AffineG1::new(ax, ay).map_err(|_| RuntimeError::OnChain(OnChainError::EmptyGas))?.into()
            };

            Ok((a, b))
        }

        if data.len() % 192 != 0 {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        let ele_len = data.len() / 192;
        let gas = Gas::from(80000usize) * Gas::from(ele_len) + Gas::from(100000usize);
        if gas > gas_limit {
            return Err(RuntimeError::OnChain(OnChainError::EmptyGas));
        }

        let mut acc = Gt::one();
        for i in 0..ele_len {
            let (a, b) = read_one(&data[i*192..i*192+192])?;
            acc = acc * pairing(a, b);
        }

        let result = if acc == Gt::one() {
            U256::from(1)
        } else {
            U256::zero()
        };

        let mut output = vec![0u8; 32];
        result.to_big_endian(&mut output);

        Ok((gas, Rc::new(output)))
    }
}
<|endoftext|>


<commit_before>//! Densely numbered entity references as mapping keys.
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::slice;
use std::vec::Vec;
use {EntityRef, Iter, IterMut, Keys};

/// A primary mapping `K -> V` allocating dense entity references.
///
/// The `PrimaryMap` data structure uses the dense index space to implement a map with a vector.
///
/// A primary map contains the main definition of an entity, and it can be used to allocate new
/// entity references with the `push` method.
///
/// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise
/// conflicting references will be created. Using unknown keys for indexing will cause a panic.
///
/// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow
/// `&PrimaryMap<K, V>` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is
/// that it only allows indexing with the distinct `EntityRef` key type, so converting to a
/// plain slice would make it easier to use incorrectly.
#[derive(Debug, Clone)]
pub struct PrimaryMap<K, V>
where
    K: EntityRef,
{
    elems: Vec<V>,
    unused: PhantomData<K>,
}

impl<K, V> PrimaryMap<K, V>
where
    K: EntityRef,
{
    /// Create a new empty map.
    pub fn new() -> Self {
        Self {
            elems: Vec::new(),
            unused: PhantomData,
        }
    }

    /// Check if `k` is a valid key in the map.
    pub fn is_valid(&self, k: K) -> bool {
        k.index() < self.elems.len()
    }

    /// Get the element at `k` if it exists.
    pub fn get(&self, k: K) -> Option<&V> {
        self.elems.get(k.index())
    }

    /// Get the element at `k` if it exists, mutable version.
    pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
        self.elems.get_mut(k.index())
    }

    /// Is this map completely empty?
    pub fn is_empty(&self) -> bool {
        self.elems.is_empty()
    }

    /// Get the total number of entity references created.
    pub fn len(&self) -> usize {
        self.elems.len()
    }

    /// Iterate over all the keys in this map.
    pub fn keys(&self) -> Keys<K> {
        Keys::with_len(self.elems.len())
    }

    /// Iterate over all the values in this map.
    pub fn values(&self) -> slice::Iter<V> {
        self.elems.iter()
    }

    /// Iterate over all the values in this map, mutable edition.
    pub fn values_mut(&mut self) -> slice::IterMut<V> {
        self.elems.iter_mut()
    }

    /// Iterate over all the keys and values in this map.
    pub fn iter(&self) -> Iter<K, V> {
        Iter::new(self.elems.iter())
    }

    /// Iterate over all the keys and values in this map, mutable edition.
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        IterMut::new(self.elems.iter_mut())
    }

    /// Remove all entries from this map.
    pub fn clear(&mut self) {
        self.elems.clear()
    }

    /// Get the key that will be assigned to the next pushed value.
    pub fn next_key(&self) -> K {
        K::new(self.elems.len())
    }

    /// Append `v` to the mapping, assigning a new key which is returned.
    pub fn push(&mut self, v: V) -> K {
        let k = self.next_key();
        self.elems.push(v);
        k
    }

    /// Returns the last element that was inserted in the map.
    pub fn last(&self) -> Option<&V> {
        self.elems.last()
    }

    /// Reserves capacity for at least `additional` more elements to be inserted.
    pub fn reserve(&mut self, additional: usize) {
        self.elems.reserve(additional)
    }

    /// Reserves the minimum capacity for exactly `additional` more elements to be inserted.
    pub fn reserve_exact(&mut self, additional: usize) {
        self.elems.reserve_exact(additional)
    }
}

/// Immutable indexing into an `PrimaryMap`.
/// The indexed value must be in the map.
impl<K, V> Index<K> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Output = V;

    fn index(&self, k: K) -> &V {
        &self.elems[k.index()]
    }
}

/// Mutable indexing into an `PrimaryMap`.
impl<K, V> IndexMut<K> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    fn index_mut(&mut self, k: K) -> &mut V {
        &mut self.elems[k.index()]
    }
}

impl<'a, K, V> IntoIterator for &'a PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;

    fn into_iter(self) -> Self::IntoIter {
        Iter::new(self.elems.iter())
    }
}

impl<'a, K, V> IntoIterator for &'a mut PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;

    fn into_iter(self) -> Self::IntoIter {
        IterMut::new(self.elems.iter_mut())
    }
}

impl<K, V> FromIterator<V> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    fn from_iter<T>(iter: T) -> Self
    where
        T: IntoIterator<Item = V>,
    {
        Self {
            elems: Vec::from_iter(iter),
            unused: PhantomData,
        }
    }
}

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

    // `EntityRef` impl for testing.
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    struct E(u32);

    impl EntityRef for E {
        fn new(i: usize) -> Self {
            E(i as u32)
        }
        fn index(self) -> usize {
            self.0 as usize
        }
    }

    #[test]
    fn basic() {
        let r0 = E(0);
        let r1 = E(1);
        let m = PrimaryMap::<E, isize>::new();

        let v: Vec<E> = m.keys().collect();
        assert_eq!(v, []);

        assert!(!m.is_valid(r0));
        assert!(!m.is_valid(r1));
    }

    #[test]
    fn push() {
        let mut m = PrimaryMap::new();
        let k0: E = m.push(12);
        let k1 = m.push(33);

        assert_eq!(m[k0], 12);
        assert_eq!(m[k1], 33);

        let v: Vec<E> = m.keys().collect();
        assert_eq!(v, [k0, k1]);
    }

    #[test]
    fn iter() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for (key, value) in &m {
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
            i += 1;
        }
        i = 0;
        for (key_mut, value_mut) in m.iter_mut() {
            assert_eq!(key_mut.index(), i);
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
            i += 1;
        }
    }

    #[test]
    fn iter_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for (key, value) in m.iter().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }

        i = 2;
        for (key, value) in m.iter_mut().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }
    }
    #[test]
    fn keys() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for key in m.keys() {
            assert_eq!(key.index(), i);
            i += 1;
        }
    }

    #[test]
    fn keys_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for key in m.keys().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
        }
    }

    #[test]
    fn values() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for value in m.values() {
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
            i += 1;
        }
        i = 0;
        for value_mut in m.values_mut() {
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
            i += 1;
        }
    }

    #[test]
    fn values_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for value in m.values().rev() {
            i -= 1;
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }
        i = 2;
        for value_mut in m.values_mut().rev() {
            i -= 1;
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
        }
    }

    fn from_iter() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);
        let n = m.values().collect::<PrimaryMap<E, _>>();
        assert!(m.len() == n.len());
        for (me, ne) in m.values().zip(n.values()) {
            assert!(*me == **ne);
        }
    }
}
<commit_msg>Implement `PrimaryMap::with_capacity`.<commit_after>//! Densely numbered entity references as mapping keys.
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::slice;
use std::vec::Vec;
use {EntityRef, Iter, IterMut, Keys};

/// A primary mapping `K -> V` allocating dense entity references.
///
/// The `PrimaryMap` data structure uses the dense index space to implement a map with a vector.
///
/// A primary map contains the main definition of an entity, and it can be used to allocate new
/// entity references with the `push` method.
///
/// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise
/// conflicting references will be created. Using unknown keys for indexing will cause a panic.
///
/// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow
/// `&PrimaryMap<K, V>` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is
/// that it only allows indexing with the distinct `EntityRef` key type, so converting to a
/// plain slice would make it easier to use incorrectly.
#[derive(Debug, Clone)]
pub struct PrimaryMap<K, V>
where
    K: EntityRef,
{
    elems: Vec<V>,
    unused: PhantomData<K>,
}

impl<K, V> PrimaryMap<K, V>
where
    K: EntityRef,
{
    /// Create a new empty map.
    pub fn new() -> Self {
        Self {
            elems: Vec::new(),
            unused: PhantomData,
        }
    }

    /// Create a new empty map with the given capacity.
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            elems: Vec::with_capacity(capacity),
            unused: PhantomData,
        }
    }

    /// Check if `k` is a valid key in the map.
    pub fn is_valid(&self, k: K) -> bool {
        k.index() < self.elems.len()
    }

    /// Get the element at `k` if it exists.
    pub fn get(&self, k: K) -> Option<&V> {
        self.elems.get(k.index())
    }

    /// Get the element at `k` if it exists, mutable version.
    pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
        self.elems.get_mut(k.index())
    }

    /// Is this map completely empty?
    pub fn is_empty(&self) -> bool {
        self.elems.is_empty()
    }

    /// Get the total number of entity references created.
    pub fn len(&self) -> usize {
        self.elems.len()
    }

    /// Iterate over all the keys in this map.
    pub fn keys(&self) -> Keys<K> {
        Keys::with_len(self.elems.len())
    }

    /// Iterate over all the values in this map.
    pub fn values(&self) -> slice::Iter<V> {
        self.elems.iter()
    }

    /// Iterate over all the values in this map, mutable edition.
    pub fn values_mut(&mut self) -> slice::IterMut<V> {
        self.elems.iter_mut()
    }

    /// Iterate over all the keys and values in this map.
    pub fn iter(&self) -> Iter<K, V> {
        Iter::new(self.elems.iter())
    }

    /// Iterate over all the keys and values in this map, mutable edition.
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        IterMut::new(self.elems.iter_mut())
    }

    /// Remove all entries from this map.
    pub fn clear(&mut self) {
        self.elems.clear()
    }

    /// Get the key that will be assigned to the next pushed value.
    pub fn next_key(&self) -> K {
        K::new(self.elems.len())
    }

    /// Append `v` to the mapping, assigning a new key which is returned.
    pub fn push(&mut self, v: V) -> K {
        let k = self.next_key();
        self.elems.push(v);
        k
    }

    /// Returns the last element that was inserted in the map.
    pub fn last(&self) -> Option<&V> {
        self.elems.last()
    }

    /// Reserves capacity for at least `additional` more elements to be inserted.
    pub fn reserve(&mut self, additional: usize) {
        self.elems.reserve(additional)
    }

    /// Reserves the minimum capacity for exactly `additional` more elements to be inserted.
    pub fn reserve_exact(&mut self, additional: usize) {
        self.elems.reserve_exact(additional)
    }
}

/// Immutable indexing into an `PrimaryMap`.
/// The indexed value must be in the map.
impl<K, V> Index<K> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Output = V;

    fn index(&self, k: K) -> &V {
        &self.elems[k.index()]
    }
}

/// Mutable indexing into an `PrimaryMap`.
impl<K, V> IndexMut<K> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    fn index_mut(&mut self, k: K) -> &mut V {
        &mut self.elems[k.index()]
    }
}

impl<'a, K, V> IntoIterator for &'a PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;

    fn into_iter(self) -> Self::IntoIter {
        Iter::new(self.elems.iter())
    }
}

impl<'a, K, V> IntoIterator for &'a mut PrimaryMap<K, V>
where
    K: EntityRef,
{
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;

    fn into_iter(self) -> Self::IntoIter {
        IterMut::new(self.elems.iter_mut())
    }
}

impl<K, V> FromIterator<V> for PrimaryMap<K, V>
where
    K: EntityRef,
{
    fn from_iter<T>(iter: T) -> Self
    where
        T: IntoIterator<Item = V>,
    {
        Self {
            elems: Vec::from_iter(iter),
            unused: PhantomData,
        }
    }
}

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

    // `EntityRef` impl for testing.
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    struct E(u32);

    impl EntityRef for E {
        fn new(i: usize) -> Self {
            E(i as u32)
        }
        fn index(self) -> usize {
            self.0 as usize
        }
    }

    #[test]
    fn basic() {
        let r0 = E(0);
        let r1 = E(1);
        let m = PrimaryMap::<E, isize>::new();

        let v: Vec<E> = m.keys().collect();
        assert_eq!(v, []);

        assert!(!m.is_valid(r0));
        assert!(!m.is_valid(r1));
    }

    #[test]
    fn push() {
        let mut m = PrimaryMap::new();
        let k0: E = m.push(12);
        let k1 = m.push(33);

        assert_eq!(m[k0], 12);
        assert_eq!(m[k1], 33);

        let v: Vec<E> = m.keys().collect();
        assert_eq!(v, [k0, k1]);
    }

    #[test]
    fn iter() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for (key, value) in &m {
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
            i += 1;
        }
        i = 0;
        for (key_mut, value_mut) in m.iter_mut() {
            assert_eq!(key_mut.index(), i);
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
            i += 1;
        }
    }

    #[test]
    fn iter_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for (key, value) in m.iter().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }

        i = 2;
        for (key, value) in m.iter_mut().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }
    }
    #[test]
    fn keys() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for key in m.keys() {
            assert_eq!(key.index(), i);
            i += 1;
        }
    }

    #[test]
    fn keys_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for key in m.keys().rev() {
            i -= 1;
            assert_eq!(key.index(), i);
        }
    }

    #[test]
    fn values() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 0;
        for value in m.values() {
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
            i += 1;
        }
        i = 0;
        for value_mut in m.values_mut() {
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
            i += 1;
        }
    }

    #[test]
    fn values_rev() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);

        let mut i = 2;
        for value in m.values().rev() {
            i -= 1;
            match i {
                0 => assert_eq!(*value, 12),
                1 => assert_eq!(*value, 33),
                _ => panic!(),
            }
        }
        i = 2;
        for value_mut in m.values_mut().rev() {
            i -= 1;
            match i {
                0 => assert_eq!(*value_mut, 12),
                1 => assert_eq!(*value_mut, 33),
                _ => panic!(),
            }
        }
    }

    fn from_iter() {
        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
        m.push(12);
        m.push(33);
        let n = m.values().collect::<PrimaryMap<E, _>>();
        assert!(m.len() == n.len());
        for (me, ne) in m.values().zip(n.values()) {
            assert!(*me == **ne);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The rust-pcre authors.
//
// 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 mod extra;
extern mod rustc;
extern mod rustpkg;

use extra::time;
use rustc::driver::driver::host_triple;
use rustpkg::api;
use std::from_str::{from_str};
use std::io;
use std::libc;
use std::option::{Option};
use std::os;
use std::run;
use std::str;
use std::vec;

struct Version {
    major: uint,
    minor: uint
}

impl Version {
    pub fn parse(version_str: &str) -> Option<Version> {
        let mut it = version_str.split_iter('.');
        match (it.next().and_then(from_str::<uint>), it.next().and_then(from_str::<uint>)) {
            (Some(major), Some(minor)) => Some(Version { major: major, minor: minor }),
            _                          => None
        }
    }
}

impl ToStr for Version {
    fn to_str(&self) -> ~str {
        fmt!("%u.%u", self.major, self.minor)
    }
}

impl Ord for Version {
    fn ge(&self, other: &Version) -> bool {
        !self.lt(other)
    }

    fn gt(&self, other: &Version) -> bool {
        self.major > other.major || (self.major == other.major && self.minor > other.minor)
    }

    fn le(&self, other: &Version) -> bool {
        !self.gt(other)
    }

    fn lt(&self, other: &Version) -> bool {
        self.major < other.major || (self.major == other.major && self.minor < other.minor)
    }
}

fn cd(path: &Path) {
    if !os::change_dir(path) {
        fail2!("Package script error: Failed to `cd` into `{}`", path.to_str());
    }
}

#[cfg(not(target_os = "win32"))]
#[fixed_stack_segment]
fn make_read_only(path: &Path) {
    do path.to_str().with_c_str |path_c_str| {
        let res = unsafe { libc::chmod(path_c_str, libc::consts::os::posix88::S_IRUSR as libc::mode_t) };
        if res != 0 {
            fail2!("Package script error: Failed to make `{}` read-only", path.to_str());
        }
    };
}

fn main() {
    let args = os::args();
    let args_len = args.len();

    if args_len < 2 {
        fail!("Package script requires a directory where rustc libraries live as the first argument");
    } else if args_len < 3 {
        fail!("Package script requires a command as the second argument");
    }

    let sysroot_arg = args[1].clone();
    let sysroot_path = Path(sysroot_arg);

    if args[2] != ~"install" {
        fail2!("Package script error: Unsupported command `{}`", args[2]);
    }

    let pcre_libs = match os::getenv("PCRE_LIBS") {
        None            => {
            let pcre_config_output = run::process_output("pcre-config", [~"--libs"]);
            if pcre_config_output.status != 0 {
                fail!("Package script error: `pcre-config` failed");
            }
            let output_ptr = vec::raw::to_ptr(pcre_config_output.output);
            let output_len = pcre_config_output.output.len();
            let libs_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };
            os::setenv("PCRE_LIBS", libs_str);
            libs_str
        },
        Some(pcre_libs) => pcre_libs
    };
    // `pcre-config` adds a newline to the end, which we need to trim away because newlines
    // in link_args cause build issues.
    let trimmed_pcre_libs = pcre_libs.trim();
    debug!("PCRE_LIBS=\"%s\"", trimmed_pcre_libs);

    let workspace_path = os::getcwd();

    // Check the version
    let target_build_path = workspace_path.push("build").push(host_triple());
    if !os::path_exists(&target_build_path) {
        if !os::make_dir(&target_build_path, 0x1FF) {
            fail2!("Package script error: Failed to create target build directory `{}`", target_build_path.to_str());
        }
    }
    let out_path = target_build_path.push("pcre");
    if !os::path_exists(&out_path) {
        if !os::make_dir(&out_path, 0x1FF) {
            fail2!("Package script error: Failed to create output directory `{}`", out_path.to_str());
        }
    }

    let versioncheck_rs_path = out_path.push("versioncheck.rs");
    {
        let w = match io::file_writer(&versioncheck_rs_path, [io::Create]) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", versioncheck_rs_path.to_str(), err_str),
            Ok(w)        => w
        };
        w.write_str("\
use std::c_str::{CString};
use std::libc::*;
use std::ptr;
use std::vec;

type options = c_int;
struct pcre;
struct pcre_extra;

#[link_args = \"" + trimmed_pcre_libs + "\"]
extern {
    static pcre_free: extern \"C\" fn(ptr: *c_void);

    fn pcre_compile(pattern: *c_char, options: options, errptr: *mut *c_char, erroffset: *mut c_int, tableptr: *c_uchar) -> *pcre;
    fn pcre_exec(code: *pcre, extra: *pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: options, ovector: *mut c_int, ovecsize: c_int) -> c_int;
    fn pcre_version() -> *c_char;
}

#[fixed_stack_segment]
#[inline(never)]
fn main () {
    unsafe {
        let version_cstring = CString::new(pcre_version(), false);
        let version_str = version_cstring.as_str().unwrap().to_owned();

        let pattern = \"^\\\\d+\\\\.\\\\d+\";
        do pattern.with_c_str |pattern_c_str| {
            let mut err: *c_char = ptr::null();
            let mut erroffset: c_int = 0;
            let code = pcre_compile(pattern_c_str, 0, &mut err, &mut erroffset, ptr::null());
            if ptr::is_null(code) {
                if ptr::is_null(code) {
                    let err_cstring = CString::new(err, false);
                    match err_cstring.as_str() {
                        None          => fail2!(\"pcre_compile() failed at offset {}\", erroffset as uint),
                        Some(err_str) => fail2!(\"pcre_compile() failed at offset {}: {}\", erroffset as uint, err_str)
                    }
                }
            }
            assert!(ptr::is_not_null(code));

            let ovecsize = 1 * 3;
            let mut ovector: ~[c_int] = vec::from_elem(ovecsize, 0 as c_int);
            do version_str.with_c_str_unchecked |version_c_str| {
                let rc = pcre_exec(code, ptr::null(), version_c_str, version_str.len() as c_int, 0, 0, vec::raw::to_mut_ptr(ovector), ovecsize as c_int);
                if rc < 0 {
                    fail!(\"pcre_exec() failed\");
                }

                print(version_str.slice_to(ovector[1] as uint));
            }

            pcre_free(code as *c_void);
        }
    }
}
");
    }

    // Compile and run `versioncheck.rs`
    cd(&out_path);
    let rust_run_output = run::process_output("rust", [~"run", ~"versioncheck.rs"]);
    cd(&workspace_path);
    if rust_run_output.status != 0 {
        fail!("Package script error: `rust run versioncheck.rs` failed");
    }
    let output_ptr = vec::raw::to_ptr(rust_run_output.output);
    let output_len = rust_run_output.output.len();
    let output_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };

    // The "no debug symbols in executable" warning may be present in the output.
    // https://github.com/mozilla/rust/issues/3495
    let mut output_rsplit_iter = output_str.rsplit_iter('\n');
    let version_str: ~str = match output_rsplit_iter.next() {
        None              => output_str.clone(),
        Some(version_str) => version_str.to_owned()
    };

    debug!("libpcre version %s", version_str);

    let min_required_version = Version::parse("8.20").unwrap();
    let pcre_version = match Version::parse(version_str) {
        None               => fail2!("Package script error: Failed to parse version string '{}'", version_str),
        Some(pcre_version) => pcre_version
    };
    if pcre_version < min_required_version {
        fail2!("Package script error: Found libpcre version {}, but at least version {} is required", version_str, min_required_version.to_str());
    }

    let src_path = workspace_path.push("src");

    // Output `src/pcre/detail/native.rs`
    let detail_src_path = src_path.push("pcre").push("detail");
    if !os::path_exists(&detail_src_path) {
        fail2!("Package script error: Source directory `{}` does not exist.", detail_src_path.to_str());
    }
    let native_rs_path = detail_src_path.push("native.rs");
    let native_rs_in_path = detail_src_path.push("native.rs.in");
    if !os::path_exists(&native_rs_in_path) {
        fail2!("Package script error: Source file `{}` does not exist.", native_rs_in_path.to_str());
    }
    {
        let r = match io::file_reader(&native_rs_in_path) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for reading: {}", native_rs_in_path.to_str(), err_str),
            Ok(r)        => r
        };
        let w = match io::file_writer(&native_rs_path, [io::Create]) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", native_rs_path.to_str(), err_str),
            Ok(w)        => w
        };
        w.write_line("// Generated by " + args[0] + " on " + time::now().rfc822());
        w.write_char('\n');

        do r.each_line |line| -> bool {
            let substituted_line = str::replace(line, "@PCRE_LIBS@", trimmed_pcre_libs);
            w.write_line(substituted_line);
            true
        };
    }
    make_read_only(&native_rs_path);

    api::build_lib(sysroot_path, workspace_path, ~"pcre", rustpkg::version::ExactRevision(~"0.1"), Path("mod.rs"));
}
<commit_msg>Revert bee8660<commit_after>// Copyright 2013 The rust-pcre authors.
//
// 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 mod extra;
extern mod rustc;
extern mod rustpkg;

use extra::time;
use rustc::driver::driver::host_triple;
use rustpkg::api;
use std::from_str::{from_str};
use std::io;
use std::option::{Option};
use std::os;
use std::run;
use std::str;
use std::vec;

struct Version {
    major: uint,
    minor: uint
}

impl Version {
    pub fn parse(version_str: &str) -> Option<Version> {
        let mut it = version_str.split_iter('.');
        match (it.next().and_then(from_str::<uint>), it.next().and_then(from_str::<uint>)) {
            (Some(major), Some(minor)) => Some(Version { major: major, minor: minor }),
            _                          => None
        }
    }
}

impl ToStr for Version {
    fn to_str(&self) -> ~str {
        fmt!("%u.%u", self.major, self.minor)
    }
}

impl Ord for Version {
    fn ge(&self, other: &Version) -> bool {
        !self.lt(other)
    }

    fn gt(&self, other: &Version) -> bool {
        self.major > other.major || (self.major == other.major && self.minor > other.minor)
    }

    fn le(&self, other: &Version) -> bool {
        !self.gt(other)
    }

    fn lt(&self, other: &Version) -> bool {
        self.major < other.major || (self.major == other.major && self.minor < other.minor)
    }
}

fn cd(path: &Path) {
    if !os::change_dir(path) {
        fail2!("Package script error: Failed to `cd` into `{}`", path.to_str());
    }
}

fn main() {
    let args = os::args();
    let args_len = args.len();

    if args_len < 2 {
        fail!("Package script requires a directory where rustc libraries live as the first argument");
    } else if args_len < 3 {
        fail!("Package script requires a command as the second argument");
    }

    let sysroot_arg = args[1].clone();
    let sysroot_path = Path(sysroot_arg);

    if args[2] != ~"install" {
        fail2!("Package script error: Unsupported command `{}`", args[2]);
    }

    let pcre_libs = match os::getenv("PCRE_LIBS") {
        None            => {
            let pcre_config_output = run::process_output("pcre-config", [~"--libs"]);
            if pcre_config_output.status != 0 {
                fail!("Package script error: `pcre-config` failed");
            }
            let output_ptr = vec::raw::to_ptr(pcre_config_output.output);
            let output_len = pcre_config_output.output.len();
            let libs_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };
            os::setenv("PCRE_LIBS", libs_str);
            libs_str
        },
        Some(pcre_libs) => pcre_libs
    };
    // `pcre-config` adds a newline to the end, which we need to trim away because newlines
    // in link_args cause build issues.
    let trimmed_pcre_libs = pcre_libs.trim();
    debug!("PCRE_LIBS=\"%s\"", trimmed_pcre_libs);

    let workspace_path = os::getcwd();

    // Check the version
    let target_build_path = workspace_path.push("build").push(host_triple());
    if !os::path_exists(&target_build_path) {
        if !os::make_dir(&target_build_path, 0x1FF) {
            fail2!("Package script error: Failed to create target build directory `{}`", target_build_path.to_str());
        }
    }
    let out_path = target_build_path.push("pcre");
    if !os::path_exists(&out_path) {
        if !os::make_dir(&out_path, 0x1FF) {
            fail2!("Package script error: Failed to create output directory `{}`", out_path.to_str());
        }
    }

    let versioncheck_rs_path = out_path.push("versioncheck.rs");
    {
        let w = match io::file_writer(&versioncheck_rs_path, [io::Create]) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", versioncheck_rs_path.to_str(), err_str),
            Ok(w)        => w
        };
        w.write_str("\
use std::c_str::{CString};
use std::libc::*;
use std::ptr;
use std::vec;

type options = c_int;
struct pcre;
struct pcre_extra;

#[link_args = \"" + trimmed_pcre_libs + "\"]
extern {
    static pcre_free: extern \"C\" fn(ptr: *c_void);

    fn pcre_compile(pattern: *c_char, options: options, errptr: *mut *c_char, erroffset: *mut c_int, tableptr: *c_uchar) -> *pcre;
    fn pcre_exec(code: *pcre, extra: *pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: options, ovector: *mut c_int, ovecsize: c_int) -> c_int;
    fn pcre_version() -> *c_char;
}

#[fixed_stack_segment]
#[inline(never)]
fn main () {
    unsafe {
        let version_cstring = CString::new(pcre_version(), false);
        let version_str = version_cstring.as_str().unwrap().to_owned();

        let pattern = \"^\\\\d+\\\\.\\\\d+\";
        do pattern.with_c_str |pattern_c_str| {
            let mut err: *c_char = ptr::null();
            let mut erroffset: c_int = 0;
            let code = pcre_compile(pattern_c_str, 0, &mut err, &mut erroffset, ptr::null());
            if ptr::is_null(code) {
                if ptr::is_null(code) {
                    let err_cstring = CString::new(err, false);
                    match err_cstring.as_str() {
                        None          => fail2!(\"pcre_compile() failed at offset {}\", erroffset as uint),
                        Some(err_str) => fail2!(\"pcre_compile() failed at offset {}: {}\", erroffset as uint, err_str)
                    }
                }
            }
            assert!(ptr::is_not_null(code));

            let ovecsize = 1 * 3;
            let mut ovector: ~[c_int] = vec::from_elem(ovecsize, 0 as c_int);
            do version_str.with_c_str_unchecked |version_c_str| {
                let rc = pcre_exec(code, ptr::null(), version_c_str, version_str.len() as c_int, 0, 0, vec::raw::to_mut_ptr(ovector), ovecsize as c_int);
                if rc < 0 {
                    fail!(\"pcre_exec() failed\");
                }

                print(version_str.slice_to(ovector[1] as uint));
            }

            pcre_free(code as *c_void);
        }
    }
}
");
    }

    // Compile and run `versioncheck.rs`
    cd(&out_path);
    let rust_run_output = run::process_output("rust", [~"run", ~"versioncheck.rs"]);
    cd(&workspace_path);
    if rust_run_output.status != 0 {
        fail!("Package script error: `rust run versioncheck.rs` failed");
    }
    let output_ptr = vec::raw::to_ptr(rust_run_output.output);
    let output_len = rust_run_output.output.len();
    let output_str = unsafe { str::raw::from_buf_len(output_ptr, output_len) };

    // The "no debug symbols in executable" warning may be present in the output.
    // https://github.com/mozilla/rust/issues/3495
    let mut output_rsplit_iter = output_str.rsplit_iter('\n');
    let version_str: ~str = match output_rsplit_iter.next() {
        None              => output_str.clone(),
        Some(version_str) => version_str.to_owned()
    };

    debug!("libpcre version %s", version_str);

    let min_required_version = Version::parse("8.20").unwrap();
    let pcre_version = match Version::parse(version_str) {
        None               => fail2!("Package script error: Failed to parse version string '{}'", version_str),
        Some(pcre_version) => pcre_version
    };
    if pcre_version < min_required_version {
        fail2!("Package script error: Found libpcre version {}, but at least version {} is required", version_str, min_required_version.to_str());
    }

    let src_path = workspace_path.push("src");

    // Output `src/pcre/detail/native.rs`
    let detail_src_path = src_path.push("pcre").push("detail");
    if !os::path_exists(&detail_src_path) {
        fail2!("Package script error: Source directory `{}` does not exist.", detail_src_path.to_str());
    }
    let native_rs_path = detail_src_path.push("native.rs");
    let native_rs_in_path = detail_src_path.push("native.rs.in");
    if !os::path_exists(&native_rs_in_path) {
        fail2!("Package script error: Source file `{}` does not exist.", native_rs_in_path.to_str());
    }
    {
        let r = match io::file_reader(&native_rs_in_path) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for reading: {}", native_rs_in_path.to_str(), err_str),
            Ok(r)        => r
        };
        let w = match io::file_writer(&native_rs_path, [io::Create]) {
            Err(err_str) => fail2!("Package script error: Failed to open `{}` for writing: {}", native_rs_path.to_str(), err_str),
            Ok(w)        => w
        };
        w.write_line("// -*- buffer-read-only: t -*-");
        w.write_line("// Generated by " + args[0] + " on " + time::now().rfc822());
        w.write_char('\n');

        do r.each_line |line| -> bool {
            let substituted_line = str::replace(line, "@PCRE_LIBS@", trimmed_pcre_libs);
            w.write_line(substituted_line);
            true
        };
    }

    api::build_lib(sysroot_path, workspace_path, ~"pcre", rustpkg::version::ExactRevision(~"0.1"), Path("mod.rs"));
}
<|endoftext|>


<commit_before>use std::hash::Hash;

mod private {
    use std::collections::HashMap;
    use std::hash::Hash;
    use std::fmt;

    #[derive(Clone)]
    #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
    pub struct DuplicatesBy<I: Iterator, Key, F> {
        pub(crate) iter: I,
        pub(crate) meta: Meta<Key, F>,
    }

    impl<I, V, F> fmt::Debug for DuplicatesBy<I, V, F>
    where
        I: Iterator + fmt::Debug,
        V: fmt::Debug + Hash + Eq,
    {
        debug_fmt_fields!(DuplicatesBy, iter, meta.used);
    }

    impl<I: Iterator, Key: Eq + Hash, F> DuplicatesBy<I, Key, F> {
        pub(crate) fn new(iter: I, key_method: F) -> Self {
            DuplicatesBy {
                iter,
                meta: Meta {
                    used: HashMap::new(),
                    pending: 0,
                    key_method,
                },
            }
        }
    }

    #[derive(Clone)]
    pub struct Meta<Key, F> {
        used: HashMap<Key, bool>,
        pending: usize,
        key_method: F,
    }

    impl<Key, F> Meta<Key, F>
    where
        Key: Eq + Hash,
    {
        /// Takes an item and returns it back to the caller if it's the second time we see it.
        /// Otherwise the item is consumed and None is returned
        #[inline(always)]
        fn filter<I>(&mut self, item: I) -> Option<I>
        where
            F: KeyMethod<Key, I>,
        {
            let kv = self.key_method.make(item);
            match self.used.get_mut(kv.key_ref()) {
                None => {
                    self.used.insert(kv.key(), false);
                    self.pending += 1;
                    None
                }
                Some(true) => None,
                Some(produced) => {
                    *produced = true;
                    self.pending -= 1;
                    Some(kv.value())
                }
            }
        }
    }

    impl<I, Key, F> Iterator for DuplicatesBy<I, Key, F>
    where
        I: Iterator,
        Key: Eq + Hash,
        F: KeyMethod<Key, I::Item>,
    {
        type Item = I::Item;

        fn next(&mut self) -> Option<Self::Item> {
            let DuplicatesBy { iter, meta } = self;
            iter.find_map(|v| meta.filter(v))
        }

        #[inline]
        fn size_hint(&self) -> (usize, Option<usize>) {
            let (_, hi) = self.iter.size_hint();
            // There are `hi` number of items left in the base iterator. In the best case scenario,
            // these items are exactly the same as the ones pending (i.e items seen exactly once so
            // far), plus (hi - pending) / 2 pairs of never seen before items.
            let hi = hi.map(|hi| {
                let max_pending = std::cmp::min(self.meta.pending, hi);
                let max_new = hi.saturating_sub(self.meta.pending) / 2;
                max_pending + max_new
            });
            // The lower bound is always 0 since we might only get unique items from now on
            (0, hi)
        }
    }

    impl<I, Key, F> DoubleEndedIterator for DuplicatesBy<I, Key, F>
    where
        I: DoubleEndedIterator,
        Key: Eq + Hash,
        F: KeyMethod<Key, I::Item>,
    {
        fn next_back(&mut self) -> Option<Self::Item> {
            let DuplicatesBy { iter, meta } = self;
            iter.rev().find_map(|v| meta.filter(v))
        }
    }

    /// A keying method for use with `DuplicatesBy`
    pub trait KeyMethod<K, V> {
        type Container: KeyXorValue<K, V>;

        fn make(&mut self, value: V) -> Self::Container;
    }

    /// Apply the identity function to elements before checking them for equality.
    pub struct ById;
    impl<V> KeyMethod<V, V> for ById {
        type Container = JustValue<V>;

        fn make(&mut self, v: V) -> Self::Container {
            JustValue(v)
        }
    }

    /// Apply a user-supplied function to elements before checking them for equality.
    pub struct ByFn<F>(pub(crate) F);
    impl<K, V, F> KeyMethod<K, V> for ByFn<F>
    where
        F: FnMut(&V) -> K,
    {
        type Container = KeyValue<K, V>;

        fn make(&mut self, v: V) -> Self::Container {
            KeyValue((self.0)(&v), v)
        }
    }

    // Implementors of this trait can hold onto a key and a value but only give access to one of them
    // at a time. This allows the key and the value to be the same value internally
    pub trait KeyXorValue<K, V> {
        fn key_ref(&self) -> &K;
        fn key(self) -> K;
        fn value(self) -> V;
    }

    pub struct KeyValue<K, V>(K, V);
    impl<K, V> KeyXorValue<K, V> for KeyValue<K, V> {
        fn key_ref(&self) -> &K {
            &self.0
        }
        fn key(self) -> K {
            self.0
        }
        fn value(self) -> V {
            self.1
        }
    }

    pub struct JustValue<V>(V);
    impl<V> KeyXorValue<V, V> for JustValue<V> {
        fn key_ref(&self) -> &V {
            &self.0
        }
        fn key(self) -> V {
            self.0
        }
        fn value(self) -> V {
            self.0
        }
    }
}

/// An iterator adapter to filter for duplicate elements.
///
/// See [`.duplicates_by()`](crate::Itertools::duplicates_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub type DuplicatesBy<I, V, F> = private::DuplicatesBy<I, V, private::ByFn<F>>;

/// Create a new `DuplicatesBy` iterator.
pub fn duplicates_by<I, Key, F>(iter: I, f: F) -> DuplicatesBy<I, Key, F>
where
    Key: Eq + Hash,
    F: FnMut(&I::Item) -> Key,
    I: Iterator,
{
    DuplicatesBy::new(iter, private::ByFn(f))
}

/// An iterator adapter to filter out duplicate elements.
///
/// See [`.duplicates()`](crate::Itertools::duplicates) for more information.
pub type Duplicates<I> = private::DuplicatesBy<I, <I as Iterator>::Item, private::ById>;

/// Create a new `Duplicates` iterator.
pub fn duplicates<I>(iter: I) -> Duplicates<I>
where
    I: Iterator,
    I::Item: Eq + Hash,
{
    Duplicates::new(iter, private::ById)
}

<commit_msg>Make hi calculation clearer in DuplicatesBy size_hint<commit_after>use std::hash::Hash;

mod private {
    use std::collections::HashMap;
    use std::hash::Hash;
    use std::fmt;

    #[derive(Clone)]
    #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
    pub struct DuplicatesBy<I: Iterator, Key, F> {
        pub(crate) iter: I,
        pub(crate) meta: Meta<Key, F>,
    }

    impl<I, V, F> fmt::Debug for DuplicatesBy<I, V, F>
    where
        I: Iterator + fmt::Debug,
        V: fmt::Debug + Hash + Eq,
    {
        debug_fmt_fields!(DuplicatesBy, iter, meta.used);
    }

    impl<I: Iterator, Key: Eq + Hash, F> DuplicatesBy<I, Key, F> {
        pub(crate) fn new(iter: I, key_method: F) -> Self {
            DuplicatesBy {
                iter,
                meta: Meta {
                    used: HashMap::new(),
                    pending: 0,
                    key_method,
                },
            }
        }
    }

    #[derive(Clone)]
    pub struct Meta<Key, F> {
        used: HashMap<Key, bool>,
        pending: usize,
        key_method: F,
    }

    impl<Key, F> Meta<Key, F>
    where
        Key: Eq + Hash,
    {
        /// Takes an item and returns it back to the caller if it's the second time we see it.
        /// Otherwise the item is consumed and None is returned
        #[inline(always)]
        fn filter<I>(&mut self, item: I) -> Option<I>
        where
            F: KeyMethod<Key, I>,
        {
            let kv = self.key_method.make(item);
            match self.used.get_mut(kv.key_ref()) {
                None => {
                    self.used.insert(kv.key(), false);
                    self.pending += 1;
                    None
                }
                Some(true) => None,
                Some(produced) => {
                    *produced = true;
                    self.pending -= 1;
                    Some(kv.value())
                }
            }
        }
    }

    impl<I, Key, F> Iterator for DuplicatesBy<I, Key, F>
    where
        I: Iterator,
        Key: Eq + Hash,
        F: KeyMethod<Key, I::Item>,
    {
        type Item = I::Item;

        fn next(&mut self) -> Option<Self::Item> {
            let DuplicatesBy { iter, meta } = self;
            iter.find_map(|v| meta.filter(v))
        }

        #[inline]
        fn size_hint(&self) -> (usize, Option<usize>) {
            let (_, hi) = self.iter.size_hint();
            let hi = hi.map(|hi| {
                if hi <= self.meta.pending {
                    // fewer or equally many iter-remaining elements than pending elements
                    // => at most, each iter-remaining element is matched
                    hi
                } else {
                    // fewer pending elements than iter-remaining elements
                    // => at most:
                    //    * each pending element is matched
                    //    * the other iter-remaining elements come in pairs
                    self.meta.pending + (hi - self.meta.pending) / 2
                }
            });
            // The lower bound is always 0 since we might only get unique items from now on
            (0, hi)
        }
    }

    impl<I, Key, F> DoubleEndedIterator for DuplicatesBy<I, Key, F>
    where
        I: DoubleEndedIterator,
        Key: Eq + Hash,
        F: KeyMethod<Key, I::Item>,
    {
        fn next_back(&mut self) -> Option<Self::Item> {
            let DuplicatesBy { iter, meta } = self;
            iter.rev().find_map(|v| meta.filter(v))
        }
    }

    /// A keying method for use with `DuplicatesBy`
    pub trait KeyMethod<K, V> {
        type Container: KeyXorValue<K, V>;

        fn make(&mut self, value: V) -> Self::Container;
    }

    /// Apply the identity function to elements before checking them for equality.
    pub struct ById;
    impl<V> KeyMethod<V, V> for ById {
        type Container = JustValue<V>;

        fn make(&mut self, v: V) -> Self::Container {
            JustValue(v)
        }
    }

    /// Apply a user-supplied function to elements before checking them for equality.
    pub struct ByFn<F>(pub(crate) F);
    impl<K, V, F> KeyMethod<K, V> for ByFn<F>
    where
        F: FnMut(&V) -> K,
    {
        type Container = KeyValue<K, V>;

        fn make(&mut self, v: V) -> Self::Container {
            KeyValue((self.0)(&v), v)
        }
    }

    // Implementors of this trait can hold onto a key and a value but only give access to one of them
    // at a time. This allows the key and the value to be the same value internally
    pub trait KeyXorValue<K, V> {
        fn key_ref(&self) -> &K;
        fn key(self) -> K;
        fn value(self) -> V;
    }

    pub struct KeyValue<K, V>(K, V);
    impl<K, V> KeyXorValue<K, V> for KeyValue<K, V> {
        fn key_ref(&self) -> &K {
            &self.0
        }
        fn key(self) -> K {
            self.0
        }
        fn value(self) -> V {
            self.1
        }
    }

    pub struct JustValue<V>(V);
    impl<V> KeyXorValue<V, V> for JustValue<V> {
        fn key_ref(&self) -> &V {
            &self.0
        }
        fn key(self) -> V {
            self.0
        }
        fn value(self) -> V {
            self.0
        }
    }
}

/// An iterator adapter to filter for duplicate elements.
///
/// See [`.duplicates_by()`](crate::Itertools::duplicates_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub type DuplicatesBy<I, V, F> = private::DuplicatesBy<I, V, private::ByFn<F>>;

/// Create a new `DuplicatesBy` iterator.
pub fn duplicates_by<I, Key, F>(iter: I, f: F) -> DuplicatesBy<I, Key, F>
where
    Key: Eq + Hash,
    F: FnMut(&I::Item) -> Key,
    I: Iterator,
{
    DuplicatesBy::new(iter, private::ByFn(f))
}

/// An iterator adapter to filter out duplicate elements.
///
/// See [`.duplicates()`](crate::Itertools::duplicates) for more information.
pub type Duplicates<I> = private::DuplicatesBy<I, <I as Iterator>::Item, private::ById>;

/// Create a new `Duplicates` iterator.
pub fn duplicates<I>(iter: I) -> Duplicates<I>
where
    I: Iterator,
    I::Item: Eq + Hash,
{
    Duplicates::new(iter, private::ById)
}

<|endoftext|>


<commit_before>extern crate cortex;
use cortex::importer::*;
use std::vec::Vec;
use std::fs;
use std::io::{Error};

fn assert_files(files:Vec<&str>) -> Result<(),std::io::Error> {
  for file in files.iter() {
    let meta = fs::metadata(file.clone());
    assert!(meta.is_ok());
    assert!(meta.unwrap().is_file());
    // They're also temporary, so delete them
    try!(fs::remove_file(file.clone()));
  }
  Ok(()) }

fn assert_dirs(dirs : Vec<&str>) -> Result<(),std::io::Error> {
  for dir in dirs.iter() {
    let meta = fs::metadata(dir.clone());
    assert!(meta.is_ok());
    assert!(meta.unwrap().is_dir());
    // They're also temporary, so delete them
    try!(fs::remove_dir(dir.clone()));
  }
  Ok(()) }

#[test]
fn can_import_simple() {
  let importer = Importer {
    complex: false,
    path: "tests/data/"};

  println!("-- Testing simple import");
  assert_eq!( importer.process(), Ok(()) );
}

#[test]
fn can_import_complex() {
  let importer = Importer {
    complex: true,
    path: "tests/data/"};

  println!("-- Testing complex import");
  assert_eq!( importer.process(), Ok(()) );
  let files_removed_ok = assert_files(vec![
    // "tests/data/9107/hep-lat9107001/9107001.tex",
    // "tests/data/9107/hep-lat9107001/fig1.eps",
    // "tests/data/9107/hep-lat9107002/hep-lat9107002.tex"
    "tests/data/9107/hep-lat9107001/hep-lat9107001.zip",
    "tests/data/9107/hep-lat9107002/hep-lat9107002.zip",
    ]);
  assert!(files_removed_ok.is_ok());
  let dirs_removed_ok = assert_dirs(vec![
    "tests/data/9107/hep-lat9107001",
    "tests/data/9107/hep-lat9107002",
    "tests/data/9107"
  ]);
  assert!(dirs_removed_ok.is_ok());

}<commit_msg>re-import existing data<commit_after>extern crate cortex;
use cortex::importer::*;
use std::vec::Vec;
use std::fs;
use std::io::{Error};

fn assert_files(files:Vec<&str>) -> Result<(),std::io::Error> {
  for file in files.iter() {
    let meta = fs::metadata(file.clone());
    assert!(meta.is_ok());
    assert!(meta.unwrap().is_file());
    // They're also temporary, so delete them
    try!(fs::remove_file(file.clone()));
  }
  Ok(()) }

fn assert_dirs(dirs : Vec<&str>) -> Result<(),std::io::Error> {
  for dir in dirs.iter() {
    let meta = fs::metadata(dir.clone());
    assert!(meta.is_ok());
    assert!(meta.unwrap().is_dir());
    // They're also temporary, so delete them
    try!(fs::remove_dir(dir.clone()));
  }
  Ok(()) }

#[test]
fn can_import_simple() {
  let importer = Importer {
    complex: false,
    path: "tests/data/"};

  println!("-- Testing simple import");
  assert_eq!( importer.process(), Ok(()) );
}

#[test]
fn can_import_complex() {
  let importer = Importer {
    complex: true,
    path: "tests/data/"};

  println!("-- Testing complex import");
  assert_eq!( importer.process(), Ok(()) );

  let repeat_importer = Importer {
    complex: true,
    path: "tests/data/"};

  println!("-- Testing repeated complex import (successful and no-op)");
  assert_eq!( repeat_importer.process(), Ok(()) );

  let files_removed_ok = assert_files(vec![
    "tests/data/9107/hep-lat9107001/hep-lat9107001.zip",
    "tests/data/9107/hep-lat9107002/hep-lat9107002.zip",
    ]);
  assert!(files_removed_ok.is_ok());
  let dirs_removed_ok = assert_dirs(vec![
    "tests/data/9107/hep-lat9107001",
    "tests/data/9107/hep-lat9107002",
    "tests/data/9107"
  ]);
  assert!(dirs_removed_ok.is_ok());

}<|endoftext|>


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

//! Record audio

#![allow(missing_doc)]

use std::{task, cast};
use std::vec::Vec;

use record_context::RecordContext;
use record_context;
use openal::ffi;
use sndfile::{SndInfo, SndFile, FormatWav, FormatPcm16, Write};

/**
 * Record audio
 *
 * This class provide easy audio recording using. The Recorder allow the user
 * to record sound, then save it in a file, or create a SoundData object to play the
 * recorded sound in the same program.
 * A special context, RecordContext is needed to create the Recorder object.
 * The Recorder work in it's own task.
 *
 * # Examples
 * ```Rust
 * extern mod ears;
 * use ears::{RecordContext, Recorder};
 *
 * fn main() -> () {
 *     // Create a new context to record audio
 *     let context = ears::init_in().unwrap();
 *     // Create the recorder
 *     let recorder = Recorder::new(context);
 *     // Start to record something
 *     recorder.start();
 *
 *     // Do some other stuff here //
 *
 *     // Stop the recorder
 *     recorder.stop();
 *     // Then store the recorded data in a file
 *     recorder.save_to_file("hello_file");
 * }
 * ```
 */
pub struct Recorder {
    ctxt: RecordContext,
    stop_sender: Option<Sender<bool>>,
    data_receiver: Option<Receiver<Vec<i16>>>,
    samples: Vec<i16>
}

impl Recorder {
    /// Create a new audio recorder
    pub fn new(record_context: RecordContext) -> Recorder {
        Recorder {
            ctxt: record_context,
            stop_sender: None,
            data_receiver: None,
            samples: Vec::new()

        }
    }

    pub fn start(&mut self) {
        let (stop_sender, stop_receiver) = channel();
        let (data_sender, data_receiver) = channel();
        let r_c = self.ctxt.clone();

        self.stop_sender = Some(stop_sender);
        self.data_receiver = Some(data_receiver);

        task::spawn(proc() {
            let mut terminate = false;
            let ctxt = record_context::get(r_c);
            unsafe { ffi::alcCaptureStart(ctxt); }
            let mut available_samples = 0;
            let mut samples: Vec<i16> = Vec::new();

            while !terminate {
                unsafe {
                    ffi::alcGetIntegerv(ctxt,
                                        ffi::ALC_CAPTURE_SAMPLES,
                                        1,
                                        &mut available_samples)
                };

                if available_samples != 0 {
                    let tmp_buf =
                        Vec::from_elem(available_samples as uint, 0i16);
                    unsafe {
                        ffi::alcCaptureSamples(ctxt,
                                               cast::transmute(&tmp_buf.as_slice()[0]),
                                               available_samples);
                    }
                    samples.push_all_move(tmp_buf);
                }

                match stop_receiver.try_recv() {
                    Ok(_) => {
                        unsafe { ffi::alcCaptureStop(ctxt); }
                        terminate = true;
                    },
                    _       => {}
                }
            }
            data_sender.send(samples);
        });
    }

    pub fn stop(&mut self) -> bool {
        match self.stop_sender {
            Some(ref s_c) => {
                s_c.send(true);
                match self.data_receiver {
                    Some(ref d_p) => {
                        self.samples = d_p.recv();
                        true
                    },
                    None          => false
                }
            },
            None      => false
        }
    }

    pub fn save_to_file(&mut self, filename: &str) -> bool {
        if self.samples.len() == 0 {
            false
        } else {
            let infos = box SndInfo {
                frames : self.samples.len() as i64,
                samplerate : 44100,
                channels : 1,
                format : (FormatPcm16 | FormatWav) as i32,
                sections : 0,
                seekable : 0
            };

            let mut file_ext = StrBuf::from_str(filename);
            file_ext.push_str(".wav");
            match SndFile::new_with_info(file_ext.into_owned(), Write, infos) {
                Ok(mut f) => {
                    let len = self.samples.len() as i64;
                    f.write_i16(self.samples.as_mut_slice(), len);
                    f.close();
                    true
                },
                Err(e) => { println!("{}", e); false }
            }
        }
    }
}
<commit_msg>update to last Rust - std::cast is now std::mem<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//! Record audio

#![allow(missing_doc)]

use std::{task, mem};
use std::vec::Vec;

use record_context::RecordContext;
use record_context;
use openal::ffi;
use sndfile::{SndInfo, SndFile, FormatWav, FormatPcm16, Write};

/**
 * Record audio
 *
 * This class provide easy audio recording using. The Recorder allow the user
 * to record sound, then save it in a file, or create a SoundData object to play the
 * recorded sound in the same program.
 * A special context, RecordContext is needed to create the Recorder object.
 * The Recorder work in it's own task.
 *
 * # Examples
 * ```Rust
 * extern mod ears;
 * use ears::{RecordContext, Recorder};
 *
 * fn main() -> () {
 *     // Create a new context to record audio
 *     let context = ears::init_in().unwrap();
 *     // Create the recorder
 *     let recorder = Recorder::new(context);
 *     // Start to record something
 *     recorder.start();
 *
 *     // Do some other stuff here //
 *
 *     // Stop the recorder
 *     recorder.stop();
 *     // Then store the recorded data in a file
 *     recorder.save_to_file("hello_file");
 * }
 * ```
 */
pub struct Recorder {
    ctxt: RecordContext,
    stop_sender: Option<Sender<bool>>,
    data_receiver: Option<Receiver<Vec<i16>>>,
    samples: Vec<i16>
}

impl Recorder {
    /// Create a new audio recorder
    pub fn new(record_context: RecordContext) -> Recorder {
        Recorder {
            ctxt: record_context,
            stop_sender: None,
            data_receiver: None,
            samples: Vec::new()

        }
    }

    pub fn start(&mut self) {
        let (stop_sender, stop_receiver) = channel();
        let (data_sender, data_receiver) = channel();
        let r_c = self.ctxt.clone();

        self.stop_sender = Some(stop_sender);
        self.data_receiver = Some(data_receiver);

        task::spawn(proc() {
            let mut terminate = false;
            let ctxt = record_context::get(r_c);
            unsafe { ffi::alcCaptureStart(ctxt); }
            let mut available_samples = 0;
            let mut samples: Vec<i16> = Vec::new();

            while !terminate {
                unsafe {
                    ffi::alcGetIntegerv(ctxt,
                                        ffi::ALC_CAPTURE_SAMPLES,
                                        1,
                                        &mut available_samples)
                };

                if available_samples != 0 {
                    let tmp_buf =
                        Vec::from_elem(available_samples as uint, 0i16);
                    unsafe {
                        ffi::alcCaptureSamples(ctxt,
                                               mem::transmute(&tmp_buf.as_slice()[0]),
                                               available_samples);
                    }
                    samples.push_all_move(tmp_buf);
                }

                match stop_receiver.try_recv() {
                    Ok(_) => {
                        unsafe { ffi::alcCaptureStop(ctxt); }
                        terminate = true;
                    },
                    _       => {}
                }
            }
            data_sender.send(samples);
        });
    }

    pub fn stop(&mut self) -> bool {
        match self.stop_sender {
            Some(ref s_c) => {
                s_c.send(true);
                match self.data_receiver {
                    Some(ref d_p) => {
                        self.samples = d_p.recv();
                        true
                    },
                    None          => false
                }
            },
            None      => false
        }
    }

    pub fn save_to_file(&mut self, filename: &str) -> bool {
        if self.samples.len() == 0 {
            false
        } else {
            let infos = box SndInfo {
                frames : self.samples.len() as i64,
                samplerate : 44100,
                channels : 1,
                format : (FormatPcm16 | FormatWav) as i32,
                sections : 0,
                seekable : 0
            };

            let mut file_ext = StrBuf::from_str(filename);
            file_ext.push_str(".wav");
            match SndFile::new_with_info(file_ext.into_owned(), Write, infos) {
                Ok(mut f) => {
                    let len = self.samples.len() as i64;
                    f.write_i16(self.samples.as_mut_slice(), len);
                    f.close();
                    true
                },
                Err(e) => { println!("{}", e); false }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Releases inteface

use self::super::{Github, Result};
use rustc_serialize::json;
use rep::{Asset, Release, ReleaseReq};

pub struct Assets<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
    releaseid: u64,
}

impl<'a> Assets<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R, releaseid: u64) -> Assets<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Assets {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            releaseid: releaseid,
        }
    }

    // todo: upload asset
    // todo: edit asset

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases/{}/assets{}",
                self.owner,
                self.repo,
                self.releaseid,
                more)
    }

    // todo: stream interface to download
    pub fn get(&self, id: u64) -> Result<Asset> {
        self.github.get::<Asset>(&self.path(&format!("/{}", id)))
    }

    pub fn delete(&self, id: u64) -> Result<()> {
        self.github
            .delete(&self.path(&format!("/{}", id)))
            .map(|_| ())
    }

    pub fn list(&self) -> Result<Vec<Asset>> {
        self.github.get::<Vec<Asset>>(&self.path(""))
    }
}

pub struct ReleaseRef<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
    id: u64,
}

impl<'a> ReleaseRef<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R, id: u64) -> ReleaseRef<'a>
        where O: Into<String>,
              R: Into<String>
    {
        ReleaseRef {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            id: id,
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases/{}{}",
                self.owner,
                self.repo,
                self.id,
                more)
    }

    pub fn get(&self) -> Result<Release> {
        self.github.get::<Release>(&self.path(""))
    }

    pub fn assets(&self) -> Assets {
        Assets::new(self.github,
                    self.owner.as_ref(),
                    self.repo.as_ref(),
                    self.id)
    }
}

pub struct Releases<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
}

impl<'a> Releases<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R) -> Releases<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Releases {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases{}", self.owner, self.repo, more)
    }

    pub fn create(&self, rel: &ReleaseReq) -> Result<Release> {
        let data = try!(json::encode(&rel));
        self.github.post::<Release>(&self.path(""), data.as_bytes())
    }

    pub fn edit(&self, id: u64, rel: &ReleaseReq) -> Result<Release> {
        let data = try!(json::encode(&rel));
        self.github.patch::<Release>(&self.path(&format!("/{}", id)), data.as_bytes())
    }

    pub fn delete(&self, id: u64) -> Result<()> {
        self.github
            .delete(&self.path(&format!("/{}", id)))
            .map(|_| ())
    }

    pub fn list(&self) -> Result<Vec<Release>> {
        self.github.get::<Vec<Release>>(&self.path(""))
    }

    pub fn get(&self, id: u64) -> ReleaseRef {
        ReleaseRef::new(self.github, self.owner.as_ref(), self.repo.as_ref(), id)
    }
}
<commit_msg>remove excess whitespace<commit_after>//! Releases inteface

use self::super::{Github, Result};
use rustc_serialize::json;
use rep::{Asset, Release, ReleaseReq};

pub struct Assets<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
    releaseid: u64,
}

impl<'a> Assets<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R, releaseid: u64) -> Assets<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Assets {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            releaseid: releaseid,
        }
    }

    // todo: upload asset
    // todo: edit asset

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases/{}/assets{}",
                self.owner,
                self.repo,
                self.releaseid,
                more)
    }

    // todo: stream interface to download
    pub fn get(&self, id: u64) -> Result<Asset> {
        self.github.get::<Asset>(&self.path(&format!("/{}", id)))
    }

    pub fn delete(&self, id: u64) -> Result<()> {
        self.github
            .delete(&self.path(&format!("/{}", id)))
            .map(|_| ())
    }

    pub fn list(&self) -> Result<Vec<Asset>> {
        self.github.get::<Vec<Asset>>(&self.path(""))
    }
}

pub struct ReleaseRef<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
    id: u64,
}

impl<'a> ReleaseRef<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R, id: u64) -> ReleaseRef<'a>
        where O: Into<String>,
              R: Into<String>
    {
        ReleaseRef {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
            id: id,
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases/{}{}",
                self.owner,
                self.repo,
                self.id,
                more)
    }

    pub fn get(&self) -> Result<Release> {
        self.github.get::<Release>(&self.path(""))
    }

    pub fn assets(&self) -> Assets {
        Assets::new(self.github,
                    self.owner.as_ref(),
                    self.repo.as_ref(),
                    self.id)
    }
}

pub struct Releases<'a> {
    github: &'a Github<'a>,
    owner: String,
    repo: String,
}

impl<'a> Releases<'a> {
    pub fn new<O, R>(github: &'a Github<'a>, owner: O, repo: R) -> Releases<'a>
        where O: Into<String>,
              R: Into<String>
    {
        Releases {
            github: github,
            owner: owner.into(),
            repo: repo.into(),
        }
    }

    fn path(&self, more: &str) -> String {
        format!("/repos/{}/{}/releases{}", self.owner, self.repo, more)
    }

    pub fn create(&self, rel: &ReleaseReq) -> Result<Release> {
        let data = try!(json::encode(&rel));
        self.github.post::<Release>(&self.path(""), data.as_bytes())
    }

    pub fn edit(&self, id: u64, rel: &ReleaseReq) -> Result<Release> {
        let data = try!(json::encode(&rel));
        self.github.patch::<Release>(&self.path(&format!("/{}", id)), data.as_bytes())
    }

    pub fn delete(&self, id: u64) -> Result<()> {
        self.github
            .delete(&self.path(&format!("/{}", id)))
            .map(|_| ())
    }

    pub fn list(&self) -> Result<Vec<Release>> {
        self.github.get::<Vec<Release>>(&self.path(""))
    }

    pub fn get(&self, id: u64) -> ReleaseRef {
        ReleaseRef::new(self.github, self.owner.as_ref(), self.repo.as_ref(), id)
    }
}
<|endoftext|>


<commit_before>// Copyright(C) 2016 Chris Liebert
extern crate glium;
extern crate image;
extern crate nalgebra;

use std::collections::HashMap;

use common;
use glium::backend::glutin_backend::GlutinFacade;
use glium::Program;
use glium::Surface;
use self::nalgebra::{Matrix4, PerspectiveMatrix3};

use common::{Scene, Vertex8f32};
implement_vertex!(Vertex8f32, position, normal, texcoord);

pub struct Renderer {
	pub index_buffer: glium::index::NoIndices,
	pub modelview_matrix_array: [[f32; 4]; 4],
	pub program: Program,
	pub projection_matrix: Matrix4<f32>,
    pub scene: Scene,
    pub textures: HashMap<String, glium::texture::CompressedSrgbTexture2d>,
    pub vertex_buffers: Vec<glium::vertex::VertexBuffer<common::Vertex8f32>>,
}

impl Renderer {
    pub fn new(display: &GlutinFacade, scene: Scene) -> Renderer {

    let mut vertex_buffers: Vec<glium::vertex::VertexBuffer<common::Vertex8f32>> = Vec::with_capacity(scene.meshes.len());

    for i in 0..scene.meshes.len() {
        vertex_buffers.push(glium::vertex::VertexBuffer::new(display, &scene.meshes[i].vertices).unwrap());
    }

    let index_buffer: glium::index::NoIndices =
        glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    if scene.shaders.len() == 0 {
        panic!("No shaders loaded");
    }

	let mut textures: HashMap<String, glium::texture::CompressedSrgbTexture2d> = HashMap::new();

	for i in 0..scene.images.len() {
		//TODO: determine image format by name extension if nessisary
		//let image = image::load_from_memory_with_format(&scene.images[i].image, image::PNG).unwrap().to_rgba();
		let image = image::load_from_memory(&scene.images[i].image).unwrap().to_rgba();

	    let image_dimensions = image.dimensions();
	    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(),
	                                                                   image_dimensions);
	    let opengl_texture: glium::texture::CompressedSrgbTexture2d = glium::texture::CompressedSrgbTexture2d::new(display, image).unwrap();
		textures.insert(scene.images[i].name.clone(), opengl_texture);
	}

    // Load the first shader in the database by default
    // TODO: load from config settings table?
    let shader_index = 0;

    // println!("Using glsl version {}", glsl_version);

    let program: Program = program!(display,
    	/*
			110 => {
				vertex: &scene.shaders[shader_index].vertex_source_110,
				fragment: &scene.shaders[shader_index].fragment_source_110,
			},
			120 => {
				vertex: &scene.shaders[shader_index].vertex_source_120,
				fragment: &scene.shaders[shader_index].fragment_source_120,
			},
			130 => {
				vertex: &scene.shaders[shader_index].vertex_source_130,
				fragment: &scene.shaders[shader_index].fragment_source_130,
			},
			*/
			140 => {
				vertex: &scene.shaders[shader_index].vertex_source_140,
				fragment: &scene.shaders[shader_index].fragment_source_140,
			},
			/*
			150 => {
				vertex: &scene.shaders[shader_index].vertex_source_150,
				fragment: &scene.shaders[shader_index].fragment_source_150,
			},
			300 => {
				vertex: &scene.shaders[shader_index].vertex_source_300,
				fragment: &scene.shaders[shader_index].fragment_source_300,
			},
			330 => {
				vertex: &scene.shaders[shader_index].vertex_source_330,
				fragment: &scene.shaders[shader_index].fragment_source_330,
			},
			400 => {
				vertex: &scene.shaders[shader_index].vertex_source_400,
				fragment: &scene.shaders[shader_index].fragment_source_400,
			},
			410 => {
				vertex: &scene.shaders[shader_index].vertex_source_410,
				fragment: &scene.shaders[shader_index].fragment_source_410,
			},
			420 => {
				vertex: &scene.shaders[shader_index].vertex_source_420,
				fragment: &scene.shaders[shader_index].fragment_source_420,
			},
			430 => {
				vertex: &scene.shaders[shader_index].vertex_source_430,
				fragment: &scene.shaders[shader_index].fragment_source_430,
			},
			100 es => {
				vertex: &scene.shaders[shader_index].vertex_source_100es,
				fragment: &scene.shaders[shader_index].fragment_source_100es,
			},
			300 es => {
				vertex: &scene.shaders[shader_index].vertex_source_300es,
				fragment: &scene.shaders[shader_index].fragment_source_300es,
			}, */
		)
        .unwrap();

    // Shader compilation no longer required
    display.release_shader_compiler();

    // Get the screen width and height in pixels
    let screen_width: u32;
    let screen_height: u32;
    match display.get_window() {
        Some(window) =>  {
        	let pixel_dimensions: (u32,u32) = window.get_inner_size_pixels().unwrap();
        	screen_width = pixel_dimensions.0;
        	screen_height = pixel_dimensions.1;
	    },
        None => {
            panic!("Error retrieving window when querying display size.");
        }
    }

    // Set up camera
    let projection_matrix = PerspectiveMatrix3::new(screen_width as f32 / screen_height as f32,
                                              45.0,
                                              0.1,
                                              1000.0);
    let projection_matrix_array: Matrix4<f32> = projection_matrix.to_matrix();

    let modelview_matrix_array = [[1.0f32, -0.0f32, -0.0f32, 0.0f32],
                                  [0.0f32, 1.0f32, -0.0f32, 0.0f32],
                                  [0.0f32, 0.0f32, 1.0f32, 0.0f32],
                                  [-5.0f32, -3.0f32, -12.0f32, 1.0f32]];
        Renderer {
        	index_buffer: index_buffer,
        	modelview_matrix_array: modelview_matrix_array,
        	program: program,
        	projection_matrix: projection_matrix_array,
        	scene: scene,
        	textures: textures,
        	vertex_buffers: vertex_buffers,
        }
    }

    pub fn render(&self, display: &GlutinFacade) {
		 let mut target = display.draw();
	 	// TODO: generate this texture instead of loading from sqlite
		let default_blank_texture = &self.textures["DEFAULT_BLANK_TEXTURE.png"];
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        for i in 0..self.vertex_buffers.len() as usize {
            let material_index: usize = self.scene.meshes[i].material_index.clone();
            let diffuse = self.scene.materials[material_index].diffuse.clone();
            let diffuse_texname: String =
                self.scene.materials[material_index].diffuse_texname.clone();
            let opengl_texture: &glium::texture::CompressedSrgbTexture2d;
            if diffuse_texname.len() == 0 {
                opengl_texture = &default_blank_texture;
            } else {
                match self.textures.get(&diffuse_texname) {
                	Some(t) => {
                		 opengl_texture = &t;
                	},
                	None => {
                		println!("Unable to load {}, using blank texture instead.", diffuse_texname);
                		opengl_texture = &default_blank_texture;
                	},
                }
            }
            let uniforms: glium::uniforms::UniformsStorage<_, _> = uniform! {
		        projection: *self.projection_matrix.as_ref(),
		        modelview: self.modelview_matrix_array,
		        light_position_worldspace: [2.0, 10.0, 1.0f32],
		        diffuse: diffuse,
		        diffuse_texture: opengl_texture,
		    };

            target.draw(&self.vertex_buffers[i],
                      &self.index_buffer,
                      &self.program,
                      &uniforms,
                      &Default::default())
                .unwrap();
        }
        target.finish().unwrap();
    }
}
<commit_msg>manual formatting changes since rustfmt is failing do to excessive macros<commit_after>// Copyright(C) 2016 Chris Liebert
extern crate glium;
extern crate image;
extern crate nalgebra;

use std::collections::HashMap;

use common;
use glium::backend::glutin_backend::GlutinFacade;
use glium::Program;
use glium::Surface;
use self::nalgebra::{Matrix4, PerspectiveMatrix3};

use common::{Scene, Vertex8f32};
implement_vertex!(Vertex8f32, position, normal, texcoord);

pub struct Renderer {
	pub index_buffer: glium::index::NoIndices,
	pub modelview_matrix_array: [[f32; 4]; 4],
	pub program: Program,
	pub projection_matrix: Matrix4<f32>,
	pub scene: Scene,
	pub textures: HashMap<String, glium::texture::CompressedSrgbTexture2d>,
	pub vertex_buffers: Vec<glium::vertex::VertexBuffer<common::Vertex8f32>>,
}

impl Renderer {
	pub fn new(display: &GlutinFacade, scene: Scene) -> Renderer {

		let mut vertex_buffers: Vec<glium::vertex::VertexBuffer<common::Vertex8f32>> = Vec::with_capacity(scene.meshes.len());

		for i in 0..scene.meshes.len() {
			vertex_buffers.push(glium::vertex::VertexBuffer::new(display, &scene.meshes[i].vertices).unwrap());
		}

		let index_buffer: glium::index::NoIndices =
			glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

		if scene.shaders.len() == 0 {
			panic!("No shaders loaded");
		}

		let mut textures: HashMap<String, glium::texture::CompressedSrgbTexture2d> = HashMap::new();

		for i in 0..scene.images.len() {
			//TODO: determine image format by name extension if nessisary
			//let image = image::load_from_memory_with_format(&scene.images[i].image, image::PNG).unwrap().to_rgba();
			let image = image::load_from_memory(&scene.images[i].image).unwrap().to_rgba();

			let image_dimensions = image.dimensions();
			let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(),
			                                                               image_dimensions);
			let opengl_texture: glium::texture::CompressedSrgbTexture2d = glium::texture::CompressedSrgbTexture2d::new(display, image).unwrap();
			textures.insert(scene.images[i].name.clone(), opengl_texture);
		}

		// Load the first shader in the database by default
		// TODO: load from config settings table?
		let shader_index = 0;

		// println!("Using glsl version {}", glsl_version);

		let program: Program = program!(display,
			/*
				110 => {
					vertex: &scene.shaders[shader_index].vertex_source_110,
					fragment: &scene.shaders[shader_index].fragment_source_110,
				},
				120 => {
					vertex: &scene.shaders[shader_index].vertex_source_120,
					fragment: &scene.shaders[shader_index].fragment_source_120,
				},
				130 => {
					vertex: &scene.shaders[shader_index].vertex_source_130,
					fragment: &scene.shaders[shader_index].fragment_source_130,
				},
				*/
				140 => {
					vertex: &scene.shaders[shader_index].vertex_source_140,
					fragment: &scene.shaders[shader_index].fragment_source_140,
				},
				/*
				150 => {
					vertex: &scene.shaders[shader_index].vertex_source_150,
					fragment: &scene.shaders[shader_index].fragment_source_150,
				},
				300 => {
					vertex: &scene.shaders[shader_index].vertex_source_300,
					fragment: &scene.shaders[shader_index].fragment_source_300,
				},
				330 => {
					vertex: &scene.shaders[shader_index].vertex_source_330,
					fragment: &scene.shaders[shader_index].fragment_source_330,
				},
				400 => {
					vertex: &scene.shaders[shader_index].vertex_source_400,
					fragment: &scene.shaders[shader_index].fragment_source_400,
				},
				410 => {
					vertex: &scene.shaders[shader_index].vertex_source_410,
					fragment: &scene.shaders[shader_index].fragment_source_410,
				},
				420 => {
					vertex: &scene.shaders[shader_index].vertex_source_420,
					fragment: &scene.shaders[shader_index].fragment_source_420,
				},
				430 => {
					vertex: &scene.shaders[shader_index].vertex_source_430,
					fragment: &scene.shaders[shader_index].fragment_source_430,
				},
				100 es => {
					vertex: &scene.shaders[shader_index].vertex_source_100es,
					fragment: &scene.shaders[shader_index].fragment_source_100es,
				},
				300 es => {
					vertex: &scene.shaders[shader_index].vertex_source_300es,
					fragment: &scene.shaders[shader_index].fragment_source_300es,
				}, */
			)
			.unwrap();

		// Shader compilation no longer required
		display.release_shader_compiler();

		// Get the screen width and height in pixels
		let screen_width: u32;
		let screen_height: u32;
		match display.get_window() {
			Some(window) =>  {
				let pixel_dimensions: (u32,u32) = window.get_inner_size_pixels().unwrap();
				screen_width = pixel_dimensions.0;
				screen_height = pixel_dimensions.1;
			},
			None => {
				panic!("Error retrieving window when querying display size.");
			}
		}

		// Set up camera
		let projection_matrix = PerspectiveMatrix3::new(screen_width as f32 / screen_height as f32,
		                                          45.0,
		                                          0.1,
		                                          1000.0);
		let projection_matrix_array: Matrix4<f32> = projection_matrix.to_matrix();

		let modelview_matrix_array = [[1.0f32, -0.0f32, -0.0f32, 0.0f32],
		                          [0.0f32, 1.0f32, -0.0f32, 0.0f32],
		                          [0.0f32, 0.0f32, 1.0f32, 0.0f32],
		                          [-5.0f32, -3.0f32, -12.0f32, 1.0f32]];
		Renderer {
			index_buffer: index_buffer,
			modelview_matrix_array: modelview_matrix_array,
			program: program,
			projection_matrix: projection_matrix_array,
			scene: scene,
			textures: textures,
			vertex_buffers: vertex_buffers,
		}
	}

	pub fn render(&self, display: &GlutinFacade) {
		let mut target = display.draw();
		// TODO: generate this texture instead of loading from sqlite
		let default_blank_texture = &self.textures["DEFAULT_BLANK_TEXTURE.png"];
		target.clear_color(0.0, 0.0, 0.0, 1.0);
		for i in 0..self.vertex_buffers.len() as usize {
			let material_index: usize = self.scene.meshes[i].material_index.clone();
			let diffuse = self.scene.materials[material_index].diffuse.clone();
			let diffuse_texname: String =
				self.scene.materials[material_index].diffuse_texname.clone();
			let opengl_texture: &glium::texture::CompressedSrgbTexture2d;
			if diffuse_texname.len() == 0 {
				opengl_texture = &default_blank_texture;
			} else {
				match self.textures.get(&diffuse_texname) {
					Some(t) => {
						opengl_texture = &t;
					},
					None => {
						println!("Unable to load {}, using blank texture instead.", diffuse_texname);
						opengl_texture = &default_blank_texture;
					},
				}
			}
			let uniforms: glium::uniforms::UniformsStorage<_, _> = uniform! {
				projection: *self.projection_matrix.as_ref(),
				modelview: self.modelview_matrix_array,
				light_position_worldspace: [2.0, 10.0, 1.0f32],
				diffuse: diffuse,
				diffuse_texture: opengl_texture,
			};

			target.draw(&self.vertex_buffers[i],
				&self.index_buffer,
				&self.program,
				&uniforms,
				&Default::default())
				.unwrap();
		}
		target.finish().unwrap();
	}
}
<|endoftext|>