<commit_before>use sodiumoxide::crypto::sign::ed25519::{PublicKey as PublicKeySodium,
                                         SecretKey as SecretKeySodium, Seed as SeedSodium,
                                         Signature as SignatureSodium, sign_detached,
                                         verify_detached, gen_keypair as gen_keypair_sodium,
                                         keypair_from_seed};
use sodiumoxide::crypto::hash::sha256::{Digest, hash as hash_sodium};
use serde::{Serialize, Serializer};
use serde::de::{self, Visitor, Deserialize, Deserializer};
use hex::{ToHex, FromHex};

use std::default::Default;
use std::ops::{Index, Range, RangeFrom, RangeTo, RangeFull};
use std::fmt;

use storage::bytes_to_hex;

pub use sodiumoxide::init;
pub use sodiumoxide::crypto::sign::ed25519::{PUBLICKEYBYTES as PUBLIC_KEY_LENGTH,
                                             SECRETKEYBYTES as SECRET_KEY_LENGTH,
                                             SIGNATUREBYTES as SIGNATURE_LENGTH,
                                             SEEDBYTES as SEED_LENGTH};
pub use sodiumoxide::crypto::hash::sha256::DIGESTBYTES as HASH_SIZE;

pub use encoding::serialize::{FromHexError, HexValue};

const BYTES_IN_DEBUG: usize = 4;

pub fn sign(m: &[u8], secret_key: &SecretKey) -> Signature {
    let sodium_signature = sign_detached(m, &secret_key.0);
    Signature(sodium_signature)
}

pub fn gen_keypair_from_seed(seed: &Seed) -> (PublicKey, SecretKey) {
    let (sod_pub_key, sod_secr_key) = keypair_from_seed(&seed.0);
    (PublicKey(sod_pub_key), SecretKey(sod_secr_key))
}

pub fn gen_keypair() -> (PublicKey, SecretKey) {
    let (pubkey, secrkey) = gen_keypair_sodium();
    (PublicKey(pubkey), SecretKey(secrkey))
}

pub fn verify(sig: &Signature, m: &[u8], pubkey: &PublicKey) -> bool {
    verify_detached(&sig.0, m, &pubkey.0)
}

pub fn hash(m: &[u8]) -> Hash {
    let dig = hash_sodium(m);
    Hash(dig)
}

macro_rules! implement_public_sodium_wrapper {
    ($name:ident, $name_from:ident, $size:expr) => (
    #[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
    pub struct $name($name_from);

    impl $name {
        pub fn zero() -> Self {
            $name::new([0; $size])
        }
    }

    impl $name {
        pub fn new(ba: [u8; $size]) -> $name {
            $name($name_from(ba))
        }

        pub fn from_slice(bs: &[u8]) -> Option<$name> {
            $name_from::from_slice(bs).map($name)
        }
    }
    impl AsRef<[u8]> for $name {
        fn as_ref(&self) -> &[u8] {
            self.0.as_ref()
        }
    }

    impl fmt::Debug for $name {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let inner = &self.0;
            let slice = &inner.0;
            let hex_bytes = bytes_to_hex(&slice[0..BYTES_IN_DEBUG]);
            let type_str = stringify!($name);
            write!(f, "\"{}({}...)\"",type_str, hex_bytes)
        }
    }
    )
}

macro_rules! implement_private_sodium_wrapper {
    ($name:ident, $name_from:ident, $size:expr) => (
    #[derive(Clone, PartialEq, Eq)]
    pub struct $name($name_from);

    impl $name {
        pub fn zero() -> Self {
            $name::new([0; $size])
        }
    }

    impl $name {
        pub fn new(ba: [u8; $size]) -> $name {
            $name($name_from(ba))
        }

        pub fn from_slice(bs: &[u8]) -> Option<$name> {
            $name_from::from_slice(bs).map($name)
        }
    }
    impl fmt::Debug for $name {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let inner = &self.0;
            let slice = &inner.0;
            let hex_bytes = bytes_to_hex(&slice[0..BYTES_IN_DEBUG]);
            let type_str = stringify!($name);
            write!(f, "\"{}({}...)\"",type_str, hex_bytes)
        }
    }
    )
}

implement_public_sodium_wrapper! {PublicKey, PublicKeySodium, PUBLIC_KEY_LENGTH}
implement_public_sodium_wrapper! {Hash, Digest, HASH_SIZE}
implement_public_sodium_wrapper! {Signature, SignatureSodium, SIGNATURE_LENGTH}
implement_private_sodium_wrapper! {SecretKey, SecretKeySodium, SECRET_KEY_LENGTH}
implement_private_sodium_wrapper! {Seed, SeedSodium, SEED_LENGTH}

macro_rules! implement_serde {
($name:ident) => (
    impl HexValue for $name {
        fn to_hex(&self) -> String {
            let inner = &self.0;
            inner.0.as_ref().to_hex()
        }
        fn from_hex<T: AsRef<str>>(v: T) -> Result<Self, FromHexError> {
            let bytes: Vec<u8> = FromHex::from_hex(v.as_ref())?;
            if let Some(self_value) = Self::from_slice(bytes.as_ref()) {
                Ok(self_value)
            } else {
                Err(FromHexError::InvalidHexLength)
            }
        }
    }

    impl Serialize for $name
    {
        fn serialize<S>(&self, ser:S) -> Result<S::Ok, S::Error>
        where S: Serializer
        {
            ser.serialize_str(&HexValue::to_hex(self))
        }
    }

    impl<'de> Deserialize<'de> for $name
    {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
        {
            struct HexVisitor;

            impl<'v> Visitor<'v> for HexVisitor
            {
                type Value = $name;
                fn expecting (&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                    write!(fmt, "expecting str.")
                }
                fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: de::Error
                {
                    $name::from_hex(s).map_err(|_| de::Error::custom("Invalid hex"))
                }
            }
            deserializer.deserialize_str(HexVisitor)
        }
    }
    )
}

implement_serde! {Hash}
implement_serde! {PublicKey}
implement_serde! {SecretKey}
implement_serde! {Seed}
implement_serde! {Signature}

impl HexValue for Vec<u8> {
    fn to_hex(&self) -> String {
        ToHex::to_hex(self)
    }
    fn from_hex<T: AsRef<str>>(v: T) -> Result<Self, FromHexError> {
        FromHex::from_hex(v.as_ref())
    }
}
macro_rules! implement_index_traits {
    ($newtype:ident) => (
        impl Index<Range<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: Range<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeTo<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeTo<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeFrom<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeFrom<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeFull> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeFull) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        })
}
implement_index_traits! {Hash}
implement_index_traits! {PublicKey}
implement_index_traits! {SecretKey}
implement_index_traits! {Seed}
implement_index_traits! {Signature}

impl Default for Hash {
    fn default() -> Hash {
        Hash::zero()
    }
}

#[cfg(test)]
mod tests {
    use super::{hash, gen_keypair, Hash, PublicKey, SecretKey, Seed, Signature};
    use super::HexValue;
    use serde_json;
    #[test]
    fn test_hash() {
        let h = hash(&[]);
        let h1 = Hash::from_hex(h.to_hex()).unwrap();
        assert_eq!(h1, h);
        let h = Hash::zero();
        assert_eq!(*h.as_ref(), [0; 32]);
    }

    #[test]
    fn test_keys() {
        let (p, s) = gen_keypair();
        let p1 = PublicKey::from_hex(p.to_hex()).unwrap();
        let s1 = SecretKey::from_hex(s.to_hex()).unwrap();
        assert_eq!(p1, p);
        assert_eq!(s1, s);
    }

