<commit_before>use std::net::{
    IpAddr,
    Ipv4Addr,
    Ipv6Addr,
    SocketAddr,
};
use std::sync::{
    Arc,
    Mutex,
};

use c_ares;
use futures;
use futures::Future;

use error::Error;
use eventloop::{
    EventLoop,
    EventLoopHandle
};

/// Used to configure the behaviour of the resolver.
#[derive(Default)]
pub struct Options {
    inner: c_ares::Options,
}

impl Options {
    /// Returns a fresh `Options`, on which no values are set.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set flags controlling the behaviour of the resolver.  The available
    /// flags are documented [here](flags/index.html).
    pub fn set_flags(&mut self, flags: c_ares::flags::Flags) -> &mut Self {
        self.inner.set_flags(flags);
        self
    }

    /// Set the number of milliseconds each name server is given to respond to
    /// a query on the first try.  (After the first try, the timeout algorithm
    /// becomes more complicated, but scales linearly with the value of
    /// timeout).  The default is 5000ms.
    pub fn set_timeout(&mut self, ms: u32) -> &mut Self {
        self.inner.set_timeout(ms);
        self
    }

    /// Set the number of tries the resolver will try contacting each name
    /// server before giving up.  The default is four tries.
    pub fn set_tries(&mut self, tries: u32) -> &mut Self {
        self.inner.set_tries(tries);
        self
    }

    /// Set the number of dots which must be present in a domain name for it to
    /// be queried for "as is" prior to querying for it with the default domain
    /// extensions appended.  The default value is 1 unless set otherwise by
    /// resolv.conf or the RES_OPTIONS environment variable.
    pub fn set_ndots(&mut self, ndots: u32) -> &mut Self {
        self.inner.set_ndots(ndots);
        self
    }

    /// Set the UDP port to use for queries.  The default value is 53, the
    /// standard name service port.
    pub fn set_udp_port(&mut self, udp_port: u16) -> &mut Self {
        self.inner.set_udp_port(udp_port);
        self
    }

    /// Set the TCP port to use for queries.  The default value is 53, the
    /// standard name service port.
    pub fn set_tcp_port(&mut self, tcp_port: u16) -> &mut Self {
        self.inner.set_tcp_port(tcp_port);
        self
    }

    /// Set the domains to search, instead of the domains specified in
    /// resolv.conf or the domain derived from the kernel hostname variable.
    pub fn set_domains(&mut self, domains: &[&str]) -> &mut Self {
        self.inner.set_domains(domains);
        self
    }

    /// Set the lookups to perform for host queries. `lookups` should be set to
    /// a string of the characters "b" or "f", where "b" indicates a DNS lookup
    /// and "f" indicates a lookup in the hosts file.
    pub fn set_lookups(&mut self, lookups: &str) -> &mut Self {
        self.inner.set_lookups(lookups);
        self
    }

    /// Set the socket send buffer size.
    pub fn set_sock_send_buffer_size(&mut self, size: u32) -> &mut Self {
        self.inner.set_sock_send_buffer_size(size);
        self
    }

    /// Set the socket receive buffer size.
    pub fn set_sock_receive_buffer_size(&mut self, size: u32) -> &mut Self {
        self.inner.set_sock_receive_buffer_size(size);
        self
    }

    /// Configure round robin selection of nameservers.
    pub fn set_rotate(&mut self) -> &mut Self {
        self.inner.set_rotate();
        self
    }

    /// Prevent round robin selection of nameservers.
    pub fn set_no_rotate(&mut self) -> &mut Self {
        self.inner.set_no_rotate();
        self
    }

    /// Set the EDNS packet size.
    pub fn set_ednspsz(&mut self, size: u32) -> &mut Self {
        self.inner.set_ednspsz(size);
        self
    }
}

/// An asynchronous DNS resolver.
pub struct Resolver {
    ares_channel: Arc<Mutex<c_ares::Channel>>,
    event_loop_handle: EventLoopHandle,
}

impl Resolver {
    /// Create a new Resolver.
    pub fn new(options: Options) -> Result<Resolver, Error> {
        // Create and run the event loop.
        let event_loop = try!(EventLoop::new(options.inner));
        let channel = event_loop.ares_channel.clone();
        let handle = event_loop.run();

        // Return the Resolver.
        let resolver = Resolver {
            ares_channel: channel,
            event_loop_handle: handle,
        };
        Ok(resolver)
    }

    /// Set the list of servers to contact, instead of the servers specified
    /// in resolv.conf or the local named.
    ///
    /// String format is `host[:port]`.  IPv6 addresses with ports require
    /// square brackets eg `[2001:4860:4860::8888]:53`.
    pub fn set_servers(
        &mut self,
        servers: &[&str]) -> Result<&mut Self, c_ares::Error> {
        try!(self.ares_channel.lock().unwrap().set_servers(servers));
        Ok(self)
    }

    /// Set the local IPv4 address from which to make queries.
    pub fn set_local_ipv4(&mut self, ipv4: &Ipv4Addr) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_ipv4(ipv4);
        self
    }

    /// Set the local IPv6 address from which to make queries.
    pub fn set_local_ipv6(&mut self, ipv6: &Ipv6Addr) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_ipv6(ipv6);
        self
    }

    /// Set the local device from which to make queries.
    pub fn set_local_device(&mut self, device: &str) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_device(device);
        self
    }

    /// Look up the A records associated with `name`.
    pub fn query_a(&self, name: &str)
        -> futures::BoxFuture<c_ares::AResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_a(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the AAAA records associated with `name`.
    pub fn query_aaaa(&self, name: &str)
        -> futures::BoxFuture<c_ares::AAAAResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_aaaa(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the CNAME records associated with `name`.
    pub fn query_cname(&self, name: &str)
        -> futures::BoxFuture<c_ares::CNameResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_cname(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the MX records associated with `name`.
    pub fn query_mx(&self, name: &str)
        -> futures::BoxFuture<c_ares::MXResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_mx(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the NAPTR records associated with `name`.
    pub fn query_naptr(&self, name: &str)
        -> futures::BoxFuture<c_ares::NAPTRResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_naptr(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the NS records associated with `name`.
    pub fn query_ns(&self, name: &str)
        -> futures::BoxFuture<c_ares::NSResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_ns(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the PTR records associated with `name`.
    pub fn query_ptr(&self, name: &str)
        -> futures::BoxFuture<c_ares::PTRResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_ptr(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the SRV records associated with `name`.
    pub fn query_srv(&self, name: &str)
        -> futures::BoxFuture<c_ares::SRVResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_srv(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the TXT records associated with `name`.
    pub fn query_txt(&self, name: &str)
        -> futures::BoxFuture<c_ares::TXTResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_txt(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the SOA records associated with `name`.
    pub fn query_soa(&self, name: &str)
        -> futures::BoxFuture<c_ares::SOAResult, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_soa(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Perform a host query by address.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_host_by_address<F>(
        &self,
        address: &IpAddr,
        handler: F
    ) where F: FnOnce(Result<c_ares::HostResults, c_ares::Error>) + Send + 'static {
         self.ares_channel.lock().unwrap()
             .get_host_by_address(address, handler);
    }

    /// Perform a host query by name.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_host_by_name<F>(
        &self,
        name: &str,
        family: c_ares::AddressFamily,
        handler: F
    ) where F: FnOnce(Result<c_ares::HostResults, c_ares::Error>) + Send + 'static {
         self.ares_channel.lock().unwrap()
             .get_host_by_name(name, family, handler);
    }

    /// Address-to-nodename translation in protocol-independent manner.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_name_info<F>(
        &self,
        address: &SocketAddr,
        flags: c_ares::ni_flags::NIFlags,
        handler: F
    ) where F: FnOnce(Result<c_ares::NameInfoResult, c_ares::Error>) + Send + 'static {
        self.ares_channel.lock().unwrap()
            .get_name_info(address, flags, handler)
    }

    /// Perform a DNS query for `name`.  The class and type of the query are
    /// per the provided parameters, taking values as defined in
    /// `arpa/nameser.h`.
    ///
    /// On completion, `handler` is called with the result.
    ///
    /// This method is provided so that users can query DNS types for which
    /// `c-ares` does not provide a parser; or in case a third-party parser is
    /// preferred.  Usually, if a suitable `query_xxx()` is available, that should be used.
    pub fn query<F>(
        &self,
        name: &str,
        dns_class: u16,
        query_type: u16,
        handler: F
    ) where F: FnOnce(Result<&[u8], c_ares::Error>) + Send + 'static {
        self.ares_channel.lock().unwrap()
            .query(name, dns_class, query_type, handler);
    }

    /// Cancel all requests made on this `Channel`.
    pub fn cancel(&mut self) {
        self.ares_channel.lock().unwrap().cancel();
    }
}

impl Drop for Resolver {
    fn drop(&mut self) {
        // Shut down the event loop.
        self.event_loop_handle.shutdown();
    }
}
<commit_msg>long lines<commit_after>use std::net::{
    IpAddr,
    Ipv4Addr,
    Ipv6Addr,
    SocketAddr,
};
use std::sync::{
    Arc,
    Mutex,
};

use c_ares;
use futures;
use futures::Future;

use error::Error;
use eventloop::{
    EventLoop,
    EventLoopHandle
};

/// Used to configure the behaviour of the resolver.
#[derive(Default)]
pub struct Options {
    inner: c_ares::Options,
}

impl Options {
    /// Returns a fresh `Options`, on which no values are set.
    pub fn new() -> Self {
        Self::default()
    }

    /// Set flags controlling the behaviour of the resolver.  The available
    /// flags are documented [here](flags/index.html).
    pub fn set_flags(&mut self, flags: c_ares::flags::Flags) -> &mut Self {
        self.inner.set_flags(flags);
        self
    }

    /// Set the number of milliseconds each name server is given to respond to
    /// a query on the first try.  (After the first try, the timeout algorithm
    /// becomes more complicated, but scales linearly with the value of
    /// timeout).  The default is 5000ms.
    pub fn set_timeout(&mut self, ms: u32) -> &mut Self {
        self.inner.set_timeout(ms);
        self
    }

    /// Set the number of tries the resolver will try contacting each name
    /// server before giving up.  The default is four tries.
    pub fn set_tries(&mut self, tries: u32) -> &mut Self {
        self.inner.set_tries(tries);
        self
    }

    /// Set the number of dots which must be present in a domain name for it to
    /// be queried for "as is" prior to querying for it with the default domain
    /// extensions appended.  The default value is 1 unless set otherwise by
    /// resolv.conf or the RES_OPTIONS environment variable.
    pub fn set_ndots(&mut self, ndots: u32) -> &mut Self {
        self.inner.set_ndots(ndots);
        self
    }

    /// Set the UDP port to use for queries.  The default value is 53, the
    /// standard name service port.
    pub fn set_udp_port(&mut self, udp_port: u16) -> &mut Self {
        self.inner.set_udp_port(udp_port);
        self
    }

    /// Set the TCP port to use for queries.  The default value is 53, the
    /// standard name service port.
    pub fn set_tcp_port(&mut self, tcp_port: u16) -> &mut Self {
        self.inner.set_tcp_port(tcp_port);
        self
    }

    /// Set the domains to search, instead of the domains specified in
    /// resolv.conf or the domain derived from the kernel hostname variable.
    pub fn set_domains(&mut self, domains: &[&str]) -> &mut Self {
        self.inner.set_domains(domains);
        self
    }

    /// Set the lookups to perform for host queries. `lookups` should be set to
    /// a string of the characters "b" or "f", where "b" indicates a DNS lookup
    /// and "f" indicates a lookup in the hosts file.
    pub fn set_lookups(&mut self, lookups: &str) -> &mut Self {
        self.inner.set_lookups(lookups);
        self
    }

    /// Set the socket send buffer size.
    pub fn set_sock_send_buffer_size(&mut self, size: u32) -> &mut Self {
        self.inner.set_sock_send_buffer_size(size);
        self
    }

    /// Set the socket receive buffer size.
    pub fn set_sock_receive_buffer_size(&mut self, size: u32) -> &mut Self {
        self.inner.set_sock_receive_buffer_size(size);
        self
    }

    /// Configure round robin selection of nameservers.
    pub fn set_rotate(&mut self) -> &mut Self {
        self.inner.set_rotate();
        self
    }

    /// Prevent round robin selection of nameservers.
    pub fn set_no_rotate(&mut self) -> &mut Self {
        self.inner.set_no_rotate();
        self
    }

    /// Set the EDNS packet size.
    pub fn set_ednspsz(&mut self, size: u32) -> &mut Self {
        self.inner.set_ednspsz(size);
        self
    }
}

/// An asynchronous DNS resolver.
pub struct Resolver {
    ares_channel: Arc<Mutex<c_ares::Channel>>,
    event_loop_handle: EventLoopHandle,
}

impl Resolver {
    /// Create a new Resolver.
    pub fn new(options: Options) -> Result<Resolver, Error> {
        // Create and run the event loop.
        let event_loop = try!(EventLoop::new(options.inner));
        let channel = event_loop.ares_channel.clone();
        let handle = event_loop.run();

        // Return the Resolver.
        let resolver = Resolver {
            ares_channel: channel,
            event_loop_handle: handle,
        };
        Ok(resolver)
    }

    /// Set the list of servers to contact, instead of the servers specified
    /// in resolv.conf or the local named.
    ///
    /// String format is `host[:port]`.  IPv6 addresses with ports require
    /// square brackets eg `[2001:4860:4860::8888]:53`.
    pub fn set_servers(
        &mut self,
        servers: &[&str]) -> Result<&mut Self, c_ares::Error> {
        try!(self.ares_channel.lock().unwrap().set_servers(servers));
        Ok(self)
    }

    /// Set the local IPv4 address from which to make queries.
    pub fn set_local_ipv4(&mut self, ipv4: &Ipv4Addr) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_ipv4(ipv4);
        self
    }

    /// Set the local IPv6 address from which to make queries.
    pub fn set_local_ipv6(&mut self, ipv6: &Ipv6Addr) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_ipv6(ipv6);
        self
    }

    /// Set the local device from which to make queries.
    pub fn set_local_device(&mut self, device: &str) -> &mut Self {
        self.ares_channel.lock().unwrap().set_local_device(device);
        self
    }

    /// Look up the A records associated with `name`.
    pub fn query_a(&self, name: &str)
        -> futures::BoxFuture<c_ares::AResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_a(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the AAAA records associated with `name`.
    pub fn query_aaaa(&self, name: &str)
        -> futures::BoxFuture<c_ares::AAAAResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_aaaa(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the CNAME records associated with `name`.
    pub fn query_cname(&self, name: &str)
        -> futures::BoxFuture<c_ares::CNameResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_cname(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the MX records associated with `name`.
    pub fn query_mx(&self, name: &str)
        -> futures::BoxFuture<c_ares::MXResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_mx(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the NAPTR records associated with `name`.
    pub fn query_naptr(&self, name: &str)
        -> futures::BoxFuture<c_ares::NAPTRResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_naptr(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the NS records associated with `name`.
    pub fn query_ns(&self, name: &str)
        -> futures::BoxFuture<c_ares::NSResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_ns(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the PTR records associated with `name`.
    pub fn query_ptr(&self, name: &str)
        -> futures::BoxFuture<c_ares::PTRResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_ptr(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the SRV records associated with `name`.
    pub fn query_srv(&self, name: &str)
        -> futures::BoxFuture<c_ares::SRVResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_srv(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the TXT records associated with `name`.
    pub fn query_txt(&self, name: &str)
        -> futures::BoxFuture<c_ares::TXTResults, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_txt(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Look up the SOA records associated with `name`.
    pub fn query_soa(&self, name: &str)
        -> futures::BoxFuture<c_ares::SOAResult, c_ares::Error> {
        let (c, p) = futures::oneshot();
        self.ares_channel.lock().unwrap().query_soa(name, move |result| {
            c.complete(result);
        });
        p.map_err(|_| c_ares::Error::ECANCELLED)
            .and_then(futures::done)
            .boxed()
    }

    /// Perform a host query by address.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_host_by_address<F>(
        &self,
        address: &IpAddr,
        handler: F
    ) where F: FnOnce(Result<c_ares::HostResults, c_ares::Error>) + Send + 'static {
         self.ares_channel.lock().unwrap()
             .get_host_by_address(address, handler);
    }

    /// Perform a host query by name.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_host_by_name<F>(
        &self,
        name: &str,
        family: c_ares::AddressFamily,
        handler: F
    ) where F: FnOnce(Result<c_ares::HostResults, c_ares::Error>) + Send + 'static {
         self.ares_channel.lock().unwrap()
             .get_host_by_name(name, family, handler);
    }

    /// Address-to-nodename translation in protocol-independent manner.
    ///
    /// On completion, `handler` is called with the result.
    pub fn get_name_info<F>(
        &self,
        address: &SocketAddr,
        flags: c_ares::ni_flags::NIFlags,
        handler: F
    ) where F: FnOnce(Result<c_ares::NameInfoResult, c_ares::Error>) + Send + 'static {
        self.ares_channel.lock().unwrap()
            .get_name_info(address, flags, handler)
    }

    /// Perform a DNS query for `name`.  The class and type of the query are
    /// per the provided parameters, taking values as defined in
    /// `arpa/nameser.h`.
    ///
    /// On completion, `handler` is called with the result.
    ///
    /// This method is provided so that users can query DNS types for which
    /// `c-ares` does not provide a parser; or in case a third-party parser is
    /// preferred.  Usually, if a suitable `query_xxx()` is available, that
    /// should be used.
    pub fn query<F>(
        &self,
        name: &str,
        dns_class: u16,
        query_type: u16,
        handler: F
    ) where F: FnOnce(Result<&[u8], c_ares::Error>) + Send + 'static {
        self.ares_channel.lock().unwrap()
            .query(name, dns_class, query_type, handler);
    }

    /// Cancel all requests made on this `Channel`.
    pub fn cancel(&mut self) {
        self.ares_channel.lock().unwrap().cancel();
    }
}

impl Drop for Resolver {
    fn drop(&mut self) {
        // Shut down the event loop.
        self.event_loop_handle.shutdown();
    }
}
<|endoftext|>


<commit_before>//! jsonrpc response
use serde::{Serialize, Serializer};
use super::{Id, Value, Error, Version};

#[derive(Debug, PartialEq, Serialize)]
pub struct Success {
	pub jsonrpc: Version,
	pub result: Value,
	pub id: Id
}

#[derive(Debug, PartialEq, Serialize)]
pub struct Failure {
	pub jsonrpc: Version,
	pub error: Error,
	pub id: Id
}

#[derive(Debug, PartialEq)]
pub enum Output {
	Success(Success),
	Failure(Failure)
}

impl Serialize for Output {
	fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
	where S: Serializer {
		match *self {
			Output::Success(ref s) => s.serialize(serializer),
			Output::Failure(ref f) => f.serialize(serializer)
		}
	}
}

#[derive(Debug, PartialEq)]
pub enum Response {
	Single(Output),
	Batch(Vec<Output>)
}

impl Serialize for Response {
	fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
	where S: Serializer {
		match *self {
			Response::Single(ref o) => o.serialize(serializer),
			Response::Batch(ref b) => b.serialize(serializer)
		}
	}
}

<commit_msg>Set Tests for Output<commit_after>//! jsonrpc response
use serde::{Serialize, Serializer};
use super::{Id, Value, Error, Version};

#[derive(Debug, PartialEq, Serialize)]
pub struct Success {
	pub jsonrpc: Version,
	pub result: Value,
	pub id: Id
}

#[derive(Debug, PartialEq, Serialize)]
pub struct Failure {
	pub jsonrpc: Version,
	pub error: Error,
	pub id: Id
}

#[derive(Debug, PartialEq)]
pub enum Output {
	Success(Success),
	Failure(Failure)
}

impl Serialize for Output {
	fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
	where S: Serializer {
		match *self {
			Output::Success(ref s) => s.serialize(serializer),
			Output::Failure(ref f) => f.serialize(serializer)
		}
	}
}

#[derive(Debug, PartialEq)]
pub enum Response {
	Single(Output),
	Batch(Vec<Output>)
}

impl Serialize for Response {
	fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
	where S: Serializer {
		match *self {
			Response::Single(ref o) => o.serialize(serializer),
			Response::Batch(ref b) => b.serialize(serializer)
		}
	}
}

#[test]
fn success_output_serialize() {
	use serde_json;
	use serde_json::Value;

	let so = Output::Success(Success {
		jsonrpc: Version::V2,
		result: Value::U64(1),
		id: Id::Num(1)
	});

	let serialized = serde_json::to_string(&so).unwrap();
	assert_eq!(serialized, r#"{"jsonrpc":"2.0","result":1,"id":1}"#);
}

#[test]
fn failure_output_serialize() {
	use serde_json;
	use serde_json::Value;

	let fo = Output::Failure(Failure {
		jsonrpc: Version::V2,
		error: Error::parse_error(),
		id: Id::Num(1)
	});

	let serialized = serde_json::to_string(&fo).unwrap();
	assert_eq!(serialized, r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":1}"#);
}

<|endoftext|>


<commit_before>//! A TCP socket implementation of Hamelin.
#![feature(env, io)]
extern crate hamelin;
extern crate mio;

use std::env::args;
use std::old_io::IoErrorKind::TimedOut;
use hamelin::{BufferedAsyncStream, Hamelin};
use mio::{event, EventLoop, IoAcceptor, Handler, Token};
use mio::net::{SockAddr};
use mio::net::tcp::{TcpSocket, TcpAcceptor};

const SERVER: Token = Token(0);

fn main() {
    let args: Vec<_> = args().skip(1).collect();
    if args.len() < 3 {
        println!("Usage: hamelin host port command [args]");
        return;
    }
    let hamelin = Hamelin::new(&args[2], if args.len() > 3 {
        Some(&args[3..])
    } else {
        None
    });
    let addr = SockAddr::parse(&format!("{}:{}", if args[0] == "localhost" { "127.0.0.1" } else
                                        { &args[0][] }, args[1])).unwrap();
    let server = TcpSocket::v4().unwrap()
                    .bind(&addr).unwrap()
                    .listen(256).unwrap();
    println!("Server bound on {:?}.", addr);
    let mut event_loop = EventLoop::<(), ()>::new().unwrap();
    event_loop.register(&server, SERVER).unwrap();
    let _ = event_loop.run(HamelinHandler { server: server, hamelin: hamelin });
}

struct HamelinHandler {
    server: TcpAcceptor,
    hamelin: Hamelin,
}

impl Handler<(), ()> for HamelinHandler {
    fn readable(&mut self, _: &mut EventLoop<(), ()>, token: Token, _: event::ReadHint) {
        match token {
            SERVER => {
                let mut bufstream = BufferedAsyncStream::new(self.server.accept().unwrap().unwrap());
                let mut guard = self.hamelin.spawn().unwrap();
                loop {
                    if let Ok(line) = guard.read_line() {
                        println!("Writing: {}", line);
                        let _ = bufstream.write_line(&line);
                    }
                    match bufstream.read_line() {
                        Ok(line) => {
                            println!("Read: {}", line);
                            let _ = guard.write_line(&line);
                        },
                        Err(ref e) if e.kind != TimedOut => {
                            break;
                        },
                        _ => ()
                    }
                }
                guard.wait().unwrap();
            }
            _ => panic!("unexpected token"),
        }
    }
}
<commit_msg>Spin off native threads again as a temporary solution.<commit_after>//! A TCP socket implementation of Hamelin.
#![feature(env, io, std_misc)]
extern crate hamelin;
extern crate mio;

use std::env::args;
use std::old_io::IoErrorKind::TimedOut;
use std::thread::Thread;
use hamelin::{BufferedAsyncStream, Hamelin};
use mio::{event, EventLoop, IoAcceptor, Handler, Token};
use mio::net::{SockAddr};
use mio::net::tcp::{TcpSocket, TcpAcceptor};

const SERVER: Token = Token(0);

fn main() {
    let args: Vec<_> = args().skip(1).collect();
    if args.len() < 3 {
        println!("Usage: hamelin host port command [args]");
        return;
    }
    let hamelin = Hamelin::new(&args[2], if args.len() > 3 {
        Some(&args[3..])
    } else {
        None
    });
    let addr = SockAddr::parse(&format!("{}:{}", if args[0] == "localhost" { "127.0.0.1" } else
                                        { &args[0][] }, args[1])).unwrap();
    let server = TcpSocket::v4().unwrap()
                    .bind(&addr).unwrap()
                    .listen(256).unwrap();
    println!("Server bound on {:?}.", addr);
    let mut event_loop = EventLoop::<(), ()>::new().unwrap();
    event_loop.register(&server, SERVER).unwrap();
    let _ = event_loop.run(HamelinHandler { server: server, hamelin: hamelin });
}

struct HamelinHandler {
    server: TcpAcceptor,
    hamelin: Hamelin,
}

impl Handler<(), ()> for HamelinHandler {
    fn readable(&mut self, _: &mut EventLoop<(), ()>, token: Token, _: event::ReadHint) {
        match token {
            SERVER => {
                let mut bufstream = BufferedAsyncStream::new(self.server.accept().unwrap().unwrap());
                let mut guard = self.hamelin.spawn().unwrap();
                Thread::spawn(move || {
                    loop {
                        if let Ok(line) = guard.read_line() {
                            println!("Writing: {}", line);
                            let _ = bufstream.write_line(&line);
                        }
                        match bufstream.read_line() {
                            Ok(line) => {
                                println!("Read: {}", line);
                                let _ = guard.write_line(&line);
                            },
                            Err(ref e) if e.kind != TimedOut => {
                                break;
                            },
                            _ => ()
                        }
                    }
                    guard.wait().unwrap();
                });
            }
            _ => panic!("unexpected token"),
        }
    }
}
<|endoftext|>


<commit_before>extern crate rhq;
extern crate clap;
extern crate env_logger;

use clap::{App, AppSettings, Arg, SubCommand};

fn build_cli() -> App<'static, 'static> {
  App::new(env!("CARGO_PKG_NAME"))
    .about(env!("CARGO_PKG_DESCRIPTION"))
    .version(env!("CARGO_PKG_VERSION"))
    .author(env!("CARGO_PKG_AUTHORS"))
    .setting(AppSettings::VersionlessSubcommands)
    .setting(AppSettings::SubcommandRequiredElseHelp)
    .subcommand(SubCommand::with_name("list")
      .about("List local repositories in the root directory"))
    .subcommand(SubCommand::with_name("config").about("Show current configuration"))
    .subcommand(SubCommand::with_name("clone")
      .about("Clone remote repositories into the root directory")
      .arg(Arg::with_name("query")
        .help("URL or query of remote repository")
        .required(false))
      .arg(Arg::with_name("arg")
        .help("supplemental arguments for Git command")
        .takes_value(true)
        .long("arg")
        .short("a")
        .required(false)))
}

fn run() -> rhq::Result<()> {
  let cli = rhq::Client::new()?;

  let matches = build_cli().get_matches();
  match matches.subcommand() {
    ("clone", Some(m)) => cli.command_clone(m.value_of("query"), m.value_of("arg")),
    ("list", _) => cli.command_list(),
    ("config", _) => cli.command_config(),
    _ => unreachable!(),
  }
}

fn main() {
  env_logger::init().unwrap();
  if let Err(message) = run() {
    println!("failed with: {}", message);
    std::process::exit(1);
  }
}
<commit_msg>generating completion scripts<commit_after>extern crate rhq;
extern crate clap;
extern crate env_logger;

use clap::{App, AppSettings, Arg, SubCommand};

fn build_cli() -> App<'static, 'static> {
  App::new(env!("CARGO_PKG_NAME"))
    .about(env!("CARGO_PKG_DESCRIPTION"))
    .version(env!("CARGO_PKG_VERSION"))
    .author(env!("CARGO_PKG_AUTHORS"))
    .setting(AppSettings::VersionlessSubcommands)
    .setting(AppSettings::SubcommandRequiredElseHelp)
    .subcommand(SubCommand::with_name("list")
      .about("List local repositories in the root directory"))
    .subcommand(SubCommand::with_name("config").about("Show current configuration"))
    .subcommand(SubCommand::with_name("clone")
      .about("Clone remote repositories into the root directory")
      .arg(Arg::with_name("query")
        .help("URL or query of remote repository")
        .required(false))
      .arg(Arg::with_name("arg")
        .help("supplemental arguments for Git command")
        .takes_value(true)
        .long("arg")
        .short("a")
        .required(false)))
    .subcommand(SubCommand::with_name("completions")
      .about("Generate completion scripts for your shell")
      .setting(AppSettings::ArgRequiredElseHelp)
      .arg(Arg::with_name("shell")
        .possible_values(&["bash", "zsh", "fish", "powershell"])))
}

fn run() -> rhq::Result<()> {
  let cli = rhq::Client::new()?;

  let matches = build_cli().get_matches();
  match matches.subcommand() {
    ("clone", Some(m)) => cli.command_clone(m.value_of("query"), m.value_of("arg")),
    ("list", _) => cli.command_list(),
    ("config", _) => cli.command_config(),
    ("completions", Some(m)) => {
      let shell: clap::Shell = m.value_of("shell").and_then(|s| s.parse().ok()).expect("failed to parse target shell");
      build_cli().gen_completions_to(env!("CARGO_PKG_NAME"), shell, &mut std::io::stdout());
      Ok(())
    }
    _ => unreachable!(),
  }
}

fn main() {
  env_logger::init().expect("failed to initialize env_logger.");
  if let Err(message) = run() {
    println!("failed with: {}", message);
    std::process::exit(1);
  }
}
<|endoftext|>


<commit_before>// Copyright 2017 James Bostock. See the LICENSE file at the top-level
// directory of this distribution.

// An implementation of the tee(1) command in Rust.
// See http://man.cat-v.org/unix-6th/1/tee
use std::env;
use std::fs::File;
use std::io;
use std::io::{Result, Write};

/// A multi-way writer.
struct Tee {
    writers: Vec<Box<Write>>
}

impl Write for Tee {
    /// Writes a buffer to each of the writers, returning how many
    /// bytes were returned by the last write.
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        let mut n: usize = 0;
        for w in &mut self.writers {
            n = (*w).write(buf)?
        }
        Ok(n)
    }

    /// Flushes each writer.
    fn flush(&mut self) -> Result<()> {
        for w in &mut self.writers {
            (*w).flush()?
        }
        Ok(())
    }
}

fn main() {
    let args: Vec<_> = env::args().collect();

    let prog = &args[0];

    if args.len() == 1 {
        eprintln!("usage: {} [name ...]", prog);
    }

    let mut tee: Tee = Tee { writers: Vec::new() };

    tee.writers.push(Box::new(io::stdout()));

    for arg in args.iter().skip(1) {
        match File::create(&arg) {
            Ok(f) => { tee.writers.push(Box::new(f)); },
            Err(e) => { eprintln!("{}: {}: {}", prog, arg, e); }
        }
    }

    io::copy(&mut io::stdin(), &mut tee).expect(prog);
}
<commit_msg>Don't need to explicitly dereference w.<commit_after>// Copyright 2017 James Bostock. See the LICENSE file at the top-level
// directory of this distribution.

// An implementation of the tee(1) command in Rust.
// See http://man.cat-v.org/unix-6th/1/tee
use std::env;
use std::fs::File;
use std::io;
use std::io::{Result, Write};

/// A multi-way writer.
struct Tee {
    writers: Vec<Box<Write>>
}

impl Write for Tee {
    /// Writes a buffer to each of the writers, returning how many
    /// bytes were returned by the last write.
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        let mut n: usize = 0;
        for w in &mut self.writers {
            n = w.write(buf)?
        }
        Ok(n)
    }

    /// Flushes each writer.
    fn flush(&mut self) -> Result<()> {
        for w in &mut self.writers {
            w.flush()?
        }
        Ok(())
    }
}

fn main() {
    let args: Vec<_> = env::args().collect();

    let prog = &args[0];

    if args.len() == 1 {
        eprintln!("usage: {} [name ...]", prog);
    }

    let mut tee: Tee = Tee { writers: Vec::new() };

    tee.writers.push(Box::new(io::stdout()));

    for arg in args.iter().skip(1) {
        match File::create(&arg) {
            Ok(f) => { tee.writers.push(Box::new(f)); },
            Err(e) => { eprintln!("{}: {}: {}", prog, arg, e); }
        }
    }

    io::copy(&mut io::stdin(), &mut tee).expect(prog);
}
<|endoftext|>


<commit_before>//! Interfaces for building [docker](https://www.docker.com/) containers

extern crate rustc_serialize;
extern crate jed;
extern crate url;

use self::super::Docker;
use self::super::transport::Body;
use self::super::rep::{ ContainerCreateInfo, Event };
use std::collections::BTreeMap;
use std::io::Result;
use rustc_serialize::json::{self, Json, ToJson};

/// Interface for building a new docker container from an existing image
pub struct ContainerBuilder<'a, 'b> {
  docker: &'a mut Docker,
  image: &'b str,
  hostname: Option<String>,
  user: Option<String>,
  memory: Option<u64>
}

impl<'a, 'b> ContainerBuilder<'a, 'b> {
  pub fn new(docker: &'a mut Docker, image: &'b str) -> ContainerBuilder<'a,'b> {
    ContainerBuilder {
      docker: docker, image: image,
      hostname: None, user: None,
      memory: None
    }
  }
  pub fn hostname(mut self, h: &str) -> ContainerBuilder<'a,'b> {
    self.hostname = Some(h.to_string());
    self
  }

  pub fn user(mut self, u: &str) -> ContainerBuilder<'a, 'b> {
    self.user = Some(u.to_string());
    self
  }

  pub fn build(self) -> Result<ContainerCreateInfo> {
    let mut body = BTreeMap::new();
    body.insert("Image".to_string(), self.image.to_json());
    let json_obj: Json = body.to_json();
    let data = json::encode(&json_obj).unwrap();
    let mut bytes = data.as_bytes();
    let raw = try!(self.docker.post("/containers/create", Some(Body::new(&mut Box::new(&mut bytes), bytes.len() as u64))));
    Ok(json::decode::<ContainerCreateInfo>(&raw).unwrap())
  }
}

/// Interface for buiding an events request
pub struct Events<'a,'b,'c> {
  docker: &'a mut Docker,
  since: Option<&'b u64>,
  until: Option<&'c u64>
}

impl<'a,'b,'c> Events<'a,'b,'c> {
  pub fn new(docker: &'a mut Docker) -> Events<'a,'b,'c> {
    Events {
      docker: docker,
      since: None,
      until: None
    }
  }

  /// Filter events since a given timestamp
  pub fn since(mut self, ts: &'b u64) -> Events<'a,'b,'c> {
    self.since = Some(ts);
    self
  }

  /// Filter events until a given timestamp
  pub fn until(mut self, ts: &'c u64) -> Events<'a,'b,'c> {
    self.until = Some(ts);
    self
  }

  pub fn get(mut self) -> Result<Box<Iterator<Item=Event>>> {
    let mut params = Vec::new();
    if let Some(s) = self.since {
      params.push(format!("since={}", s));
    }
    if let Some(u) = self.until {
      params.push(format!("until={}", u));
    }
    let mut path = vec!("/events".to_string());
    if (!params.is_empty()) {
      path.push(params.connect("&"))
    }
    let raw = try!(self.docker.stream_get(&path.connect("?")[..]));
    let it = jed::Iter::new(raw).into_iter().map(|j| {
     let s = json::encode(&j).unwrap();
     json::decode::<Event>(&s).unwrap()
    });
    Ok(Box::new(it))
  }
}
<commit_msg>parens not needed<commit_after>//! Interfaces for building [docker](https://www.docker.com/) containers

extern crate rustc_serialize;
extern crate jed;
extern crate url;

use self::super::Docker;
use self::super::transport::Body;
use self::super::rep::{ ContainerCreateInfo, Event };
use std::collections::BTreeMap;
use std::io::Result;
use rustc_serialize::json::{self, Json, ToJson};

/// Interface for building a new docker container from an existing image
pub struct ContainerBuilder<'a, 'b> {
  docker: &'a mut Docker,
  image: &'b str,
  hostname: Option<String>,
  user: Option<String>,
  memory: Option<u64>
}

impl<'a, 'b> ContainerBuilder<'a, 'b> {
  pub fn new(docker: &'a mut Docker, image: &'b str) -> ContainerBuilder<'a,'b> {
    ContainerBuilder {
      docker: docker, image: image,
      hostname: None, user: None,
      memory: None
    }
  }
  pub fn hostname(mut self, h: &str) -> ContainerBuilder<'a,'b> {
    self.hostname = Some(h.to_string());
    self
  }

  pub fn user(mut self, u: &str) -> ContainerBuilder<'a, 'b> {
    self.user = Some(u.to_string());
    self
  }

  pub fn build(self) -> Result<ContainerCreateInfo> {
    let mut body = BTreeMap::new();
    body.insert("Image".to_string(), self.image.to_json());
    let json_obj: Json = body.to_json();
    let data = json::encode(&json_obj).unwrap();
    let mut bytes = data.as_bytes();
    let raw = try!(self.docker.post("/containers/create", Some(Body::new(&mut Box::new(&mut bytes), bytes.len() as u64))));
    Ok(json::decode::<ContainerCreateInfo>(&raw).unwrap())
  }
}

/// Interface for buiding an events request
pub struct Events<'a,'b,'c> {
  docker: &'a mut Docker,
  since: Option<&'b u64>,
  until: Option<&'c u64>
}

impl<'a,'b,'c> Events<'a,'b,'c> {
  pub fn new(docker: &'a mut Docker) -> Events<'a,'b,'c> {
    Events {
      docker: docker,
      since: None,
      until: None
    }
  }

  /// Filter events since a given timestamp
  pub fn since(mut self, ts: &'b u64) -> Events<'a,'b,'c> {
    self.since = Some(ts);
    self
  }

  /// Filter events until a given timestamp
  pub fn until(mut self, ts: &'c u64) -> Events<'a,'b,'c> {
    self.until = Some(ts);
    self
  }

  pub fn get(mut self) -> Result<Box<Iterator<Item=Event>>> {
    let mut params = Vec::new();
    if let Some(s) = self.since {
      params.push(format!("since={}", s));
    }
    if let Some(u) = self.until {
      params.push(format!("until={}", u));
    }
    let mut path = vec!("/events".to_string());
    if !params.is_empty() {
      path.push(params.connect("&"))
    }
    let raw = try!(self.docker.stream_get(&path.connect("?")[..]));
    let it = jed::Iter::new(raw).into_iter().map(|j| {
     let s = json::encode(&j).unwrap();
     json::decode::<Event>(&s).unwrap()
    });
    Ok(Box::new(it))
  }
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};

#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
pub(crate) use rand_chacha::ChaCha20Core as Core;
#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
pub(crate) use rand_hc::Hc128Core as Core;

#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng as Rng;
#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;

/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
/// on the current platform, to be statistically strong and unpredictable
/// (meaning a cryptographically secure PRNG).
///
/// The current algorithm used is the ChaCha block cipher with 20 rounds.
/// This may change as new evidence of cipher security and performance
/// becomes available.
///
/// The algorithm is deterministic but should not be considered reproducible
/// due to dependence on configuration and possible replacement in future
/// library versions. For a secure reproducible generator, we recommend use of
/// the [rand_chacha] crate directly.
///
/// [rand_chacha]: https://crates.io/crates/rand_chacha
#[cfg_attr(doc_cfg, doc(cfg(feature = "std_rng")))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StdRng(Rng);

impl RngCore for StdRng {
    #[inline(always)]
    fn next_u32(&mut self) -> u32 {
        self.0.next_u32()
    }

    #[inline(always)]
    fn next_u64(&mut self) -> u64 {
        self.0.next_u64()
    }

    #[inline(always)]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        self.0.fill_bytes(dest);
    }

    #[inline(always)]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        self.0.try_fill_bytes(dest)
    }
}

impl SeedableRng for StdRng {
    type Seed = <Rng as SeedableRng>::Seed;

    #[inline(always)]
    fn from_seed(seed: Self::Seed) -> Self {
        StdRng(Rng::from_seed(seed))
    }

    #[inline(always)]
    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
        Rng::from_rng(rng).map(StdRng)
    }
}

impl CryptoRng for StdRng {}

#[cfg(test)]
mod test {
    use crate::rngs::StdRng;
    use crate::{RngCore, SeedableRng};

    #[test]
    fn test_stdrng_construction() {
        // Test value-stability of StdRng. This is expected to break any time
        // the algorithm is changed.
        #[rustfmt::skip]
        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];

        #[cfg(any(feature = "stdrng_strong", not(feature = "stdrng_fast")))]
        let target = [3950704604716924505, 5573172343717151650];
        #[cfg(all(not(feature = "stdrng_strong"), feature = "stdrng_fast"))]
        let target = [10719222850664546238, 14064965282130556830];

        let mut rng0 = StdRng::from_seed(seed);
        let x0 = rng0.next_u64();

        let mut rng1 = StdRng::from_rng(rng0).unwrap();
        let x1 = rng1.next_u64();

        assert_eq!([x0, x1], target);
    }
}
<commit_msg>`StdRng`: Switch to `ChaCha12` (#1028)<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};

#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
pub(crate) use rand_hc::Hc128Core as Core;

#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha12Rng as Rng;
#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;

/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
/// on the current platform, to be statistically strong and unpredictable
/// (meaning a cryptographically secure PRNG).
///
/// The current algorithm used is the ChaCha block cipher with 20 rounds.
/// This may change as new evidence of cipher security and performance
/// becomes available.
///
/// The algorithm is deterministic but should not be considered reproducible
/// due to dependence on configuration and possible replacement in future
/// library versions. For a secure reproducible generator, we recommend use of
/// the [rand_chacha] crate directly.
///
/// [rand_chacha]: https://crates.io/crates/rand_chacha
#[cfg_attr(doc_cfg, doc(cfg(feature = "std_rng")))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StdRng(Rng);

impl RngCore for StdRng {
    #[inline(always)]
    fn next_u32(&mut self) -> u32 {
        self.0.next_u32()
    }

    #[inline(always)]
    fn next_u64(&mut self) -> u64 {
        self.0.next_u64()
    }

    #[inline(always)]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        self.0.fill_bytes(dest);
    }

    #[inline(always)]
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        self.0.try_fill_bytes(dest)
    }
}

impl SeedableRng for StdRng {
    type Seed = <Rng as SeedableRng>::Seed;

    #[inline(always)]
    fn from_seed(seed: Self::Seed) -> Self {
        StdRng(Rng::from_seed(seed))
    }

    #[inline(always)]
    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
        Rng::from_rng(rng).map(StdRng)
    }
}

impl CryptoRng for StdRng {}

#[cfg(test)]
mod test {
    use crate::rngs::StdRng;
    use crate::{RngCore, SeedableRng};

    #[test]
    fn test_stdrng_construction() {
        // Test value-stability of StdRng. This is expected to break any time
        // the algorithm is changed.
        #[rustfmt::skip]
        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];

        let target = [10719222850664546238, 14064965282130556830];

        let mut rng0 = StdRng::from_seed(seed);
        let x0 = rng0.next_u64();

        let mut rng1 = StdRng::from_rng(rng0).unwrap();
        let x1 = rng1.next_u64();

        assert_eq!([x0, x1], target);
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use clap::{Arg, App, AppSettings};
use zx::machine::ZXMachine;
use zx::sound::ay::ZXAYMode;
use zx::constants::{SCREEN_WIDTH, SCREEN_HEIGHT};
use utils::EmulationSpeed;
// TODO: move comand line parsing here

/// Structure to handle all emulator runtime settings
pub struct RustzxSettings {
    pub machine: ZXMachine,
    pub speed: EmulationSpeed,
    pub fastload: bool,
    pub scale: usize,
    pub screen_size: (usize, usize),
    pub kempston: bool,
    pub ay_mode: ZXAYMode,
    pub ay_enabled: bool,
    pub beeper_enabled: bool,
    pub sound_enabled: bool,
    pub volume: usize,
    pub latency: usize,
    pub rom: Option<String>,
    pub tap: Option<String>,
    pub sna: Option<String>,
}

impl RustzxSettings {
    /// constructs new Settings
    pub fn new() -> RustzxSettings {
        RustzxSettings {
            machine: ZXMachine::Sinclair48K,
            speed: EmulationSpeed::Definite(1),
            fastload: false,
            scale: 2,
            screen_size: (SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2),
            kempston: false,
            ay_mode: ZXAYMode::Mono,
            ay_enabled: false,
            beeper_enabled: true,
            sound_enabled: true,
            volume: 100,
            latency: 1024,
            rom: None,
            tap: None,
            sna: None,
        }
    }
    pub fn from_clap() -> RustzxSettings {
        // get defaults
        let mut out = Self::new();
        // parse cli
        let cmd = App::new("rustzx")
                      .setting(AppSettings::ColoredHelp)
                      .version(env!("CARGO_PKG_VERSION"))
                      .author("Vladislav Nikonov <pacmancoder@gmail.com>")
                      .about("ZX Spectrum emulator written in pure Rust")
                      // machine settings
                      .arg(Arg::with_name("128K")
                               .long("128k")
                               .help("Enables ZX Spectrum 128K mode"))
                      .arg(Arg::with_name("FASTLOAD")
                               .short("f")
                               .long("fastload")
                               .help("Accelerates standard tape loaders"))
                      // media files
                      .arg(Arg::with_name("ROM")
                               .long("rom")
                               .value_name("ROM_PATH")
                               .help("Selects path to rom, otherwise default will be used"))
                      .arg(Arg::with_name("TAP")
                               .long("tap")
                               .value_name("TAP_PATH")
                               .help("Selects path to *.tap file"))
                      .arg(Arg::with_name("SNA")
                               .long("sna")
                               .value_name("SNA_PATH")
                               .help("Selects path to *.sna snapshot file"))
                      // devices
                      .arg(Arg::with_name("KEMPSTON")
                                .short("k")
                                .long("kempston")
                                .help("Enables Kempston joystick. Controlls via arrow keys and \
                                       Alt buttons"))
                      // emulator settings
                      .arg(Arg::with_name("SPEED")
                               .long("speed")
                               .value_name("SPEED_VALUE")
                               .help("Selects speed for emulator in integer multiplier form"))
                      .arg(Arg::with_name("SCALE")
                               .long("scale")
                               .value_name("SCALE_VALUE")
                               .help("Selects default screen size. possible values are positive \
                                      integers. Default value is 2"))
                      // sound
                      .arg(Arg::with_name("NOSOUND")
                               .long("nosound")
                               .help("Disables sound. Use it when you have problems with audio \
                                      playback"))
                      .arg(Arg::with_name("NOBEEPER")
                               .long("nobeeper")
                               .help("Disables beeper"))
                      .arg(Arg::with_name("AY")
                                .long("ay")
                                .value_name("AY_TYPE")
                                .possible_values(&["none", "mono", "abc", "acb"])
                                .help("Selects AY mode. Use none to disable. \
                                       For stereo features use abc or acb, default is mono."))
                      .arg(Arg::with_name("VOLUME")
                                .long("volume")
                                .value_name("VOLUME_VALUE")
                                .help("Selects volume - value in range 0..200. Volume over 100 \
                                       can cause sound artifacts"))
                      .arg(Arg::with_name("LATENCY")
                                .long("latency")
                                .short("l")
                                .value_name("SAMPLES")
                                .help("Selects audio latency. Default is 1024 samples. Set higher \
                                       latency if emulator have sound glitches. Or if your \
                                       machine can handle this - try to set it lower. Must be \
                                       power of two."))
                      .get_matches();
        // machine type
        if cmd.is_present("128K") {
            out.machine(ZXMachine::Sinclair128K);
        }
        if let Some(speed_str) = cmd.value_of("SPEED") {
            if let Ok(speed) = speed_str.parse::<usize>() {
                out.speed(EmulationSpeed::Definite(speed));
            }
        };
        if let Some(scale_str) = cmd.value_of("SCALE") {
            if let Ok(scale) = scale_str.parse::<usize>() {
                out.scale(scale);
            } else {
                println!("[Warning] Invalid scale factor");
            };
        }
        out.fastload(cmd.is_present("FASTLOAD"))
           .beeper(!cmd.is_present("NOBEEPER"))
           .sound(!cmd.is_present("NOSOUND"))
           .kempston(cmd.is_present("KEMPSTON"));
        if let Some(path) = cmd.value_of("ROM") {
            if Path::new(path).is_file() {
                out.rom(path);
            } else {
                println!("[Warning] ROM file \"{}\" not found", path);
            }
        }
        if let Some(path) = cmd.value_of("TAP") {
            if Path::new(path).is_file() {
                out.tap(path);
            } else {
                println!("[Warning] Tape file \"{}\" not found", path);
            }
        }
        if let Some(path) = cmd.value_of("SNA") {
            if out.machine == ZXMachine::Sinclair48K {
                if Path::new(path).is_file() {
                    out.sna(path);
                } else {
                    println!("[Warning] Snapshot file \"{}\" not found", path);
                }
            } else {
                println!("[Warning] 128K SNA is not supported!");
            }
        }
        if let Some(value) = cmd.value_of("AY") {
           match value {
               "none" => { out.ay(false) },
               "mono" => { out.ay_mode(ZXAYMode::Mono) },
               "abc" => { out.ay_mode(ZXAYMode::ABC) },
               "acb" => { out.ay_mode(ZXAYMode::ACB) },
               _ => unreachable!(),
           };
        };
        if let Some(value) = cmd.value_of("VOLUME") {
            if let Ok(value) = value.parse::<usize>() {
                out.volume(value);
            } else {
                println!("[Warning] Volume value is incorrect, setting volume to 100");
            }
        };
        if let Some(latency_str) = cmd.value_of("LATENCY") {
            if let Ok(latency) = latency_str.parse::<usize>() {
                out.latency(latency);
            }
        };
        out
    }
    /// Changes machine type
    pub fn machine(&mut self, machine: ZXMachine) -> &mut Self {
        self.machine = machine;
        match machine {
            ZXMachine::Sinclair48K => self.ay_enabled = false,
            ZXMachine::Sinclair128K => self.ay_enabled = true,
        }
        self
    }
    /// changes screen scale
    pub fn scale(&mut self, scale: usize) -> &mut Self {
        // place into bounds
        if scale > 5 {
            self.scale = 2;
        } else {
            self.scale = scale;
        }
        self.screen_size = (SCREEN_WIDTH * self.scale, SCREEN_HEIGHT * self.scale);
        self
    }
    /// changes fastload flag
    pub fn fastload(&mut self, value: bool) -> &mut Self {
        self.fastload = value;
        self
    }
    /// changes lound latency
    pub fn latency(&mut self, latency: usize) -> &mut Self {
        self.latency = latency;
        self
    }
    /// Changes AY chip mode
    pub fn ay_mode(&mut self, mode: ZXAYMode) -> &mut Self {
        self.ay_enabled = true;
        self.ay_mode = mode;
        self
    }
    /// Changes ay state (on/off)
    pub fn ay(&mut self, state: bool) -> &mut Self {
        self.ay_enabled = state;
        self
    }
    /// Changes beeper state (on/off)
    pub fn beeper(&mut self, state: bool) -> &mut Self {
        self.beeper_enabled = state;
        self
    }
    /// changes sound flag
    pub fn sound(&mut self, state: bool) -> &mut Self {
        self.sound_enabled = state;
        self
    }

    /// Changes volume
    pub fn volume(&mut self, val: usize) -> &mut Self {
        self.volume = if val > 200 {
            200
        } else {
            val
        };
        self
    }
    /// cahnges kempston joy connection
    pub fn kempston(&mut self, value: bool) -> &mut Self {
        self.kempston = value;
        self
    }
    /// changes TAP path
    pub fn tap(&mut self, value: &str) -> &mut Self {
        self.tap = Some(value.to_owned());
        self
    }
    /// changes SNA path
    pub fn sna(&mut self, value: &str) -> &mut Self {
        self.sna = Some(value.to_owned());
        self
    }
    /// changes ROM path
    pub fn rom(&mut self, value: &str) -> &mut Self {
        self.rom = Some(value.to_owned());
        self
    }
    /// changes emulation speed
    pub fn speed(&mut self, value: EmulationSpeed) -> &mut Self {
        self.speed = value;
        self
    }
}
<commit_msg>Explain 48k vs 128k for --ay in --help<commit_after>use std::path::Path;
use clap::{Arg, App, AppSettings};
use zx::machine::ZXMachine;
use zx::sound::ay::ZXAYMode;
use zx::constants::{SCREEN_WIDTH, SCREEN_HEIGHT};
use utils::EmulationSpeed;
// TODO: move comand line parsing here

/// Structure to handle all emulator runtime settings
pub struct RustzxSettings {
    pub machine: ZXMachine,
    pub speed: EmulationSpeed,
    pub fastload: bool,
    pub scale: usize,
    pub screen_size: (usize, usize),
    pub kempston: bool,
    pub ay_mode: ZXAYMode,
    pub ay_enabled: bool,
    pub beeper_enabled: bool,
    pub sound_enabled: bool,
    pub volume: usize,
    pub latency: usize,
    pub rom: Option<String>,
    pub tap: Option<String>,
    pub sna: Option<String>,
}

impl RustzxSettings {
    /// constructs new Settings
    pub fn new() -> RustzxSettings {
        RustzxSettings {
            machine: ZXMachine::Sinclair48K,
            speed: EmulationSpeed::Definite(1),
            fastload: false,
            scale: 2,
            screen_size: (SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2),
            kempston: false,
            ay_mode: ZXAYMode::Mono,
            ay_enabled: false,
            beeper_enabled: true,
            sound_enabled: true,
            volume: 100,
            latency: 1024,
            rom: None,
            tap: None,
            sna: None,
        }
    }
    pub fn from_clap() -> RustzxSettings {
        // get defaults
        let mut out = Self::new();
        // parse cli
        let cmd = App::new("rustzx")
                      .setting(AppSettings::ColoredHelp)
                      .version(env!("CARGO_PKG_VERSION"))
                      .author("Vladislav Nikonov <pacmancoder@gmail.com>")
                      .about("ZX Spectrum emulator written in pure Rust")
                      // machine settings
                      .arg(Arg::with_name("128K")
                               .long("128k")
                               .help("Enables ZX Spectrum 128K mode"))
                      .arg(Arg::with_name("FASTLOAD")
                               .short("f")
                               .long("fastload")
                               .help("Accelerates standard tape loaders"))
                      // media files
                      .arg(Arg::with_name("ROM")
                               .long("rom")
                               .value_name("ROM_PATH")
                               .help("Selects path to rom, otherwise default will be used"))
                      .arg(Arg::with_name("TAP")
                               .long("tap")
                               .value_name("TAP_PATH")
                               .help("Selects path to *.tap file"))
                      .arg(Arg::with_name("SNA")
                               .long("sna")
                               .value_name("SNA_PATH")
                               .help("Selects path to *.sna snapshot file"))
                      // devices
                      .arg(Arg::with_name("KEMPSTON")
                                .short("k")
                                .long("kempston")
                                .help("Enables Kempston joystick. Controlls via arrow keys and \
                                       Alt buttons"))
                      // emulator settings
                      .arg(Arg::with_name("SPEED")
                               .long("speed")
                               .value_name("SPEED_VALUE")
                               .help("Selects speed for emulator in integer multiplier form"))
                      .arg(Arg::with_name("SCALE")
                               .long("scale")
                               .value_name("SCALE_VALUE")
                               .help("Selects default screen size. possible values are positive \
                                      integers. Default value is 2"))
                      // sound
                      .arg(Arg::with_name("NOSOUND")
                               .long("nosound")
                               .help("Disables sound. Use it when you have problems with audio \
                                      playback"))
                      .arg(Arg::with_name("NOBEEPER")
                               .long("nobeeper")
                               .help("Disables beeper"))
                      .arg(Arg::with_name("AY")
                                .long("ay")
                                .value_name("AY_TYPE")
                                .possible_values(&["none", "mono", "abc", "acb"])
                                .help("Selects AY mode. Use none to disable. \
                                       For stereo features use abc or acb, default is mono for \
                                       128k and none for 48k."))
                      .arg(Arg::with_name("VOLUME")
                                .long("volume")
                                .value_name("VOLUME_VALUE")
                                .help("Selects volume - value in range 0..200. Volume over 100 \
                                       can cause sound artifacts"))
                      .arg(Arg::with_name("LATENCY")
                                .long("latency")
                                .short("l")
                                .value_name("SAMPLES")
                                .help("Selects audio latency. Default is 1024 samples. Set higher \
                                       latency if emulator have sound glitches. Or if your \
                                       machine can handle this - try to set it lower. Must be \
                                       power of two."))
                      .get_matches();
        // machine type
        if cmd.is_present("128K") {
            out.machine(ZXMachine::Sinclair128K);
        }
        if let Some(speed_str) = cmd.value_of("SPEED") {
            if let Ok(speed) = speed_str.parse::<usize>() {
                out.speed(EmulationSpeed::Definite(speed));
            }
        };
        if let Some(scale_str) = cmd.value_of("SCALE") {
            if let Ok(scale) = scale_str.parse::<usize>() {
                out.scale(scale);
            } else {
                println!("[Warning] Invalid scale factor");
            };
        }
        out.fastload(cmd.is_present("FASTLOAD"))
           .beeper(!cmd.is_present("NOBEEPER"))
           .sound(!cmd.is_present("NOSOUND"))
           .kempston(cmd.is_present("KEMPSTON"));
        if let Some(path) = cmd.value_of("ROM") {
            if Path::new(path).is_file() {
                out.rom(path);
            } else {
                println!("[Warning] ROM file \"{}\" not found", path);
            }
        }
        if let Some(path) = cmd.value_of("TAP") {
            if Path::new(path).is_file() {
                out.tap(path);
            } else {
                println!("[Warning] Tape file \"{}\" not found", path);
            }
        }
        if let Some(path) = cmd.value_of("SNA") {
            if out.machine == ZXMachine::Sinclair48K {
                if Path::new(path).is_file() {
                    out.sna(path);
                } else {
                    println!("[Warning] Snapshot file \"{}\" not found", path);
                }
            } else {
                println!("[Warning] 128K SNA is not supported!");
            }
        }
        if let Some(value) = cmd.value_of("AY") {
           match value {
               "none" => { out.ay(false) },
               "mono" => { out.ay_mode(ZXAYMode::Mono) },
               "abc" => { out.ay_mode(ZXAYMode::ABC) },
               "acb" => { out.ay_mode(ZXAYMode::ACB) },
               _ => unreachable!(),
           };
        };
        if let Some(value) = cmd.value_of("VOLUME") {
            if let Ok(value) = value.parse::<usize>() {
                out.volume(value);
            } else {
                println!("[Warning] Volume value is incorrect, setting volume to 100");
            }
        };
        if let Some(latency_str) = cmd.value_of("LATENCY") {
            if let Ok(latency) = latency_str.parse::<usize>() {
                out.latency(latency);
            }
        };
        out
    }
    /// Changes machine type
    pub fn machine(&mut self, machine: ZXMachine) -> &mut Self {
        self.machine = machine;
        match machine {
            ZXMachine::Sinclair48K => self.ay_enabled = false,
            ZXMachine::Sinclair128K => self.ay_enabled = true,
        }
        self
    }
    /// changes screen scale
    pub fn scale(&mut self, scale: usize) -> &mut Self {
        // place into bounds
        if scale > 5 {
            self.scale = 2;
        } else {
            self.scale = scale;
        }
        self.screen_size = (SCREEN_WIDTH * self.scale, SCREEN_HEIGHT * self.scale);
        self
    }
    /// changes fastload flag
    pub fn fastload(&mut self, value: bool) -> &mut Self {
        self.fastload = value;
        self
    }
    /// changes lound latency
    pub fn latency(&mut self, latency: usize) -> &mut Self {
        self.latency = latency;
        self
    }
    /// Changes AY chip mode
    pub fn ay_mode(&mut self, mode: ZXAYMode) -> &mut Self {
        self.ay_enabled = true;
        self.ay_mode = mode;
        self
    }
    /// Changes ay state (on/off)
    pub fn ay(&mut self, state: bool) -> &mut Self {
        self.ay_enabled = state;
        self
    }
    /// Changes beeper state (on/off)
    pub fn beeper(&mut self, state: bool) -> &mut Self {
        self.beeper_enabled = state;
        self
    }
    /// changes sound flag
    pub fn sound(&mut self, state: bool) -> &mut Self {
        self.sound_enabled = state;
        self
    }

    /// Changes volume
    pub fn volume(&mut self, val: usize) -> &mut Self {
        self.volume = if val > 200 {
            200
        } else {
            val
        };
        self
    }
    /// cahnges kempston joy connection
    pub fn kempston(&mut self, value: bool) -> &mut Self {
        self.kempston = value;
        self
    }
    /// changes TAP path
    pub fn tap(&mut self, value: &str) -> &mut Self {
        self.tap = Some(value.to_owned());
        self
    }
    /// changes SNA path
    pub fn sna(&mut self, value: &str) -> &mut Self {
        self.sna = Some(value.to_owned());
        self
    }
    /// changes ROM path
    pub fn rom(&mut self, value: &str) -> &mut Self {
        self.rom = Some(value.to_owned());
        self
    }
    /// changes emulation speed
    pub fn speed(&mut self, value: EmulationSpeed) -> &mut Self {
        self.speed = value;
        self
    }
}
<|endoftext|>


<commit_before>//! Thread safe communication channel implementing `Evented`

#![allow(unused_imports)]

use {io, Evented, Ready, Poll, PollOpt, Registration, SetReadiness, Token};
use lazycell::{LazyCell, AtomicLazyCell};
use std::fmt;
use std::sync::{mpsc, Arc};
use std::sync::atomic::{AtomicUsize, Ordering};

/// Creates a new asynchronous channel, where the `Receiver` can be registered
/// with `Poll`.
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let (tx_ctl, rx_ctl) = ctl_pair();
    let (tx, rx) = mpsc::channel();

    let tx = Sender {
        tx: tx,
        ctl: tx_ctl,
    };

    let rx = Receiver {
        rx: rx,
        ctl: rx_ctl,
    };

    (tx, rx)
}

/// Creates a new synchronous, bounded channel where the `Receiver` can be
/// registered with `Poll`.
pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) {
    let (tx_ctl, rx_ctl) = ctl_pair();
    let (tx, rx) = mpsc::sync_channel(bound);

    let tx = SyncSender {
        tx: tx,
        ctl: tx_ctl,
    };

    let rx = Receiver {
        rx: rx,
        ctl: rx_ctl,
    };

    (tx, rx)
}

pub fn ctl_pair() -> (SenderCtl, ReceiverCtl) {
    let inner = Arc::new(Inner {
        pending: AtomicUsize::new(0),
        senders: AtomicUsize::new(1),
        set_readiness: AtomicLazyCell::new(),
    });

    let tx = SenderCtl {
        inner: inner.clone(),
    };

    let rx = ReceiverCtl {
        registration: LazyCell::new(),
        inner: inner,
    };

    (tx, rx)
}

/// Tracks messages sent on a channel in order to update readiness.
pub struct SenderCtl {
    inner: Arc<Inner>,
}

/// Tracks messages received on a channel in order to track readiness.
pub struct ReceiverCtl {
    registration: LazyCell<Registration>,
    inner: Arc<Inner>,
}

pub struct Sender<T> {
    tx: mpsc::Sender<T>,
    ctl: SenderCtl,
}

pub struct SyncSender<T> {
    tx: mpsc::SyncSender<T>,
    ctl: SenderCtl,
}

pub struct Receiver<T> {
    rx: mpsc::Receiver<T>,
    ctl: ReceiverCtl,
}

#[derive(Debug)]
pub enum SendError<T> {
    Io(io::Error),
    Disconnected(T),
}

#[derive(Debug)]
pub enum TrySendError<T> {
    Io(io::Error),
    Full(T),
    Disconnected(T),
}

struct Inner {
    // The number of outstanding messages for the receiver to read
    pending: AtomicUsize,
    // The number of sender handles
    senders: AtomicUsize,
    // The set readiness handle
    set_readiness: AtomicLazyCell<SetReadiness>,
}

impl<T> Sender<T> {
    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
        self.tx.send(t)
            .map_err(SendError::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }
}

impl<T> Clone for Sender<T> {
    fn clone(&self) -> Sender<T> {
        Sender {
            tx: self.tx.clone(),
            ctl: self.ctl.clone(),
        }
    }
}

impl<T> SyncSender<T> {
    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
        self.tx.send(t)
            .map_err(From::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }

    pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
        self.tx.try_send(t)
            .map_err(From::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }
}

impl<T> Clone for SyncSender<T> {
    fn clone(&self) -> SyncSender<T> {
        SyncSender {
            tx: self.tx.clone(),
            ctl: self.ctl.clone(),
        }
    }
}

impl<T> Receiver<T> {
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        self.rx.try_recv().and_then(|res| {
            let _ = self.ctl.dec();
            Ok(res)
        })
    }
}