    #[test]
    fn test_ser_deser() {
        let h = Hash::new([207; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = PublicKey::new([208; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = Signature::new([209; 64]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = Seed::new([210; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = SecretKey::new([211; 64]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);
    }

    #[test]
    fn test_range_sodium() {
        let h = hash(&[]);
        let sub_range = &h[10..20];
        assert_eq!(&[244u8, 200, 153, 111, 185, 36, 39, 174, 65, 228],
                   sub_range);
    }
}
<commit_msg>Add panic when libsodium initialization failed<commit_after>use sodiumoxide::crypto::sign::ed25519::{PublicKey as PublicKeySodium,
                                         SecretKey as SecretKeySodium, Seed as SeedSodium,
                                         Signature as SignatureSodium, sign_detached,
                                         verify_detached, gen_keypair as gen_keypair_sodium,
                                         keypair_from_seed};
use sodiumoxide::crypto::hash::sha256::{Digest, hash as hash_sodium};
use sodiumoxide;
use serde::{Serialize, Serializer};
use serde::de::{self, Visitor, Deserialize, Deserializer};
use hex::{ToHex, FromHex};

use std::default::Default;
use std::ops::{Index, Range, RangeFrom, RangeTo, RangeFull};
use std::fmt;

use storage::bytes_to_hex;

pub use sodiumoxide::crypto::sign::ed25519::{PUBLICKEYBYTES as PUBLIC_KEY_LENGTH,
                                             SECRETKEYBYTES as SECRET_KEY_LENGTH,
                                             SIGNATUREBYTES as SIGNATURE_LENGTH,
                                             SEEDBYTES as SEED_LENGTH};
pub use sodiumoxide::crypto::hash::sha256::DIGESTBYTES as HASH_SIZE;

pub use encoding::serialize::{FromHexError, HexValue};

const BYTES_IN_DEBUG: usize = 4;

pub fn sign(m: &[u8], secret_key: &SecretKey) -> Signature {
    let sodium_signature = sign_detached(m, &secret_key.0);
    Signature(sodium_signature)
}

pub fn gen_keypair_from_seed(seed: &Seed) -> (PublicKey, SecretKey) {
    let (sod_pub_key, sod_secr_key) = keypair_from_seed(&seed.0);
    (PublicKey(sod_pub_key), SecretKey(sod_secr_key))
}

pub fn gen_keypair() -> (PublicKey, SecretKey) {
    let (pubkey, secrkey) = gen_keypair_sodium();
    (PublicKey(pubkey), SecretKey(secrkey))
}

pub fn verify(sig: &Signature, m: &[u8], pubkey: &PublicKey) -> bool {
    verify_detached(&sig.0, m, &pubkey.0)
}

pub fn hash(m: &[u8]) -> Hash {
    let dig = hash_sodium(m);
    Hash(dig)
}

pub fn init() {
    if !sodiumoxide::init() {
        panic!("Cryptographic library hasn't initialized.");
    }
}

macro_rules! implement_public_sodium_wrapper {
    ($name:ident, $name_from:ident, $size:expr) => (
    #[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
    pub struct $name($name_from);

    impl $name {
        pub fn zero() -> Self {
            $name::new([0; $size])
        }
    }

    impl $name {
        pub fn new(ba: [u8; $size]) -> $name {
            $name($name_from(ba))
        }

        pub fn from_slice(bs: &[u8]) -> Option<$name> {
            $name_from::from_slice(bs).map($name)
        }
    }
    impl AsRef<[u8]> for $name {
        fn as_ref(&self) -> &[u8] {
            self.0.as_ref()
        }
    }

    impl fmt::Debug for $name {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let inner = &self.0;
            let slice = &inner.0;
            let hex_bytes = bytes_to_hex(&slice[0..BYTES_IN_DEBUG]);
            let type_str = stringify!($name);
            write!(f, "\"{}({}...)\"",type_str, hex_bytes)
        }
    }
    )
}

macro_rules! implement_private_sodium_wrapper {
    ($name:ident, $name_from:ident, $size:expr) => (
    #[derive(Clone, PartialEq, Eq)]
    pub struct $name($name_from);

    impl $name {
        pub fn zero() -> Self {
            $name::new([0; $size])
        }
    }

    impl $name {
        pub fn new(ba: [u8; $size]) -> $name {
            $name($name_from(ba))
        }

        pub fn from_slice(bs: &[u8]) -> Option<$name> {
            $name_from::from_slice(bs).map($name)
        }
    }
    impl fmt::Debug for $name {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let inner = &self.0;
            let slice = &inner.0;
            let hex_bytes = bytes_to_hex(&slice[0..BYTES_IN_DEBUG]);
            let type_str = stringify!($name);
            write!(f, "\"{}({}...)\"",type_str, hex_bytes)
        }
    }
    )
}

implement_public_sodium_wrapper! {PublicKey, PublicKeySodium, PUBLIC_KEY_LENGTH}
implement_public_sodium_wrapper! {Hash, Digest, HASH_SIZE}
implement_public_sodium_wrapper! {Signature, SignatureSodium, SIGNATURE_LENGTH}
implement_private_sodium_wrapper! {SecretKey, SecretKeySodium, SECRET_KEY_LENGTH}
implement_private_sodium_wrapper! {Seed, SeedSodium, SEED_LENGTH}

macro_rules! implement_serde {
($name:ident) => (
    impl HexValue for $name {
        fn to_hex(&self) -> String {
            let inner = &self.0;
            inner.0.as_ref().to_hex()
        }
        fn from_hex<T: AsRef<str>>(v: T) -> Result<Self, FromHexError> {
            let bytes: Vec<u8> = FromHex::from_hex(v.as_ref())?;
            if let Some(self_value) = Self::from_slice(bytes.as_ref()) {
                Ok(self_value)
            } else {
                Err(FromHexError::InvalidHexLength)
            }
        }
    }

    impl Serialize for $name
    {
        fn serialize<S>(&self, ser:S) -> Result<S::Ok, S::Error>
        where S: Serializer
        {
            ser.serialize_str(&HexValue::to_hex(self))
        }
    }

    impl<'de> Deserialize<'de> for $name
    {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
        {
            struct HexVisitor;

            impl<'v> Visitor<'v> for HexVisitor
            {
                type Value = $name;
                fn expecting (&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                    write!(fmt, "expecting str.")
                }
                fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: de::Error
                {
                    $name::from_hex(s).map_err(|_| de::Error::custom("Invalid hex"))
                }
            }
            deserializer.deserialize_str(HexVisitor)
        }
    }
    )
}

implement_serde! {Hash}
implement_serde! {PublicKey}
implement_serde! {SecretKey}
implement_serde! {Seed}
implement_serde! {Signature}

impl HexValue for Vec<u8> {
    fn to_hex(&self) -> String {
        ToHex::to_hex(self)
    }
    fn from_hex<T: AsRef<str>>(v: T) -> Result<Self, FromHexError> {
        FromHex::from_hex(v.as_ref())
    }
}
macro_rules! implement_index_traits {
    ($newtype:ident) => (
        impl Index<Range<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: Range<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeTo<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeTo<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeFrom<usize>> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeFrom<usize>) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        }
        impl Index<RangeFull> for $newtype {
            type Output = [u8];
            fn index(&self, _index: RangeFull) -> &[u8] {
                let inner  = &self.0;
                inner.0.index(_index)
            }
        })
}
implement_index_traits! {Hash}
implement_index_traits! {PublicKey}
implement_index_traits! {SecretKey}
implement_index_traits! {Seed}
implement_index_traits! {Signature}

impl Default for Hash {
    fn default() -> Hash {
        Hash::zero()
    }
}

#[cfg(test)]
mod tests {
    use super::{hash, gen_keypair, Hash, PublicKey, SecretKey, Seed, Signature};
    use super::HexValue;
    use serde_json;
    #[test]
    fn test_hash() {
        let h = hash(&[]);
        let h1 = Hash::from_hex(h.to_hex()).unwrap();
        assert_eq!(h1, h);
        let h = Hash::zero();
        assert_eq!(*h.as_ref(), [0; 32]);
    }

    #[test]
    fn test_keys() {
        let (p, s) = gen_keypair();
        let p1 = PublicKey::from_hex(p.to_hex()).unwrap();
        let s1 = SecretKey::from_hex(s.to_hex()).unwrap();
        assert_eq!(p1, p);
        assert_eq!(s1, s);
    }

    #[test]
    fn test_ser_deser() {
        let h = Hash::new([207; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = PublicKey::new([208; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = Signature::new([209; 64]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = Seed::new([210; 32]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);

        let h = SecretKey::new([211; 64]);
        let json_h = serde_json::to_string(&h).unwrap();
        let h1 = serde_json::from_str(&json_h).unwrap();
        assert_eq!(h, h1);
    }

    #[test]
    fn test_range_sodium() {
        let h = hash(&[]);
        let sub_range = &h[10..20];
        assert_eq!(&[244u8, 200, 153, 111, 185, 36, 39, 174, 65, 228],
                   sub_range);
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::net::SocketAddr;
use std::collections::VecDeque;
use time::{get_time, Timespec};

use mio;

use super::messages::RawMessage;

use super::node::RequestData;
use super::crypto::PublicKey;

mod network;
mod connection;

pub use self::network::{Network, NetworkConfiguration, PeerId, EventSet};

pub type EventsConfiguration = mio::EventLoopConfig;

pub type EventLoop = mio::EventLoop<MioAdapter>;

// FIXME: move this into node module
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum Timeout {
    Status,
    Round(u64, u32),
    Request(RequestData, Option<PublicKey>),
    PeerExchange,
}

pub struct InternalMessage;

pub enum Event {
    Incoming(RawMessage),
    Internal(InternalMessage),
    Timeout(Timeout),
    Error(io::Error),
    Terminate,
}

pub struct Events {
    event_loop: EventLoop,
    queue: MioAdapter,
}

pub struct MioAdapter {
    events: VecDeque<Event>,
    network: Network,
}

impl MioAdapter {
    fn new(network: Network) -> MioAdapter {
        MioAdapter {
            // FIXME: configurable capacity?
            events: VecDeque::new(),
            network: network,
        }
    }

    fn push(&mut self, event: Event) {
        self.events.push_back(event)
    }

    fn pop(&mut self) -> Option<Event> {
        self.events.pop_front()
    }
}

impl mio::Handler for MioAdapter {
    type Timeout = Timeout;
    type Message = InternalMessage;

    fn ready(&mut self, event_loop: &mut EventLoop, token: mio::Token, events: mio::EventSet) {
        // TODO: remove unwrap here
        while let Some(buf) = self.network.io(event_loop, token, events).unwrap() {
            self.push(Event::Incoming(RawMessage::new(buf)));
        }
    }

    fn notify(&mut self, _: &mut EventLoop, msg: Self::Message) {
        self.push(Event::Internal(msg));
    }

    fn timeout(&mut self, _: &mut EventLoop, timeout: Self::Timeout) {
        self.push(Event::Timeout(timeout));
    }

    fn interrupted(&mut self, _: &mut EventLoop) {
        self.push(Event::Terminate);
    }

    fn tick(&mut self, event_loop: &mut EventLoop) {
        self.network.tick(event_loop);
    }
}

pub trait Reactor {
    fn get_time(&self) -> Timespec;
    fn poll(&mut self) -> Event;
    fn bind(&mut self) -> ::std::io::Result<()>;
    fn send_to(&mut self, address: &SocketAddr, message: RawMessage) -> io::Result<()>;
    fn address(&self) -> SocketAddr;
    fn add_timeout(&mut self, timeout: Timeout, time: Timespec);
}

impl Events {
    pub fn with_config(config: EventsConfiguration, network: Network) -> io::Result<Events> {
        // TODO: using EventLoopConfig + capacity of queue
        Ok(Events {
            event_loop: EventLoop::configured(config)?,
            queue: MioAdapter::new(network),
        })
    }
}

impl Reactor for Events {
    fn get_time(&self) -> Timespec {
        get_time()
    }

    fn poll(&mut self) -> Event {
        loop {
            if let Some(event) = self.queue.pop() {
                return event;
            }
            if let Err(err) = self.event_loop.run_once(&mut self.queue, None) {
                self.queue.push(Event::Error(err))
            }
        }
    }

    fn bind(&mut self) -> ::std::io::Result<()> {
        self.queue.network.bind(&mut self.event_loop)
    }

    fn send_to(&mut self, address: &SocketAddr, message: RawMessage) -> io::Result<()> {
        self.queue.network.send_to(&mut self.event_loop, address, message)
    }

    fn address(&self) -> SocketAddr {
        *self.queue.network.address()
    }

    fn add_timeout(&mut self, timeout: Timeout, time: Timespec) {
        let ms = (time - self.get_time()).num_milliseconds();
        if ms < 0 {
            self.queue.push(Event::Timeout(timeout))
        } else {
            // FIXME: remove unwrap here
            // TODO: use mio::Timeout
            self.event_loop.timeout_ms(timeout, ms as u64).unwrap();
        }
    }
}

#[cfg(test)]
mod tests {
    use std::{time, thread};
    use std::net::SocketAddr;

    use time::Duration;

    use super::{Events, Reactor, EventsConfiguration, Event, Timeout};
    use super::{Network, NetworkConfiguration};

    use ::messages::{MessageWriter, RawMessage};
    use ::crypto::gen_keypair;

    impl Events {
        fn with_addr(addr: SocketAddr) -> Events {
            let network = Network::with_config(NetworkConfiguration {
                listen_address: addr,
                max_connections: 256,
                tcp_nodelay: true,
                tcp_keep_alive: None

            });
            Events::with_config(EventsConfiguration::new(), network).unwrap()
        }

        fn wait_for_msg(&mut self, timeout: Duration) -> Option<RawMessage> {
            let time = self.get_time() + timeout;
            self.add_timeout(Timeout::Status, time);
            loop {
                match self.poll() {
                    Event::Incoming(msg) => return Some(msg),
                    Event::Timeout(_) => return None,
                    Event::Error(_) => return None,
                    _ => {}
                }
            }
        }

        fn wait_for_bind(&mut self) {
            self.bind().unwrap();
            thread::sleep(time::Duration::from_millis(1000));
        }

        fn process_events(&mut self, timeout: Duration) {
            let time = self.get_time() + timeout;
            self.add_timeout(Timeout::Status, time);
            loop {
                match self.poll() {
                    Event::Timeout(_) => break,
                    Event::Error(_) => return,
                    _ => {}
                }
            }
        }
    }

    fn gen_message(id: u16, len: usize) -> RawMessage {
        let writer = MessageWriter::new(id, len);
        RawMessage::new(writer.sign(&gen_keypair().1))
    }

    #[test]
    fn big_message() {
        let addrs: [SocketAddr; 2] = ["127.0.0.1:8200".parse().unwrap(),
                                      "127.0.0.1:8201".parse().unwrap()];

        let m1 = gen_message(15, 10000000);
        let m2 = gen_message(16, 400);

        let t1;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            t1 = thread::spawn(move || {
                let mut e = Events::with_addr(addrs[0].clone());
                e.wait_for_bind();
                e.send_to(&addrs[1], m1).unwrap();
                assert_eq!(e.wait_for_msg(Duration::milliseconds(1000)), Some(m2));
                e.process_events(Duration::milliseconds(5000));
            });
        }

        let t2;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            t2 = thread::spawn(move || {
                let mut e = Events::with_addr(addrs[1].clone());
                e.wait_for_bind();
                e.send_to(&addrs[0], m2).unwrap();
                assert_eq!(e.wait_for_msg(Duration::milliseconds(30000)), Some(m1));
            });
        }

        t2.join().unwrap();
        t1.join().unwrap();
    }

    #[test]
    fn reconnect() {
        let addrs: [SocketAddr; 2] = ["127.0.0.1:9000".parse().unwrap(),
                                      "127.0.0.1:9001".parse().unwrap()];

        let m1 = gen_message(15, 250);
        let m2 = gen_message(16, 400);
        let m3 = gen_message(17, 600);

        let t1;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            let m3 = m3.clone();
            t1 = thread::spawn(move || {
                {
                    let mut e = Events::with_addr(addrs[0].clone());
                    e.wait_for_bind();
                    println!("t1: connection opened");
                    println!("t1: send m1 to t2");
                    e.send_to(&addrs[1], m1).unwrap();
                    println!("t1: wait for m2");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m2));
                    println!("t1: received m2 from t2");
                    e.process_events(Duration::milliseconds(100));
                }
                println!("t1: connection closed");
                {
                    let mut e = Events::with_addr(addrs[0].clone());
                    e.wait_for_bind();
                    println!("t1: connection reopened");
                    println!("t1: send m3 to t2");
                    e.send_to(&addrs[1], m3.clone()).unwrap();
                    println!("t1: wait for m3");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m3));
                    e.process_events(Duration::milliseconds(100));
                    println!("t1: received m3 from t2");
                }
                println!("t1: connection closed");
            });
        }

        let t2;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            let m3 = m3.clone();
            t2 = thread::spawn(move || {
                {
                    let mut e = Events::with_addr(addrs[1].clone());
                    e.wait_for_bind();
                    println!("t2: connection opened");
                    println!("t2: send m2 to t1");
                    e.send_to(&addrs[0], m2).unwrap();
                    println!("t2: wait for m1");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m1));
                    println!("t2: received m1 from t1");
                    println!("t2: wait for m3");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m3.clone()));
                    println!("t2: received m3 from t1");
                    e.process_events(Duration::milliseconds(100));
                    drop(e);
                }
                println!("t2: connection closed");
                {
                    println!("t2: connection reopened");
                    let mut e = Events::with_addr(addrs[1].clone());
                    e.wait_for_bind();
                    println!("t2: send m3 to t1");
                    e.send_to(&addrs[0], m3.clone()).unwrap();
                    e.process_events(Duration::milliseconds(100));
                }
                println!("t2: connection closed");
            });
        }

        t2.join().unwrap();
        t1.join().unwrap();
    }
}
<commit_msg>Increase process events timeout<commit_after>use std::io;
use std::net::SocketAddr;
use std::collections::VecDeque;
use time::{get_time, Timespec};