impl<T> Evented for Receiver<T> {
    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        self.ctl.register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        self.ctl.reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &Poll) -> io::Result<()> {
        self.ctl.deregister(poll)
    }
}

/*
 *
 * ===== SenderCtl / ReceiverCtl =====
 *
 */

impl SenderCtl {
    /// Call to track that a message has been sent
    pub fn inc(&self) -> io::Result<()> {
        let cnt = self.inner.pending.fetch_add(1, Ordering::Acquire);

        if 0 == cnt {
            // Toggle readiness to readable
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::readable()));
            }
        }

        Ok(())
    }
}

impl Clone for SenderCtl {
    fn clone(&self) -> SenderCtl {
        self.inner.senders.fetch_add(1, Ordering::Relaxed);
        SenderCtl { inner: self.inner.clone() }
    }
}

impl Drop for SenderCtl {
    fn drop(&mut self) {
        if self.inner.senders.fetch_sub(1, Ordering::Release) == 1 {
            let _ = self.inc();
        }
    }
}

impl ReceiverCtl {
    pub fn dec(&self) -> io::Result<()> {
        let first = self.inner.pending.load(Ordering::Acquire);

        if first == 1 {
            // Unset readiness
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::none()));
            }
        }

        // Decrement
        let second = self.inner.pending.fetch_sub(1, Ordering::AcqRel);

        if first == 1 && second > 1 {
            // There are still pending messages. Since readiness was
            // previously unset, it must be reset here
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::readable()));
            }
        }

        Ok(())
    }
}

impl Evented for ReceiverCtl {
    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        if self.registration.borrow().is_some() {
            return Err(io::Error::new(io::ErrorKind::Other, "receiver already registered"));
        }

        let (registration, set_readiness) = Registration::new(poll, token, interest, opts);

        if self.inner.pending.load(Ordering::Relaxed) > 0 {
            // TODO: Don't drop readiness
            let _ = set_readiness.set_readiness(Ready::readable());
        }

        self.registration.fill(registration).ok().expect("unexpected state encountered");
        self.inner.set_readiness.fill(set_readiness).ok().expect("unexpected state encountered");

        Ok(())
    }

    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        match self.registration.borrow() {
            Some(registration) => registration.update(poll, token, interest, opts),
            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
        }
    }

    fn deregister(&self, poll: &Poll) -> io::Result<()> {
        match self.registration.borrow() {
            Some(registration) => registration.deregister(poll),
            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
        }
    }
}

/*
 *
 * ===== Error conversions =====
 *
 */

impl<T> From<mpsc::SendError<T>> for SendError<T> {
    fn from(src: mpsc::SendError<T>) -> SendError<T> {
        SendError::Disconnected(src.0)
    }
}

impl<T> From<io::Error> for SendError<T> {
    fn from(src: io::Error) -> SendError<T> {
        SendError::Io(src)
    }
}