use mio;

use super::messages::RawMessage;

use super::node::RequestData;
use super::crypto::PublicKey;

mod network;
mod connection;

pub use self::network::{Network, NetworkConfiguration, PeerId, EventSet};

pub type EventsConfiguration = mio::EventLoopConfig;

pub type EventLoop = mio::EventLoop<MioAdapter>;

// FIXME: move this into node module
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum Timeout {
    Status,
    Round(u64, u32),
    Request(RequestData, Option<PublicKey>),
    PeerExchange,
}

pub struct InternalMessage;

pub enum Event {
    Incoming(RawMessage),
    Internal(InternalMessage),
    Timeout(Timeout),
    Error(io::Error),
    Terminate,
}

pub struct Events {
    event_loop: EventLoop,
    queue: MioAdapter,
}

pub struct MioAdapter {
    events: VecDeque<Event>,
    network: Network,
}

impl MioAdapter {
    fn new(network: Network) -> MioAdapter {
        MioAdapter {
            // FIXME: configurable capacity?
            events: VecDeque::new(),
            network: network,
        }
    }

    fn push(&mut self, event: Event) {
        self.events.push_back(event)
    }

    fn pop(&mut self) -> Option<Event> {
        self.events.pop_front()
    }
}

impl mio::Handler for MioAdapter {
    type Timeout = Timeout;
    type Message = InternalMessage;

    fn ready(&mut self, event_loop: &mut EventLoop, token: mio::Token, events: mio::EventSet) {
        // TODO: remove unwrap here
        while let Some(buf) = self.network.io(event_loop, token, events).unwrap() {
            self.push(Event::Incoming(RawMessage::new(buf)));
        }
    }

    fn notify(&mut self, _: &mut EventLoop, msg: Self::Message) {
        self.push(Event::Internal(msg));
    }

    fn timeout(&mut self, _: &mut EventLoop, timeout: Self::Timeout) {
        self.push(Event::Timeout(timeout));
    }

    fn interrupted(&mut self, _: &mut EventLoop) {
        self.push(Event::Terminate);
    }

    fn tick(&mut self, event_loop: &mut EventLoop) {
        self.network.tick(event_loop);
    }
}

pub trait Reactor {
    fn get_time(&self) -> Timespec;
    fn poll(&mut self) -> Event;
    fn bind(&mut self) -> ::std::io::Result<()>;
    fn send_to(&mut self, address: &SocketAddr, message: RawMessage) -> io::Result<()>;
    fn address(&self) -> SocketAddr;
    fn add_timeout(&mut self, timeout: Timeout, time: Timespec);
}

impl Events {
    pub fn with_config(config: EventsConfiguration, network: Network) -> io::Result<Events> {
        // TODO: using EventLoopConfig + capacity of queue
        Ok(Events {
            event_loop: EventLoop::configured(config)?,
            queue: MioAdapter::new(network),
        })
    }
}

impl Reactor for Events {
    fn get_time(&self) -> Timespec {
        get_time()
    }

    fn poll(&mut self) -> Event {
        loop {
            if let Some(event) = self.queue.pop() {
                return event;
            }
            if let Err(err) = self.event_loop.run_once(&mut self.queue, None) {
                self.queue.push(Event::Error(err))
            }
        }
    }

    fn bind(&mut self) -> ::std::io::Result<()> {
        self.queue.network.bind(&mut self.event_loop)
    }

    fn send_to(&mut self, address: &SocketAddr, message: RawMessage) -> io::Result<()> {
        self.queue.network.send_to(&mut self.event_loop, address, message)
    }

    fn address(&self) -> SocketAddr {
        *self.queue.network.address()
    }

    fn add_timeout(&mut self, timeout: Timeout, time: Timespec) {
        let ms = (time - self.get_time()).num_milliseconds();
        if ms < 0 {
            self.queue.push(Event::Timeout(timeout))
        } else {
            // FIXME: remove unwrap here
            // TODO: use mio::Timeout
            self.event_loop.timeout_ms(timeout, ms as u64).unwrap();
        }
    }
}

#[cfg(test)]
mod tests {
    use std::{time, thread};
    use std::net::SocketAddr;

    use time::Duration;

    use super::{Events, Reactor, EventsConfiguration, Event, Timeout};
    use super::{Network, NetworkConfiguration};

    use ::messages::{MessageWriter, RawMessage};
    use ::crypto::gen_keypair;

    impl Events {
        fn with_addr(addr: SocketAddr) -> Events {
            let network = Network::with_config(NetworkConfiguration {
                listen_address: addr,
                max_connections: 256,
                tcp_nodelay: true,
                tcp_keep_alive: None

            });
            Events::with_config(EventsConfiguration::new(), network).unwrap()
        }

        fn wait_for_msg(&mut self, timeout: Duration) -> Option<RawMessage> {
            let time = self.get_time() + timeout;
            self.add_timeout(Timeout::Status, time);
            loop {
                match self.poll() {
                    Event::Incoming(msg) => return Some(msg),
                    Event::Timeout(_) => return None,
                    Event::Error(_) => return None,
                    _ => {}
                }
            }
        }

        fn wait_for_bind(&mut self) {
            self.bind().unwrap();
            thread::sleep(time::Duration::from_millis(1000));
        }

        fn process_events(&mut self, timeout: Duration) {
            let time = self.get_time() + timeout;
            self.add_timeout(Timeout::Status, time);
            loop {
                match self.poll() {
                    Event::Timeout(_) => break,
                    Event::Error(_) => return,
                    _ => {}
                }
            }
        }
    }

    fn gen_message(id: u16, len: usize) -> RawMessage {
        let writer = MessageWriter::new(id, len);
        RawMessage::new(writer.sign(&gen_keypair().1))
    }

    #[test]
    fn big_message() {
        let addrs: [SocketAddr; 2] = ["127.0.0.1:8200".parse().unwrap(),
                                      "127.0.0.1:8201".parse().unwrap()];

        let m1 = gen_message(15, 10000000);
        let m2 = gen_message(16, 400);

        let t1;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            t1 = thread::spawn(move || {
                let mut e = Events::with_addr(addrs[0].clone());
                e.wait_for_bind();
                e.send_to(&addrs[1], m1).unwrap();
                assert_eq!(e.wait_for_msg(Duration::milliseconds(1000)), Some(m2));
                e.process_events(Duration::milliseconds(10000));
            });
        }

        let t2;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            t2 = thread::spawn(move || {
                let mut e = Events::with_addr(addrs[1].clone());
                e.wait_for_bind();
                e.send_to(&addrs[0], m2).unwrap();
                assert_eq!(e.wait_for_msg(Duration::milliseconds(30000)), Some(m1));
            });
        }

        t2.join().unwrap();
        t1.join().unwrap();
    }

    #[test]
    fn reconnect() {
        let addrs: [SocketAddr; 2] = ["127.0.0.1:9000".parse().unwrap(),
                                      "127.0.0.1:9001".parse().unwrap()];

        let m1 = gen_message(15, 250);
        let m2 = gen_message(16, 400);
        let m3 = gen_message(17, 600);

        let t1;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            let m3 = m3.clone();
            t1 = thread::spawn(move || {
                {
                    let mut e = Events::with_addr(addrs[0].clone());
                    e.wait_for_bind();
                    println!("t1: connection opened");
                    println!("t1: send m1 to t2");
                    e.send_to(&addrs[1], m1).unwrap();
                    println!("t1: wait for m2");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m2));
                    println!("t1: received m2 from t2");
                    e.process_events(Duration::milliseconds(100));
                }
                println!("t1: connection closed");
                {
                    let mut e = Events::with_addr(addrs[0].clone());
                    e.wait_for_bind();
                    println!("t1: connection reopened");
                    println!("t1: send m3 to t2");
                    e.send_to(&addrs[1], m3.clone()).unwrap();
                    println!("t1: wait for m3");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m3));
                    e.process_events(Duration::milliseconds(100));
                    println!("t1: received m3 from t2");
                }
                println!("t1: connection closed");
            });
        }

        let t2;
        {
            let m1 = m1.clone();
            let m2 = m2.clone();
            let m3 = m3.clone();
            t2 = thread::spawn(move || {
                {
                    let mut e = Events::with_addr(addrs[1].clone());
                    e.wait_for_bind();
                    println!("t2: connection opened");
                    println!("t2: send m2 to t1");
                    e.send_to(&addrs[0], m2).unwrap();
                    println!("t2: wait for m1");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m1));
                    println!("t2: received m1 from t1");
                    println!("t2: wait for m3");
                    assert_eq!(e.wait_for_msg(Duration::milliseconds(5000)), Some(m3.clone()));
                    println!("t2: received m3 from t1");
                    e.process_events(Duration::milliseconds(100));
                    drop(e);
                }
                println!("t2: connection closed");
                {
                    println!("t2: connection reopened");
                    let mut e = Events::with_addr(addrs[1].clone());
                    e.wait_for_bind();
                    println!("t2: send m3 to t1");
                    e.send_to(&addrs[0], m3.clone()).unwrap();
                    e.process_events(Duration::milliseconds(100));
                }
                println!("t2: connection closed");
            });
        }

        t2.join().unwrap();
        t1.join().unwrap();
    }
}
<|endoftext|>


<commit_before>//! Component range error

use core::fmt;

/// An error type indicating that a component provided to a method was out of range, causing a
/// failure.
// i64 is the narrowest type fitting all use cases. This eliminates the need for a type parameter.
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ComponentRange {
    /// Name of the component.
    pub name: &'static str,
    /// Minimum allowed value, inclusive.
    pub minimum: i64,
    /// Maximum allowed value, inclusive.
    pub maximum: i64,
    /// Value that was provided.
    pub value: i64,
    /// The minimum and/or maximum value is conditional on the value of other
    /// parameters.
    pub conditional_range: bool,
}

impl fmt::Display for ComponentRange {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{} must be in the range {}..={}",
            self.name, self.minimum, self.maximum
        )?;

        if self.conditional_range {
            f.write_str(", given values of other parameters")?;
        }

        Ok(())
    }
}

impl From<ComponentRange> for crate::Error {
    fn from(original: ComponentRange) -> Self {
        Self::ComponentRange(original)
    }
}

#[cfg(feature = "serde")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "serde")))]
impl serde::de::Expected for ComponentRange {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "a value in the range {}..={}",
            self.minimum, self.maximum
        )
    }
}

#[cfg(feature = "serde")]
impl ComponentRange {
    /// Obtain an "invalid value" error type for the deserializer.
    pub(crate) fn to_invalid_serde_value<'a, D: serde::Deserializer<'a>>(self) -> D::Error {
        <D::Error as serde::de::Error>::invalid_value(
            serde::de::Unexpected::Signed(self.value),
            &self,
        )
    }
}

#[cfg(feature = "std")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "std")))]
impl std::error::Error for ComponentRange {}
<commit_msg>Make `ComponentRange` details private<commit_after>//! Component range error

use core::fmt;

/// An error type indicating that a component provided to a method was out of range, causing a
/// failure.
// i64 is the narrowest type fitting all use cases. This eliminates the need for a type parameter.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ComponentRange {
    /// Name of the component.
    pub(crate) name: &'static str,
    /// Minimum allowed value, inclusive.
    pub(crate) minimum: i64,
    /// Maximum allowed value, inclusive.
    pub(crate) maximum: i64,
    /// Value that was provided.
    pub(crate) value: i64,
    /// The minimum and/or maximum value is conditional on the value of other
    /// parameters.
    pub(crate) conditional_range: bool,
}