impl<T> From<mpsc::TrySendError<T>> for TrySendError<T> {
    fn from(src: mpsc::TrySendError<T>) -> TrySendError<T> {
        match src {
            mpsc::TrySendError::Full(v) => TrySendError::Full(v),
            mpsc::TrySendError::Disconnected(v) => TrySendError::Disconnected(v),
        }
    }
}

impl<T> From<mpsc::SendError<T>> for TrySendError<T> {
    fn from(src: mpsc::SendError<T>) -> TrySendError<T> {
        TrySendError::Disconnected(src.0)
    }
}

impl<T> From<io::Error> for TrySendError<T> {
    fn from(src: io::Error) -> TrySendError<T> {
        TrySendError::Io(src)
    }
}

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &SendError::Io(ref io_err) => write!(f, "{}", io_err),
            &SendError::Disconnected(..) => write!(f, "Disconnected"),
        }
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &TrySendError::Io(ref io_err) => write!(f, "{}", io_err),
            &TrySendError::Full(..) => write!(f, "Full"),
            &TrySendError::Disconnected(..) => write!(f, "Disconnected"),
        }
    }
}
<commit_msg>Implements Error, Display for SendError<T> and TrySendError<T>.<commit_after>//! Thread safe communication channel implementing `Evented`

#![allow(unused_imports)]