impl ComponentRange {
    /// Obtain the name of the component whose value was out of range.
    pub const fn name(self) -> &'static str {
        self.name
    }
}

impl fmt::Display for ComponentRange {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{} must be in the range {}..={}",
            self.name, self.minimum, self.maximum
        )?;

        if self.conditional_range {
            f.write_str(", given values of other parameters")?;
        }

        Ok(())
    }
}

impl From<ComponentRange> for crate::Error {
    fn from(original: ComponentRange) -> Self {
        Self::ComponentRange(original)
    }
}

#[cfg(feature = "serde")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "serde")))]
impl serde::de::Expected for ComponentRange {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "a value in the range {}..={}",
            self.minimum, self.maximum
        )
    }
}

#[cfg(feature = "serde")]
impl ComponentRange {
    /// Obtain an "invalid value" error type for the deserializer.
    pub(crate) fn to_invalid_serde_value<'a, D: serde::Deserializer<'a>>(self) -> D::Error {
        <D::Error as serde::de::Error>::invalid_value(
            serde::de::Unexpected::Signed(self.value),
            &self,
        )
    }
}

#[cfg(feature = "std")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "std")))]
impl std::error::Error for ComponentRange {}
<|endoftext|>


<commit_before>use query_builder::*;
use super::{Expression, SelectableExpression, NonAggregate};
use types::Bool;

macro_rules! infix_predicate {
    ($name:ident, $operator:expr) => {
        #[derive(Debug, Clone, Copy)]
        pub struct $name<T, U> {
            left: T,
            right: U,
        }

        impl<T, U> $name<T, U> {
            pub fn new(left: T, right: U) -> Self {
                $name {
                    left: left,
                    right: right,
                }
            }
        }

        impl<T, U> Expression for $name<T, U> where
            T: Expression,
            U: Expression,
        {
            type SqlType = Bool;

            fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
                try!(self.left.to_sql(out));
                out.push_sql($operator);
                self.right.to_sql(out)
            }
        }

        impl<T, U, QS> SelectableExpression<QS> for $name<T, U> where
            T: SelectableExpression<QS>,
            U: SelectableExpression<QS>,
        {
        }

        impl<T, U> NonAggregate for $name<T, U> where
            T: NonAggregate,
            U: NonAggregate,
        {
        }
    }
}

infix_predicate!(And, " AND ");
infix_predicate!(Between, " BETWEEN ");
infix_predicate!(Eq, " = ");
infix_predicate!(Gt, " > ");
infix_predicate!(GtEq, " >= ");
infix_predicate!(Like, " LIKE ");
infix_predicate!(Lt, " < ");
infix_predicate!(LtEq, " <= ");
infix_predicate!(NotBetween, " NOT BETWEEN ");
infix_predicate!(NotEq, " != ");
infix_predicate!(NotLike, " NOT LIKE ");
infix_predicate!(Or, " OR ");

use query_source::Column;

impl<T, U> Changeset for Eq<T, U> where
    T: Column,
    U: SelectableExpression<T::Table>,
    Eq<T, U>: Expression,
{
    type Target = T::Table;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        try!(out.push_identifier(T::name()));
        out.push_sql(" = ");
        Expression::to_sql(&self.right, out)
    }
}
<commit_msg>Allow `infix_predicate` to be used from other crates<commit_after>#[macro_export]
macro_rules! infix_predicate {
    ($name:ident, $operator:expr) => {
        infix_predicate!($name, $operator, $crate::types::Bool);
    };

    ($name:ident, $operator:expr, $return_type:ty) => {
        #[derive(Debug, Clone, Copy)]
        pub struct $name<T, U> {
            left: T,
            right: U,
        }

        impl<T, U> $name<T, U> {
            pub fn new(left: T, right: U) -> Self {
                $name {
                    left: left,
                    right: right,
                }
            }
        }

        impl<T, U> $crate::expression::Expression for $name<T, U> where
            T: $crate::expression::Expression,
            U: $crate::expression::Expression,
        {
            type SqlType = $return_type;

            fn to_sql(&self, out: &mut $crate::query_builder::QueryBuilder) -> $crate::query_builder::BuildQueryResult {
                try!(self.left.to_sql(out));
                out.push_sql($operator);
                self.right.to_sql(out)
            }
        }

        impl<T, U, QS> $crate::expression::SelectableExpression<QS> for $name<T, U> where
            T: $crate::expression::SelectableExpression<QS>,
            U: $crate::expression::SelectableExpression<QS>,
        {
        }

        impl<T, U> $crate::expression::NonAggregate for $name<T, U> where
            T: $crate::expression::NonAggregate,
            U: $crate::expression::NonAggregate,
        {
        }
    }
}

infix_predicate!(And, " AND ");
infix_predicate!(Between, " BETWEEN ");
infix_predicate!(Eq, " = ");
infix_predicate!(Gt, " > ");
infix_predicate!(GtEq, " >= ");
infix_predicate!(Like, " LIKE ");
infix_predicate!(Lt, " < ");
infix_predicate!(LtEq, " <= ");
infix_predicate!(NotBetween, " NOT BETWEEN ");
infix_predicate!(NotEq, " != ");
infix_predicate!(NotLike, " NOT LIKE ");
infix_predicate!(Or, " OR ");

use query_source::Column;
use query_builder::*;
use super::{Expression, SelectableExpression};

impl<T, U> Changeset for Eq<T, U> where
    T: Column,
    U: SelectableExpression<T::Table>,
    Eq<T, U>: Expression,
{
    type Target = T::Table;

    fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult {
        try!(out.push_identifier(T::name()));
        out.push_sql(" = ");
        Expression::to_sql(&self.right, out)
    }
}
<|endoftext|>


<commit_before>#![allow(deprecated)]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate criterion;
#[macro_use]
extern crate cfg_if;
extern crate fasthash;

use std::mem;
use std::slice;

use criterion::{black_box, Criterion, ParameterizedBenchmark, Throughput};

use fasthash::*;

const KB: usize = 1024;
const SEED: u64 = 0x0123456789ABCDEF;
const PARAMS: [usize; 7] = [7, 8, 32, 256, KB, 4 * KB, 16 * KB];

lazy_static! {
    static ref DATA: Vec<u8> = (0..16 * KB).map(|b| b as u8).collect::<Vec<_>>();
}

fn bench_memory(c: &mut Criterion) {
    c.bench(
        "memory",
        ParameterizedBenchmark::new(
            "sum",
            move |b, &&size| {
                let s = unsafe {
                    slice::from_raw_parts(DATA.as_ptr() as *mut u32, size / mem::size_of::<u32>())
                };

                b.iter(|| {
                    black_box(s.iter().fold(0u64, |acc, &x| acc + x as u64));
                })
            },
            &PARAMS,
        )
        .throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash32(c: &mut Criterion) {
    c.bench(
        "hash32",
        ParameterizedBenchmark::new(
            "city::hash32",
            move |b, &&size| {
                b.iter(|| city::hash32_with_seed(&DATA.as_slice()[..size], SEED as u32));
            },
            &PARAMS,
        )
        .with_function("farm::hash32", move |b, &&size| {
            b.iter(|| farm::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("farm::finterprint32", move |b, &&size| {
            b.iter(|| farm::fingerprint32(&DATA[..size]));
        })
        .with_function("lookup3::hash32", move |b, &&size| {
            b.iter(|| lookup3::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur::hash32", move |b, &&size| {
            b.iter(|| murmur::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur::hash32_aligned", move |b, &&size| {
            b.iter(|| murmur::hash32_aligned_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32", move |b, &&size| {
            b.iter(|| murmur2::Hash32::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_a", move |b, &&size| {
            b.iter(|| murmur2::Hash32A::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_neutral", move |b, &&size| {
            b.iter(|| murmur2::Hash32Neutral::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_aligned", move |b, &&size| {
            b.iter(|| murmur2::Hash32Aligned::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur3::hash32", move |b, &&size| {
            b.iter(|| murmur3::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("spooky::hash32", move |b, &&size| {
            b.iter(|| spooky::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("xx::hash32", move |b, &&size| {
            b.iter(|| xx::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash64(c: &mut Criterion) {
    let mut bench = ParameterizedBenchmark::new(
        "city::hash64",
        move |b, &&size| {
            b.iter(|| city::hash64_with_seed(&DATA.as_slice()[..size], SEED));
        },
        &PARAMS,
    )
    .with_function("farm::hash64", move |b, &&size| {
        b.iter(|| farm::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("farm::finterprint64", move |b, &&size| {
        b.iter(|| farm::fingerprint32(&DATA[..size]));
    })
    .with_function("metro::hash64_1", move |b, &&size| {
        b.iter(|| metro::Hash64_1::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("metro::hash64_2", move |b, &&size| {
        b.iter(|| metro::Hash64_2::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("mum::hash64", move |b, &&size| {
        b.iter(|| mum::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("murmur2::hash64_x64", move |b, &&size| {
        b.iter(|| murmur2::Hash64_x64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("murmur2::hash64_x86", move |b, &&size| {
        b.iter(|| murmur2::Hash64_x86::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("sea::hash64", move |b, &&size| {
        b.iter(|| sea::hash64_with_seeds(&DATA[..size], SEED, SEED, SEED, SEED));
    })
    .with_function("spooky::hash64", move |b, &&size| {
        b.iter(|| spooky::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha0::hash64", move |b, &&size| {
        b.iter(|| t1ha0::Hash64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha1::hash64", move |b, &&size| {
        b.iter(|| t1ha1::Hash64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha2::hash64_atonce", move |b, &&size| {
        b.iter(|| t1ha2::Hash64AtOnce::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("xx::hash64", move |b, &&size| {
        b.iter(|| xx::hash64_with_seed(&DATA[..size], SEED));
    });

    if cfg!(target_feature = "sse4.2") {
        bench = bench
            .with_function("metro::crc::hash64_1", move |b, &&size| {
                b.iter(|| metro::crc::Hash64_1::hash_with_seed(&DATA[..size], SEED as u32));
            })
            .with_function("metro::crc::hash64_2", move |b, &&size| {
                b.iter(|| metro::crc::Hash64_2::hash_with_seed(&DATA[..size], SEED as u32));
            });
    }
    if cfg!(target_feature = "aes") {
        bench = bench.with_function("t1ha0::aes::hash64", move |b, &&size| {
            b.iter(|| t1ha0::aes::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }
    if cfg!(target_feature = "avx") {
        bench = bench.with_function("t1ha0::avx::hash64", move |b, &&size| {
            b.iter(|| t1ha0::avx::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }
    if cfg!(target_feature = "avx2") {
        bench = bench.with_function("t1ha0::avx2::hash64", move |b, &&size| {
            b.iter(|| t1ha0::avx2::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }

    c.bench(
        "hash64",
        bench.throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash128(c: &mut Criterion) {
    let mut bench = ParameterizedBenchmark::new(
        "city::hash128",
        move |b, &&size| {
            b.iter(|| city::Hash128::hash_with_seed(&DATA[..size], SEED as u128));
        },
        &PARAMS,
    )
    .with_function("farm::hash128", move |b, &&size| {
        b.iter(|| farm::hash128_with_seed(&DATA[..size], SEED as u128));
    })
    .with_function("farm::fingerprint128", move |b, &&size| {
        b.iter(|| farm::fingerprint128(&DATA[..size]));
    })
    .with_function("metro::Hash128_1", move |b, &&size| {
        b.iter(|| metro::Hash128_1::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("metro::Hash128_2", move |b, &&size| {
        b.iter(|| metro::Hash128_2::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("murmur3::hash128_x64", move |b, &&size| {
        b.iter(|| murmur3::Hash128_x64::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("murmur3::hash128_x86", move |b, &&size| {
        b.iter(|| murmur3::Hash128_x86::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("spooky::hash128", move |b, &&size| {
        b.iter(|| spooky::hash128_with_seed(&DATA[..size], SEED as u128));
    })
    .with_function("t1ha2::hash128_atonce", move |b, &&size| {
        b.iter(|| t1ha2::Hash128AtOnce::hash_with_seed(&DATA[..size], SEED));
    });

    if cfg!(target_feature = "sse4.2") {
        bench = bench
            .with_function("city::crc::hash128", move |b, &&size| {
                b.iter(|| city::crc::Hash128::hash_with_seed(&DATA[..size], SEED as u128));
            })
            .with_function("metro::crc::hash128_1", move |b, &&size| {
                b.iter(|| metro::crc::Hash128_1::hash_with_seed(&DATA[..size], SEED as u32));
            })
            .with_function("metro::crc::hash128_2", move |b, &&size| {
                b.iter(|| metro::crc::Hash128_2::hash_with_seed(&DATA[..size], SEED as u32));
            });
    }

    c.bench(
        "hash128",
        bench.throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

criterion_group!(
    benches,
    bench_memory,
    bench_hash32,
    bench_hash64,
    bench_hash128,
);
criterion_main!(benches);
<commit_msg>remove unused crate<commit_after>#![allow(deprecated)]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate criterion;

use std::mem;
use std::slice;

use criterion::{black_box, Criterion, ParameterizedBenchmark, Throughput};

use fasthash::*;

const KB: usize = 1024;
const SEED: u64 = 0x0123456789ABCDEF;
const PARAMS: [usize; 7] = [7, 8, 32, 256, KB, 4 * KB, 16 * KB];

lazy_static! {
    static ref DATA: Vec<u8> = (0..16 * KB).map(|b| b as u8).collect::<Vec<_>>();
}

fn bench_memory(c: &mut Criterion) {
    c.bench(
        "memory",
        ParameterizedBenchmark::new(
            "sum",
            move |b, &&size| {
                let s = unsafe {
                    slice::from_raw_parts(DATA.as_ptr() as *mut u32, size / mem::size_of::<u32>())
                };

                b.iter(|| {
                    black_box(s.iter().fold(0u64, |acc, &x| acc + x as u64));
                })
            },
            &PARAMS,
        )
        .throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash32(c: &mut Criterion) {
    c.bench(
        "hash32",
        ParameterizedBenchmark::new(
            "city::hash32",
            move |b, &&size| {
                b.iter(|| city::hash32_with_seed(&DATA.as_slice()[..size], SEED as u32));
            },
            &PARAMS,
        )
        .with_function("farm::hash32", move |b, &&size| {
            b.iter(|| farm::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("farm::finterprint32", move |b, &&size| {
            b.iter(|| farm::fingerprint32(&DATA[..size]));
        })
        .with_function("lookup3::hash32", move |b, &&size| {
            b.iter(|| lookup3::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur::hash32", move |b, &&size| {
            b.iter(|| murmur::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur::hash32_aligned", move |b, &&size| {
            b.iter(|| murmur::hash32_aligned_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32", move |b, &&size| {
            b.iter(|| murmur2::Hash32::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_a", move |b, &&size| {
            b.iter(|| murmur2::Hash32A::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_neutral", move |b, &&size| {
            b.iter(|| murmur2::Hash32Neutral::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur2::hash32_aligned", move |b, &&size| {
            b.iter(|| murmur2::Hash32Aligned::hash_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("murmur3::hash32", move |b, &&size| {
            b.iter(|| murmur3::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("spooky::hash32", move |b, &&size| {
            b.iter(|| spooky::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .with_function("xx::hash32", move |b, &&size| {
            b.iter(|| xx::hash32_with_seed(&DATA[..size], SEED as u32));
        })
        .throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash64(c: &mut Criterion) {
    let mut bench = ParameterizedBenchmark::new(
        "city::hash64",
        move |b, &&size| {
            b.iter(|| city::hash64_with_seed(&DATA.as_slice()[..size], SEED));
        },
        &PARAMS,
    )
    .with_function("farm::hash64", move |b, &&size| {
        b.iter(|| farm::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("farm::finterprint64", move |b, &&size| {
        b.iter(|| farm::fingerprint32(&DATA[..size]));
    })
    .with_function("metro::hash64_1", move |b, &&size| {
        b.iter(|| metro::Hash64_1::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("metro::hash64_2", move |b, &&size| {
        b.iter(|| metro::Hash64_2::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("mum::hash64", move |b, &&size| {
        b.iter(|| mum::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("murmur2::hash64_x64", move |b, &&size| {
        b.iter(|| murmur2::Hash64_x64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("murmur2::hash64_x86", move |b, &&size| {
        b.iter(|| murmur2::Hash64_x86::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("sea::hash64", move |b, &&size| {
        b.iter(|| sea::hash64_with_seeds(&DATA[..size], SEED, SEED, SEED, SEED));
    })
    .with_function("spooky::hash64", move |b, &&size| {
        b.iter(|| spooky::hash64_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha0::hash64", move |b, &&size| {
        b.iter(|| t1ha0::Hash64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha1::hash64", move |b, &&size| {
        b.iter(|| t1ha1::Hash64::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("t1ha2::hash64_atonce", move |b, &&size| {
        b.iter(|| t1ha2::Hash64AtOnce::hash_with_seed(&DATA[..size], SEED));
    })
    .with_function("xx::hash64", move |b, &&size| {
        b.iter(|| xx::hash64_with_seed(&DATA[..size], SEED));
    });

    if cfg!(target_feature = "sse4.2") {
        bench = bench
            .with_function("metro::crc::hash64_1", move |b, &&size| {
                b.iter(|| metro::crc::Hash64_1::hash_with_seed(&DATA[..size], SEED as u32));
            })
            .with_function("metro::crc::hash64_2", move |b, &&size| {
                b.iter(|| metro::crc::Hash64_2::hash_with_seed(&DATA[..size], SEED as u32));
            });
    }
    if cfg!(target_feature = "aes") {
        bench = bench.with_function("t1ha0::aes::hash64", move |b, &&size| {
            b.iter(|| t1ha0::aes::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }
    if cfg!(target_feature = "avx") {
        bench = bench.with_function("t1ha0::avx::hash64", move |b, &&size| {
            b.iter(|| t1ha0::avx::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }
    if cfg!(target_feature = "avx2") {
        bench = bench.with_function("t1ha0::avx2::hash64", move |b, &&size| {
            b.iter(|| t1ha0::avx2::Hash64::hash_with_seed(&DATA[..size], SEED));
        });
    }

    c.bench(
        "hash64",
        bench.throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

fn bench_hash128(c: &mut Criterion) {
    let mut bench = ParameterizedBenchmark::new(
        "city::hash128",
        move |b, &&size| {
            b.iter(|| city::Hash128::hash_with_seed(&DATA[..size], SEED as u128));
        },
        &PARAMS,
    )
    .with_function("farm::hash128", move |b, &&size| {
        b.iter(|| farm::hash128_with_seed(&DATA[..size], SEED as u128));
    })
    .with_function("farm::fingerprint128", move |b, &&size| {
        b.iter(|| farm::fingerprint128(&DATA[..size]));
    })
    .with_function("metro::Hash128_1", move |b, &&size| {
        b.iter(|| metro::Hash128_1::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("metro::Hash128_2", move |b, &&size| {
        b.iter(|| metro::Hash128_2::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("murmur3::hash128_x64", move |b, &&size| {
        b.iter(|| murmur3::Hash128_x64::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("murmur3::hash128_x86", move |b, &&size| {
        b.iter(|| murmur3::Hash128_x86::hash_with_seed(&DATA[..size], SEED as u32));
    })
    .with_function("spooky::hash128", move |b, &&size| {
        b.iter(|| spooky::hash128_with_seed(&DATA[..size], SEED as u128));
    })
    .with_function("t1ha2::hash128_atonce", move |b, &&size| {
        b.iter(|| t1ha2::Hash128AtOnce::hash_with_seed(&DATA[..size], SEED));
    });

    if cfg!(target_feature = "sse4.2") {
        bench = bench
            .with_function("city::crc::hash128", move |b, &&size| {
                b.iter(|| city::crc::Hash128::hash_with_seed(&DATA[..size], SEED as u128));
            })
            .with_function("metro::crc::hash128_1", move |b, &&size| {
                b.iter(|| metro::crc::Hash128_1::hash_with_seed(&DATA[..size], SEED as u32));
            })
            .with_function("metro::crc::hash128_2", move |b, &&size| {
                b.iter(|| metro::crc::Hash128_2::hash_with_seed(&DATA[..size], SEED as u32));
            });
    }

    c.bench(
        "hash128",
        bench.throughput(|&&size| Throughput::Bytes(size as u32)),
    );
}

criterion_group!(
    benches,
    bench_memory,
    bench_hash32,
    bench_hash64,
    bench_hash128,
);
criterion_main!(benches);
<|endoftext|>


<commit_before>use syntax::ast::{Expr, Lit, TokenTree, TtDelimited, TtToken};
use syntax::ext::base::ExtCtxt;
use syntax::parse;
use syntax::parse::parser::Parser as RustParser;
use syntax::parse::token;
use syntax::ptr::P;

use super::render::{Escape, Renderer};

macro_rules! guard {
    ($e:expr) => (if !$e { return false; })
}

macro_rules! branch {
    ($self_:expr;) => (return false);
    ($self_:expr; $e:expr) => (branch!($self_; $e,));
    ($self_:expr; $e:expr, $($es:expr),*) => ({
        let start_ptr = $self_.input.as_ptr();
        if $e {
            true
        } else {
            if $self_.input.as_ptr() == start_ptr {
                // Parsing failed, but did not consume input.
                // Keep going.
                branch!($self_; $($es),*)
            } else {
                return false;
            }
        }
    })
}

macro_rules! dollar {
    () => (TtToken(_, token::Dollar))
}
macro_rules! eq {
    () => (TtToken(_, token::Eq))
}
macro_rules! semi {
    () => (TtToken(_, token::Semi))
}
macro_rules! minus {
    () => (TtToken(_, token::BinOp(token::Minus)))
}
macro_rules! literal {
    () => (TtToken(_, token::Literal(..)))
}
macro_rules! ident {
    ($x:pat) => (TtToken(_, token::Ident($x, token::IdentStyle::Plain)))
}

pub fn parse(cx: &mut ExtCtxt, input: &[TokenTree]) -> Option<P<Expr>> {
    let mut success = true;
    let expr = Renderer::with(cx, |render| {
        let mut parser = Parser {
            in_attr: false,
            input: input,
            render: render,
        };
        success = parser.markups();
    });
    if success {
        Some(expr)
    } else {
        None
    }
}

struct Parser<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> {
    in_attr: bool,
    input: &'i [TokenTree],
    render: &'r mut Renderer<'cx, 's, 'o>,
}

impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
    /// Consume `n` items from the input.
    fn shift(&mut self, n: usize) {
        self.input = self.input.slice_from(n);
    }

    /// Construct a Rust AST parser from the given token tree.
    fn new_rust_parser(&self, tts: Vec<TokenTree>) -> RustParser<'s> {
        parse::tts_to_parser(self.render.cx.parse_sess, tts, self.render.cx.cfg.clone())
    }

    fn markups(&mut self) -> bool {
        loop {
            match self.input {
                [] => return true,
                [semi!(), ..] => self.shift(1),
                [ref tt, ..] => {
                    if !self.markup() {
                        self.render.cx.span_err(tt.get_span(), "invalid syntax");
                        return false;
                    }
                }
            }
        }
    }

    fn markup(&mut self) -> bool {
        branch!(self;
            self.literal(),
            self.splice(),
            self.block(),
            !self.in_attr && self.element())
    }

    fn literal(&mut self) -> bool {
        let (tt, minus) = match self.input {
            [minus!(), ref tt @ literal!(), ..] => {
                self.shift(2);
                (tt, true)
            },
            [ref tt @ literal!(), ..] => {
                self.shift(1);
                (tt, false)
            },
            _ => return false,
        };
        let lit = self.new_rust_parser(vec![tt.clone()]).parse_lit();
        match lit_to_string(self.render.cx, lit, minus) {
            Some(s) => self.render.string(s.as_slice(), Escape::Escape),
            None => return false,
        }
        true
    }

    fn splice(&mut self) -> bool {
        let (escape, sp) = match self.input {
            [ref tt @ dollar!(), dollar!(), ..] => {
                self.shift(2);
                (Escape::PassThru, tt.get_span())
            },
            [ref tt @ dollar!(), ..] => {
                self.shift(1);
                (Escape::Escape, tt.get_span())
            },
            _ => return false,
        };
        let tt = match self.input {
            [ref tt, ..] => {
                self.shift(1);
                self.new_rust_parser(vec![tt.clone()]).parse_expr()
            },
            _ => {
                self.render.cx.span_err(sp, "expected expression for this splice");
                return false;
            },
        };
        self.render.splice(tt, escape);
        true
    }

    fn element(&mut self) -> bool {
        let name = match self.input {
            [ident!(name), ..] => {
                self.shift(1);
                name.as_str().to_string()
            },
            _ => return false,
        };
        let name = name.as_slice();
        self.render.element_open_start(name);
        guard!(self.attrs());
        self.render.element_open_end();
        guard!(self.markup());
        self.render.element_close(name);
        true
    }

    fn attrs(&mut self) -> bool {
        while let [ident!(name), eq!(), ..] = self.input {
            self.shift(2);
            self.render.attribute_start(name.as_str());
            {
                let old_in_attr = self.in_attr;
                self.in_attr = true;
                guard!(self.markup());
                self.in_attr = old_in_attr;
            }
            self.render.attribute_end();
        }
        true
    }

    fn block(&mut self) -> bool {
        match self.input {
            [TtDelimited(_, ref d), ..] if d.delim == token::DelimToken::Brace => {
                self.shift(1);
                Parser {
                    in_attr: self.in_attr,
                    input: d.tts.as_slice(),
                    render: self.render,
                }.markups()
            },
            _ => false,
        }
    }
}

/// Convert a literal to a string.
fn lit_to_string(cx: &mut ExtCtxt, lit: Lit, minus: bool) -> Option<String> {
    use syntax::ast::Lit_::*;
    let mut result = String::new();
    if minus {
        result.push('-');
    }
    match lit.node {
        LitStr(s, _) => result.push_str(s.get()),
        LitBinary(..) | LitByte(..) => {
            cx.span_err(lit.span, "cannot splice binary data");
            return None;
        },
        LitChar(c) => result.push(c),
        LitInt(x, _) => result.push_str(x.to_string().as_slice()),
        LitFloat(s, _) | LitFloatUnsuffixed(s) => result.push_str(s.get()),
        LitBool(b) => result.push_str(if b { "true" } else { "false" }),
    };
    Some(result)
}
<commit_msg>Simplify parser a bit<commit_after>use syntax::ast::{Expr, Lit, TokenTree, TtDelimited, TtToken};
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::parse;
use syntax::parse::parser::Parser as RustParser;
use syntax::parse::token;
use syntax::ptr::P;

use super::render::{Escape, Renderer};

macro_rules! guard {
    ($e:expr) => (if !$e { return false; })
}

macro_rules! dollar {
    () => (TtToken(_, token::Dollar))
}
macro_rules! eq {
    () => (TtToken(_, token::Eq))
}
macro_rules! semi {
    () => (TtToken(_, token::Semi))
}
macro_rules! minus {
    () => (TtToken(_, token::BinOp(token::Minus)))
}
macro_rules! literal {
    () => (TtToken(_, token::Literal(..)))
}
macro_rules! ident {
    ($x:pat) => (ident!(_, $x));
    ($sp:pat, $x:pat) => (TtToken($sp, token::Ident($x, token::IdentStyle::Plain)))
}

pub fn parse(cx: &mut ExtCtxt, input: &[TokenTree]) -> Option<P<Expr>> {
    let mut success = true;
    let expr = Renderer::with(cx, |render| {
        let mut parser = Parser {
            in_attr: false,
            input: input,
            render: render,
        };
        success = parser.markups();
    });
    if success {
        Some(expr)
    } else {
        None
    }
}

struct Parser<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> {
    in_attr: bool,
    input: &'i [TokenTree],
    render: &'r mut Renderer<'cx, 's, 'o>,
}

impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
    /// Consume `n` items from the input.
    fn shift(&mut self, n: usize) {
        self.input = self.input.slice_from(n);
    }

    /// Construct a Rust AST parser from the given token tree.
    fn new_rust_parser(&self, tts: Vec<TokenTree>) -> RustParser<'s> {
        parse::tts_to_parser(self.render.cx.parse_sess, tts, self.render.cx.cfg.clone())
    }

    fn markups(&mut self) -> bool {
        loop {
            match self.input {
                [] => return true,
                [semi!(), ..] => self.shift(1),
                [_, ..] => guard!(self.markup()),
            }
        }
    }

    fn markup(&mut self) -> bool {
        match self.input {
            // Literal
            [minus!(), ref tt @ literal!(), ..] => {
                self.shift(2);
                self.literal(tt, true)
            },
            [ref tt @ literal!(), ..] => {
                self.shift(1);
                self.literal(tt, false)
            },
            // Splice
            [ref tt @ dollar!(), dollar!(), ..] => {
                self.shift(2);
                self.splice(Escape::PassThru, tt.get_span())
            },
            [ref tt @ dollar!(), ..] => {
                self.shift(1);
                self.splice(Escape::Escape, tt.get_span())
            },
            // Element
            [ident!(sp, name), ..] => {
                self.shift(1);
                self.element(name.as_str(), sp)
            },
            // Block
            [TtDelimited(_, ref d), ..] if d.delim == token::DelimToken::Brace => {
                self.shift(1);
                self.block(d.tts.as_slice())
            },
            // ???
            _ => {
                if let [ref tt, ..] = self.input {
                    self.render.cx.span_err(tt.get_span(), "invalid syntax");
                }
                false
            },
        }
    }

    fn literal(&mut self, tt: &TokenTree, minus: bool) -> bool {
        let lit = self.new_rust_parser(vec![tt.clone()]).parse_lit();
        match lit_to_string(self.render.cx, lit, minus) {
            Some(s) => self.render.string(s.as_slice(), Escape::Escape),
            None => return false,
        }
        true
    }

    fn splice(&mut self, escape: Escape, sp: Span) -> bool {
        let tt = match self.input {
            [ref tt, ..] => {
                self.shift(1);
                self.new_rust_parser(vec![tt.clone()]).parse_expr()
            },
            _ => {
                self.render.cx.span_err(sp, "expected expression for this splice");
                return false;
            },
        };
        self.render.splice(tt, escape);
        true
    }

    fn element(&mut self, name: &str, sp: Span) -> bool {
        if self.in_attr {
            self.render.cx.span_err(sp, "unexpected element, you silly bumpkin");
            return false;
        }
        self.render.element_open_start(name);
        guard!(self.attrs());
        self.render.element_open_end();
        guard!(self.markup());
        self.render.element_close(name);
        true
    }

    fn attrs(&mut self) -> bool {
        while let [ident!(name), eq!(), ..] = self.input {
            self.shift(2);
            self.render.attribute_start(name.as_str());
            {
                let old_in_attr = self.in_attr;
                self.in_attr = true;
                guard!(self.markup());
                self.in_attr = old_in_attr;
            }
            self.render.attribute_end();
        }
        true
    }

    fn block(&mut self, tts: &[TokenTree]) -> bool {
        Parser {
            in_attr: self.in_attr,
            input: tts,
            render: self.render,
        }.markups()
    }
}

/// Convert a literal to a string.
fn lit_to_string(cx: &mut ExtCtxt, lit: Lit, minus: bool) -> Option<String> {
    use syntax::ast::Lit_::*;
    let mut result = String::new();
    if minus {
        result.push('-');
    }
    match lit.node {
        LitStr(s, _) => result.push_str(s.get()),
        LitBinary(..) | LitByte(..) => {
            cx.span_err(lit.span, "cannot splice binary data");
            return None;
        },
        LitChar(c) => result.push(c),
        LitInt(x, _) => result.push_str(x.to_string().as_slice()),
        LitFloat(s, _) | LitFloatUnsuffixed(s) => result.push_str(s.get()),
        LitBool(b) => result.push_str(if b { "true" } else { "false" }),
    };
    Some(result)
}
<|endoftext|>


<commit_before>use std::marker::ContravariantLifetime;

use objc::Id;
use objc::runtime::Object;

use INSObject;

pub struct NSEnumerator<'a, T> {
    id: Id<Object>,
    marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> where T: INSObject {
    pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> {
        NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
    }
}

impl<'a, T> Iterator for NSEnumerator<'a, T> where T: INSObject {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        unsafe {
            let obj: *mut T = msg_send![self.id, nextObject];
            obj.as_ref()
        }
    }
}
<commit_msg>Began implementing an NSFastEnumerator.<commit_after>use std::marker::ContravariantLifetime;
use libc::c_ulong;

use objc::Id;
use objc::runtime::Object;

use INSObject;

pub struct NSEnumerator<'a, T> {
    id: Id<Object>,
    marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> where T: INSObject {
    pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> {
        NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
    }
}

impl<'a, T> Iterator for NSEnumerator<'a, T> where T: INSObject {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        unsafe {
            let obj: *mut T = msg_send![self.id, nextObject];
            obj.as_ref()
        }
    }
}

trait INSFastEnumeration: INSObject {
    type Item: INSObject;

    fn enumerator(&self) -> NSFastEnumerator<Self::Item> {
        NSFastEnumerator {
            object: unsafe { &*(self as *const Self as *const Object) },
        }
    }
}

#[repr(C)]
struct NSFastEnumerationState {
    state: c_ulong,
    items_ptr: *mut *const Object,
    mutations_ptr: *mut c_ulong,
    extra: [c_ulong; 5],
}

struct NSFastEnumerator<'a, T> {
    object: &'a Object,
}
<|endoftext|>


<commit_before>use diesel::backend::Backend;
use diesel::expression::{AppearsOnTable, Expression, NonAggregate, SelectableExpression};
use diesel::prelude::*;
use diesel::query_builder::*;
use std::borrow::Borrow;
use std::marker::PhantomData;

#[derive(Debug, Clone, Copy)]
/// A database table column.
/// This type is created by the [`column`](struct.Table.html#method.column) function.
pub struct Column<T, U, ST> {
    table: T,
    name: U,
    _sql_type: PhantomData<ST>,
}

impl<T, U, ST> Column<T, U, ST> {
    pub(crate) fn new(table: T, name: U) -> Self {
        Self {
            table,
            name: name,
            _sql_type: PhantomData,
        }
    }
}

impl<T, U, ST> QueryId for Column<T, U, ST> {
    type QueryId = ();
    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, ST, QS> SelectableExpression<QS> for Column<T, U, ST> {}

impl<T, U, ST, QS> AppearsOnTable<QS> for Column<T, U, ST> {}

impl<T, U, ST> Expression for Column<T, U, ST> {
    type SqlType = ST;
}

impl<T, U, ST> NonAggregate for Column<T, U, ST> {}

impl<T, U, ST, DB> QueryFragment<DB> for Column<T, U, ST>
where
    DB: Backend,
    T: QueryFragment<DB>,
    U: Borrow<str>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.table.walk_ast(out.reborrow())?;
        out.push_sql(".");
        out.push_identifier(self.name.borrow())?;
        Ok(())
    }
}
<commit_msg>Update diesel_dynamic_schema/src/column.rs<commit_after>use diesel::backend::Backend;
use diesel::expression::{AppearsOnTable, Expression, NonAggregate, SelectableExpression};
use diesel::prelude::*;
use diesel::query_builder::*;
use std::borrow::Borrow;
use std::marker::PhantomData;

#[derive(Debug, Clone, Copy)]
/// A database table column.
/// This type is created by the [`column`](struct.Table.html#method.column) function.
pub struct Column<T, U, ST> {
    table: T,
    name: U,
    _sql_type: PhantomData<ST>,
}

impl<T, U, ST> Column<T, U, ST> {
    pub(crate) fn new(table: T, name: U) -> Self {
        Self {
            table,
            name,
            _sql_type: PhantomData,
        }
    }
}

impl<T, U, ST> QueryId for Column<T, U, ST> {
    type QueryId = ();
    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, ST, QS> SelectableExpression<QS> for Column<T, U, ST> {}

impl<T, U, ST, QS> AppearsOnTable<QS> for Column<T, U, ST> {}

impl<T, U, ST> Expression for Column<T, U, ST> {
    type SqlType = ST;
}

impl<T, U, ST> NonAggregate for Column<T, U, ST> {}

impl<T, U, ST, DB> QueryFragment<DB> for Column<T, U, ST>
where
    DB: Backend,
    T: QueryFragment<DB>,
    U: Borrow<str>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.table.walk_ast(out.reborrow())?;
        out.push_sql(".");
        out.push_identifier(self.name.borrow())?;
        Ok(())
    }
}
<|endoftext|>