use {io, Evented, Ready, Poll, PollOpt, Registration, SetReadiness, Token};
use lazycell::{LazyCell, AtomicLazyCell};
use std::fmt;
use std::error;
use std::sync::{mpsc, Arc};
use std::sync::atomic::{AtomicUsize, Ordering};

/// Creates a new asynchronous channel, where the `Receiver` can be registered
/// with `Poll`.
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let (tx_ctl, rx_ctl) = ctl_pair();
    let (tx, rx) = mpsc::channel();

    let tx = Sender {
        tx: tx,
        ctl: tx_ctl,
    };

    let rx = Receiver {
        rx: rx,
        ctl: rx_ctl,
    };

    (tx, rx)
}

/// Creates a new synchronous, bounded channel where the `Receiver` can be
/// registered with `Poll`.
pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) {
    let (tx_ctl, rx_ctl) = ctl_pair();
    let (tx, rx) = mpsc::sync_channel(bound);

    let tx = SyncSender {
        tx: tx,
        ctl: tx_ctl,
    };

    let rx = Receiver {
        rx: rx,
        ctl: rx_ctl,
    };

    (tx, rx)
}

pub fn ctl_pair() -> (SenderCtl, ReceiverCtl) {
    let inner = Arc::new(Inner {
        pending: AtomicUsize::new(0),
        senders: AtomicUsize::new(1),
        set_readiness: AtomicLazyCell::new(),
    });

    let tx = SenderCtl {
        inner: inner.clone(),
    };

    let rx = ReceiverCtl {
        registration: LazyCell::new(),
        inner: inner,
    };

    (tx, rx)
}

/// Tracks messages sent on a channel in order to update readiness.
pub struct SenderCtl {
    inner: Arc<Inner>,
}

/// Tracks messages received on a channel in order to track readiness.
pub struct ReceiverCtl {
    registration: LazyCell<Registration>,
    inner: Arc<Inner>,
}

pub struct Sender<T> {
    tx: mpsc::Sender<T>,
    ctl: SenderCtl,
}

pub struct SyncSender<T> {
    tx: mpsc::SyncSender<T>,
    ctl: SenderCtl,
}

pub struct Receiver<T> {
    rx: mpsc::Receiver<T>,
    ctl: ReceiverCtl,
}

pub enum SendError<T> {
    Io(io::Error),
    Disconnected(T),
}

pub enum TrySendError<T> {
    Io(io::Error),
    Full(T),
    Disconnected(T),
}

struct Inner {
    // The number of outstanding messages for the receiver to read
    pending: AtomicUsize,
    // The number of sender handles
    senders: AtomicUsize,
    // The set readiness handle
    set_readiness: AtomicLazyCell<SetReadiness>,
}

impl<T> Sender<T> {
    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
        self.tx.send(t)
            .map_err(SendError::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }
}

impl<T> Clone for Sender<T> {
    fn clone(&self) -> Sender<T> {
        Sender {
            tx: self.tx.clone(),
            ctl: self.ctl.clone(),
        }
    }
}

impl<T> SyncSender<T> {
    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
        self.tx.send(t)
            .map_err(From::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }

    pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
        self.tx.try_send(t)
            .map_err(From::from)
            .and_then(|_| {
                try!(self.ctl.inc());
                Ok(())
            })
    }
}

impl<T> Clone for SyncSender<T> {
    fn clone(&self) -> SyncSender<T> {
        SyncSender {
            tx: self.tx.clone(),
            ctl: self.ctl.clone(),
        }
    }
}

impl<T> Receiver<T> {
    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
        self.rx.try_recv().and_then(|res| {
            let _ = self.ctl.dec();
            Ok(res)
        })
    }
}

impl<T> Evented for Receiver<T> {
    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        self.ctl.register(poll, token, interest, opts)
    }

    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        self.ctl.reregister(poll, token, interest, opts)
    }

    fn deregister(&self, poll: &Poll) -> io::Result<()> {
        self.ctl.deregister(poll)
    }
}

/*
 *
 * ===== SenderCtl / ReceiverCtl =====
 *
 */

impl SenderCtl {
    /// Call to track that a message has been sent
    pub fn inc(&self) -> io::Result<()> {
        let cnt = self.inner.pending.fetch_add(1, Ordering::Acquire);

        if 0 == cnt {
            // Toggle readiness to readable
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::readable()));
            }
        }

        Ok(())
    }
}

impl Clone for SenderCtl {
    fn clone(&self) -> SenderCtl {
        self.inner.senders.fetch_add(1, Ordering::Relaxed);
        SenderCtl { inner: self.inner.clone() }
    }
}

impl Drop for SenderCtl {
    fn drop(&mut self) {
        if self.inner.senders.fetch_sub(1, Ordering::Release) == 1 {
            let _ = self.inc();
        }
    }
}

impl ReceiverCtl {
    pub fn dec(&self) -> io::Result<()> {
        let first = self.inner.pending.load(Ordering::Acquire);

        if first == 1 {
            // Unset readiness
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::none()));
            }
        }

        // Decrement
        let second = self.inner.pending.fetch_sub(1, Ordering::AcqRel);

        if first == 1 && second > 1 {
            // There are still pending messages. Since readiness was
            // previously unset, it must be reset here
            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
                try!(set_readiness.set_readiness(Ready::readable()));
            }
        }

        Ok(())
    }
}

impl Evented for ReceiverCtl {
    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        if self.registration.borrow().is_some() {
            return Err(io::Error::new(io::ErrorKind::Other, "receiver already registered"));
        }

        let (registration, set_readiness) = Registration::new(poll, token, interest, opts);

        if self.inner.pending.load(Ordering::Relaxed) > 0 {
            // TODO: Don't drop readiness
            let _ = set_readiness.set_readiness(Ready::readable());
        }

        self.registration.fill(registration).ok().expect("unexpected state encountered");
        self.inner.set_readiness.fill(set_readiness).ok().expect("unexpected state encountered");

        Ok(())
    }

    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
        match self.registration.borrow() {
            Some(registration) => registration.update(poll, token, interest, opts),
            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
        }
    }

    fn deregister(&self, poll: &Poll) -> io::Result<()> {
        match self.registration.borrow() {
            Some(registration) => registration.deregister(poll),
            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
        }
    }
}

/*
 *
 * ===== Error conversions =====
 *
 */

impl<T> From<mpsc::SendError<T>> for SendError<T> {
    fn from(src: mpsc::SendError<T>) -> SendError<T> {
        SendError::Disconnected(src.0)
    }
}

impl<T> From<io::Error> for SendError<T> {
    fn from(src: io::Error) -> SendError<T> {
        SendError::Io(src)
    }
}

impl<T> From<mpsc::TrySendError<T>> for TrySendError<T> {
    fn from(src: mpsc::TrySendError<T>) -> TrySendError<T> {
        match src {
            mpsc::TrySendError::Full(v) => TrySendError::Full(v),
            mpsc::TrySendError::Disconnected(v) => TrySendError::Disconnected(v),
        }
    }
}

impl<T> From<mpsc::SendError<T>> for TrySendError<T> {
    fn from(src: mpsc::SendError<T>) -> TrySendError<T> {
        TrySendError::Disconnected(src.0)
    }
}

impl<T> From<io::Error> for TrySendError<T> {
    fn from(src: io::Error) -> TrySendError<T> {
        TrySendError::Io(src)
    }
}

/*
 *
 * ===== Implement Error, Debug and Display for Errors =====
 *
 */

impl<T> error::Error for SendError<T> {
    fn description(&self) -> &str {
        match self {
            &SendError::Io(ref io_err) => io_err.description(),
            &SendError::Disconnected(..) => "Disconnected",
        }
    }
}

impl<T> error::Error for TrySendError<T> {
    fn description(&self) -> &str {
        match self {
            &TrySendError::Io(ref io_err) => io_err.description(),
            &TrySendError::Full(..) => "Full",
            &TrySendError::Disconnected(..) => "Disconnected",
        }
    }
}

impl<T> fmt::Debug for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        format_send_error(self, f)
    }
}

impl<T> fmt::Display for SendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        format_send_error(self, f)
    }
}

impl<T> fmt::Debug for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        format_try_send_errror(self, f)
    }
}

impl<T> fmt::Display for TrySendError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        format_try_send_errror(self, f)
    }
}

#[inline]
fn format_send_error<T>(e: &SendError<T>, f: &mut fmt::Formatter) -> fmt::Result {
    match e {
        &SendError::Io(ref io_err) => write!(f, "{}", io_err),
        &SendError::Disconnected(..) => write!(f, "Disconnected"),
    }
}

#[inline]
fn format_try_send_errror<T>(e: &TrySendError<T>, f: &mut fmt::Formatter) -> fmt::Result {
    match e {
        &TrySendError::Io(ref io_err) => write!(f, "{}", io_err),
        &TrySendError::Full(..) => write!(f, "Full"),
        &TrySendError::Disconnected(..) => write!(f, "Disconnected"),
    }
}
<|endoftext|>