<commit_before>// min-llvm-version: 10.0.1
// revisions: s390x
// assembly-output: emit-asm
//[s390x] compile-flags: --target s390x-unknown-linux-gnu
//[s390x] needs-llvm-components: systemz

#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]

#[rustc_builtin_macro]
macro_rules! asm {
    () => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
    () => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
    () => {};
}

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

type ptr = *const i32;

impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}

extern "C" {
    fn extern_func();
    static extern_static: u8;
}

// Hack to avoid function merging
extern "Rust" {
    fn dont_merge(s: &str);
}

macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
    #[no_mangle]
    pub unsafe fn $func(x: $ty) -> $ty {
        dont_merge(stringify!(func));

        let y;
        asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
        y
    }
};}

macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
    #[no_mangle]
    pub unsafe fn $func(x: $ty) -> $ty {
        dont_merge(stringify!(func));

        let y;
        asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
        y
    }
};}

// CHECK-LABEL: sym_fn_32:
// CHECK: #APP
// CHECK: brasl %r14, extern_func
// CHECK: #NO_APP
#[cfg(s390x)]
#[no_mangle]
pub unsafe fn sym_fn_32() {
    asm!("brasl %r14, {}", sym extern_func);
}

// CHECK-LABEL: sym_static:
// CHECK: #APP
// CHECK: brasl %r14, extern_static
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
    asm!("brasl %r14, {}", sym extern_static);
}

// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8, i8, reg, "lgr");

// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16, i16, reg, "lgr");

// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32, i32, reg, "lgr");

// CHECK-LABEL: reg_i64:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i64, i64, reg, "lgr");

// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32, f32, freg, "ler");

// CHECK-LABEL: reg_f64:
// CHECK: #APP
// CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f64, f64, freg, "ldr");
<commit_msg>Fix: added necessary prefix<commit_after>// min-llvm-version: 10.0.1
// revisions: s390x
// assembly-output: emit-asm
//[s390x] compile-flags: --target s390x-unknown-linux-gnu
//[s390x] needs-llvm-components: systemz

#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]

#[rustc_builtin_macro]
macro_rules! asm {
    () => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
    () => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
    () => {};
}

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

type ptr = *const i32;

impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}

extern "C" {
    fn extern_func();
    static extern_static: u8;
}

// Hack to avoid function merging
extern "Rust" {
    fn dont_merge(s: &str);
}

macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
    #[no_mangle]
    pub unsafe fn $func(x: $ty) -> $ty {
        dont_merge(stringify!($func));

        let y;
        asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
        y
    }
};}

macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
    #[no_mangle]
    pub unsafe fn $func(x: $ty) -> $ty {
        dont_merge(stringify!($func));

        let y;
        asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
        y
    }
};}

// CHECK-LABEL: sym_fn_32:
// CHECK: #APP
// CHECK: brasl %r14, extern_func
// CHECK: #NO_APP
#[cfg(s390x)]
#[no_mangle]
pub unsafe fn sym_fn_32() {
    asm!("brasl %r14, {}", sym extern_func);
}

// CHECK-LABEL: sym_static:
// CHECK: #APP
// CHECK: brasl %r14, extern_static
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
    asm!("brasl %r14, {}", sym extern_static);
}

// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8, i8, reg, "lgr");

// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16, i16, reg, "lgr");

// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32, i32, reg, "lgr");

// CHECK-LABEL: reg_i64:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i64, i64, reg, "lgr");

// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32, f32, freg, "ler");

// CHECK-LABEL: reg_f64:
// CHECK: #APP
// CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f64, f64, freg, "ldr");

// CHECK-LABEL: reg_ptr:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_ptr, ptr, reg, "lgr");
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#![warn(missing_docs)]
#![recursion_limit = "1024"]

//! Trust-DNS is intended to be a fully compliant domain name server and client library.
//!
//! The Client library is responsible for the basic protocols responsible for communicating with DNS servers (authorities) and resolvers. It can be used for managing DNS records through the use of update operations. It is possible to send raw DNS Messages with the Client, but for ease of use the `query` and various other update operations are recommended for general use.
//!
//! For a system-like resolver, see [trust-dns-resolver](https://docs.rs/trust-dns-resolver). This is most likely what you want if all you want to do is lookup IP addresses.
//!
//! For serving DNS serving, see [trust-dns-server](https://docs.rs/trust-dns-server).
//!
//! # Goals
//!
//! * Only safe Rust
//! * All errors handled
//! * Simple to manage servers
//! * High level abstraction for clients
//! * Secure dynamic update
//! * New features for securing public information
//!
//! # Usage
//!
//! This shows basic usage of the SyncClient. More examples will be associated directly with other types.
//!
//! ## Dependency
//!
//! ```toml
//! [dependencies]
//! trust-dns = "^0.13"
//! ```
//!
//! By default DNSSec validation is built in with OpenSSL, this can be disabled with:
//!
//! ```toml
//! [dependencies]
//! trust-dns = { version = "^0.10", default-features = false }
//! ```
//!
//! Extern the crate into your program or library:
//!
//! ```rust
//! extern crate trust_dns;
//! ```
//!
//! ## Objects
//!
//! There are two variations of implementations of the Client. The `SyncClient`, a synchronous client, and the `ClientFuture`, a Tokio async client. `SyncClient` is an implementation of the `Client` trait, there is another implementation, `SecureSyncClient`, which validates DNSSec records. For these basic examples we'll only look at the `SyncClient`
//!
//! First we must decide on the type of connection, there are three supported by TRust-DNS today, UDP, TCP and TLS. TLS requires OpenSSL by default, see also [trust-dns-native-tls](https://docs.rs/trust-dns-native-tls) and [trust-dns-rustls](https://docs.rs/trust-dns-rustls) for other TLS options.
//!
//! ## Setup a connection
//!
//! ```rust
//! use trust_dns::client::{Client, ClientConnection, ClientStreamHandle, SyncClient};
//! use trust_dns::udp::UdpClientConnection;
//!
//! let address = "8.8.8.8:53".parse().unwrap();
//! let conn = UdpClientConnection::new(address).unwrap();
//!
//! // and then create the Client
//! let client = SyncClient::new(conn);
//! ```
//!
//! At this point the client is ready to be used. See also `client::SecureSyncClient` for DNSSec validation. The rest of these examples will assume that the above boilerplate has already been performed.
//!
//! ## Querying
//!
//! Using the Client to query for DNS records is easy enough, though it performs no resolution. The `trust-dns-resolver` has a simpler interface if that's what is desired. Over time that library will gain more features to generically query for differnet types.
//!
//! ```rust
//! use std::net::Ipv4Addr;
//! use std::str::FromStr;
//! # use trust_dns::client::{Client, SyncClient};
//! # use trust_dns::udp::UdpClientConnection;
//! use trust_dns::op::DnsResponse;
//! use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType};
//! #
//! # let address = "8.8.8.8:53".parse().unwrap();
//! # let conn = UdpClientConnection::new(address).unwrap();
//! # let client = SyncClient::new(conn);
//!
//! // Specify the name, note the final '.' which specifies it's an FQDN
//! let name = Name::from_str("www.example.com.").unwrap();
//!
//! // NOTE: see 'Setup a connection' example above
//! // Send the query and get a message response, see RecordType for all supported options
//! let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::A).unwrap();
//!
//! // Messages are the packets sent between client and server in DNS.
//! //  there are many fields to a Message, DnsResponse can be dereferenced into
//! //  a Message. It's beyond the scope of these examples
//! //  to explain all the details of a Message. See trust_dns::op::message::Message for more details.
//! //  generally we will be insterested in the Message::answers
//! let answers: &[Record] = response.answers();
//!
//! // Records are generic objects which can contain any data.
//! //  In order to access it we need to first check what type of record it is
//! //  In this case we are interested in A, IPv4 address
//! if let &RData::A(ref ip) = answers[0].rdata() {
//!     assert_eq!(*ip, Ipv4Addr::new(93, 184, 216, 34))
//! } else {
//!     assert!(false, "unexpected result")
//! }
//! ```
//!
//! In the above example we successfully queried for a A record. There are many other types, each can be independenly queried and the associated `trust_dns::rr::record_data::RData` has a variant with the deserialized data for the record stored.
//!
//! ## Dynamic update
//!
//! Currently `trust-dns` supports SIG(0) signed records for authentication and authorization of dynamic DNS updates. It's beyond the scope of these examples to show how to setup SIG(0) authorization on the server. `trust-dns` is known to work with BIND9 and `trust-dns-server`. Expect in the future for TLS to become a potentially better option for authorization with certificate chains. These examples show using SIG(0) for auth, requires OpenSSL. It's beyond the scope of these examples to describe the configuration for the server.

//!
//! ```rust,no_run
//! # extern crate chrono;
//! # extern crate openssl;
//! # extern crate trust_dns;
//!
//! use std::fs::File;
//! use std::io::Read;
//! use std::net::Ipv4Addr;
//! use std::str::FromStr;
//!
//! use chrono::Duration;
//! # #[cfg(feature = "openssl")]
//! use openssl::rsa::Rsa;
//! # use trust_dns::client::Client;
//! # use trust_dns::udp::UdpClientConnection;
//! use trust_dns::client::SyncClient;
//! use trust_dns::rr::{Name, RData, Record, RecordType};
//! use trust_dns::rr::dnssec::{Algorithm, Signer, KeyPair};
//! use trust_dns::op::ResponseCode;
//! use trust_dns::rr::rdata::key::KEY;
//!
//! # #[cfg(feature = "openssl")]
//! # fn main() {
//! # let address = "0.0.0.0:53".parse().unwrap();
//! # let conn = UdpClientConnection::new(address).unwrap();
//!
//! // The format of the key is dependent on the KeyPair type, in this example we're using RSA
//! //  if the key was generated with BIND, the binary in TRust-DNS client lib `dnskey-to-pem`
//! //  can be used to convert this to a pem file
//! let mut pem = File::open("my_private_key.pem").unwrap();
//! let mut pem_buf = Vec::<u8>::new();
//! pem.read_to_end(&mut pem_buf).unwrap();
//!
//! // Create the RSA key
//! let rsa = Rsa::private_key_from_pem(&pem_buf).unwrap();
//! let key = KeyPair::from_rsa(rsa).unwrap();
//!
//! // Create the RData KEY associated with the key. This example uses defaults for all the
//! //  KeyTrust, KeyUsage, UpdateScope, Protocol. Many of these have been deprecated in current
//! //  DNS RFCs, but are still supported by many servers for auth. See auth docs of the remote
//! //  server for help in understanding it's requirements and support of these options.
//! let sig0key = KEY::new(Default::default(),
//!                        Default::default(),
//!                        Default::default(),
//!                        Default::default(),
//!                        Algorithm::RSASHA256,
//!                        key.to_public_bytes().unwrap());
//!
//! // Create the TRust-DNS SIG(0) signing facility. Generally the signer_name is the label
//! //  associated with KEY record in the server.
//! let signer = Signer::sig0(sig0key,
//!                           key,
//!                           Name::from_str("update.example.com.").unwrap());
//!
//! // Create the DNS client, see above for creating a the connection
//! let client = SyncClient::with_signer(conn, signer);
//!
//! // At this point we should have a client capable of sending signed SIG(0) records.
//!
//! // Now we can send updates... let's create a new Record
//! let mut record = Record::with(Name::from_str("new.example.com").unwrap(),
//!                               RecordType::A,
//!                               Duration::minutes(5).num_seconds() as u32);
//! record.set_rdata(RData::A(Ipv4Addr::new(100, 10, 100, 10)));
//!
//! // the server must be authoritative for this zone
//! let origin = Name::from_str("example.com.").unwrap();
//!
//! // Create the record.
//! let result = client.create(record, origin).unwrap();
//! assert_eq!(result.response_code(), ResponseCode::NoError);
//! # }
//! # #[cfg(not(feature = "openssl"))]
//! # fn main() {
//! # }
//! ```
//!
//! *Note*: The dynamic DNS functions defined by TRust-DNS are expressed as atomic operations, but this depends on support of the remote server. For example, the `create` operation shown above, should only succeed if there is no `RecordSet` of the specified type at the specified label. The other update operations are `append`, `compare_and_swap`, `delete_by_rdata`, `delete_rrset`, and `delete_all`. See the documentation for each of these methods on the `Client` trait.

extern crate chrono;
extern crate data_encoding;
#[macro_use]
extern crate data_encoding_macro;
#[macro_use]
extern crate failure;
extern crate futures;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(feature = "native-tls")]
extern crate native_tls;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate radix_trie;
extern crate rand;
#[cfg(feature = "ring")]
extern crate ring;
extern crate tokio;
#[cfg(feature = "tokio-openssl")]
extern crate tokio_openssl;
extern crate tokio_tcp;
#[cfg(feature = "tokio-tls")]
extern crate tokio_tls;
extern crate trust_dns_proto;
#[cfg(feature = "ring")]
extern crate untrusted;

pub mod client;
pub mod error;
#[cfg(feature = "mdns")]
pub mod multicast;
pub mod op;
pub mod rr;
pub mod serialize;
pub mod tcp;
pub mod udp;

/// A sender to which serialized DNS Messages can be sent
#[deprecated(note = "use [`trust_dns_proto::BufDnsStreamHandle`] instead")]
pub use trust_dns_proto::BufStreamHandle;

/// A sender to which a Message can be sent
// pub type MessageStreamHandle = UnboundedSender<Message>;
#[deprecated(note = "use [`trust_dns_proto::BufDnsStreamHandle`] instead")]
pub use trust_dns_proto::BufDnsStreamHandle as BufClientStreamHandle;

/// Returns a version as specified in Cargo.toml
pub fn version() -> &'static str {
    env!("CARGO_PKG_VERSION")
}
<commit_msg>update client doc version reference<commit_after>/*
 * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#![warn(missing_docs)]
#![recursion_limit = "1024"]

//! Trust-DNS is intended to be a fully compliant domain name server and client library.
//!
//! The Client library is responsible for the basic protocols responsible for communicating with DNS servers (authorities) and resolvers. It can be used for managing DNS records through the use of update operations. It is possible to send raw DNS Messages with the Client, but for ease of use the `query` and various other update operations are recommended for general use.
//!
//! For a system-like resolver, see [trust-dns-resolver](https://docs.rs/trust-dns-resolver). This is most likely what you want if all you want to do is lookup IP addresses.
//!
//! For serving DNS serving, see [trust-dns-server](https://docs.rs/trust-dns-server).
//!
//! # Goals
//!
//! * Only safe Rust
//! * All errors handled
//! * Simple to manage servers
//! * High level abstraction for clients
//! * Secure dynamic update
//! * New features for securing public information
//!
//! # Usage
//!
//! This shows basic usage of the SyncClient. More examples will be associated directly with other types.
//!
//! ## Dependency
//!
//! ```toml
//! [dependencies]
//! trust-dns = "^0.14"
//! ```
//!
//! By default DNSSec validation is built in with OpenSSL, this can be disabled with:
//!
//! ```toml
//! [dependencies]
//! trust-dns = { version = "^0.10", default-features = false }
//! ```
//!
//! Extern the crate into your program or library:
//!
//! ```rust
//! extern crate trust_dns;
//! ```
//!
//! ## Objects
//!
//! There are two variations of implementations of the Client. The `SyncClient`, a synchronous client, and the `ClientFuture`, a Tokio async client. `SyncClient` is an implementation of the `Client` trait, there is another implementation, `SecureSyncClient`, which validates DNSSec records. For these basic examples we'll only look at the `SyncClient`
//!
//! First we must decide on the type of connection, there are three supported by TRust-DNS today, UDP, TCP and TLS. TLS requires OpenSSL by default, see also [trust-dns-native-tls](https://docs.rs/trust-dns-native-tls) and [trust-dns-rustls](https://docs.rs/trust-dns-rustls) for other TLS options.
//!
//! ## Setup a connection
//!
//! ```rust
//! use trust_dns::client::{Client, ClientConnection, ClientStreamHandle, SyncClient};
//! use trust_dns::udp::UdpClientConnection;
//!
//! let address = "8.8.8.8:53".parse().unwrap();
//! let conn = UdpClientConnection::new(address).unwrap();
//!
//! // and then create the Client
//! let client = SyncClient::new(conn);
//! ```
//!
//! At this point the client is ready to be used. See also `client::SecureSyncClient` for DNSSec validation. The rest of these examples will assume that the above boilerplate has already been performed.
//!
//! ## Querying
//!
//! Using the Client to query for DNS records is easy enough, though it performs no resolution. The `trust-dns-resolver` has a simpler interface if that's what is desired. Over time that library will gain more features to generically query for differnet types.
//!
//! ```rust
//! use std::net::Ipv4Addr;
//! use std::str::FromStr;
//! # use trust_dns::client::{Client, SyncClient};
//! # use trust_dns::udp::UdpClientConnection;
//! use trust_dns::op::DnsResponse;
//! use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType};
//! #
//! # let address = "8.8.8.8:53".parse().unwrap();
//! # let conn = UdpClientConnection::new(address).unwrap();
//! # let client = SyncClient::new(conn);
//!
//! // Specify the name, note the final '.' which specifies it's an FQDN
//! let name = Name::from_str("www.example.com.").unwrap();
//!
//! // NOTE: see 'Setup a connection' example above
//! // Send the query and get a message response, see RecordType for all supported options
//! let response: DnsResponse = client.query(&name, DNSClass::IN, RecordType::A).unwrap();
//!
//! // Messages are the packets sent between client and server in DNS.
//! //  there are many fields to a Message, DnsResponse can be dereferenced into
//! //  a Message. It's beyond the scope of these examples
//! //  to explain all the details of a Message. See trust_dns::op::message::Message for more details.
//! //  generally we will be insterested in the Message::answers
//! let answers: &[Record] = response.answers();
//!
//! // Records are generic objects which can contain any data.
//! //  In order to access it we need to first check what type of record it is
//! //  In this case we are interested in A, IPv4 address
//! if let &RData::A(ref ip) = answers[0].rdata() {
//!     assert_eq!(*ip, Ipv4Addr::new(93, 184, 216, 34))
//! } else {
//!     assert!(false, "unexpected result")
//! }
//! ```
//!
//! In the above example we successfully queried for a A record. There are many other types, each can be independenly queried and the associated `trust_dns::rr::record_data::RData` has a variant with the deserialized data for the record stored.
//!
//! ## Dynamic update
//!
//! Currently `trust-dns` supports SIG(0) signed records for authentication and authorization of dynamic DNS updates. It's beyond the scope of these examples to show how to setup SIG(0) authorization on the server. `trust-dns` is known to work with BIND9 and `trust-dns-server`. Expect in the future for TLS to become a potentially better option for authorization with certificate chains. These examples show using SIG(0) for auth, requires OpenSSL. It's beyond the scope of these examples to describe the configuration for the server.

//!
//! ```rust,no_run
//! # extern crate chrono;
//! # extern crate openssl;
//! # extern crate trust_dns;
//!
//! use std::fs::File;
//! use std::io::Read;
//! use std::net::Ipv4Addr;
//! use std::str::FromStr;
//!
//! use chrono::Duration;
//! # #[cfg(feature = "openssl")]
//! use openssl::rsa::Rsa;
//! # use trust_dns::client::Client;
//! # use trust_dns::udp::UdpClientConnection;
//! use trust_dns::client::SyncClient;
//! use trust_dns::rr::{Name, RData, Record, RecordType};
//! use trust_dns::rr::dnssec::{Algorithm, Signer, KeyPair};
//! use trust_dns::op::ResponseCode;
//! use trust_dns::rr::rdata::key::KEY;
//!
//! # #[cfg(feature = "openssl")]
//! # fn main() {
//! # let address = "0.0.0.0:53".parse().unwrap();
//! # let conn = UdpClientConnection::new(address).unwrap();
//!
//! // The format of the key is dependent on the KeyPair type, in this example we're using RSA
//! //  if the key was generated with BIND, the binary in TRust-DNS client lib `dnskey-to-pem`
//! //  can be used to convert this to a pem file
//! let mut pem = File::open("my_private_key.pem").unwrap();
//! let mut pem_buf = Vec::<u8>::new();
//! pem.read_to_end(&mut pem_buf).unwrap();
//!
//! // Create the RSA key
//! let rsa = Rsa::private_key_from_pem(&pem_buf).unwrap();
//! let key = KeyPair::from_rsa(rsa).unwrap();
//!
//! // Create the RData KEY associated with the key. This example uses defaults for all the
//! //  KeyTrust, KeyUsage, UpdateScope, Protocol. Many of these have been deprecated in current
//! //  DNS RFCs, but are still supported by many servers for auth. See auth docs of the remote
//! //  server for help in understanding it's requirements and support of these options.
//! let sig0key = KEY::new(Default::default(),
//!                        Default::default(),
//!                        Default::default(),
//!                        Default::default(),
//!                        Algorithm::RSASHA256,
//!                        key.to_public_bytes().unwrap());
//!
//! // Create the TRust-DNS SIG(0) signing facility. Generally the signer_name is the label
//! //  associated with KEY record in the server.
//! let signer = Signer::sig0(sig0key,
//!                           key,
//!                           Name::from_str("update.example.com.").unwrap());
//!
//! // Create the DNS client, see above for creating a the connection
//! let client = SyncClient::with_signer(conn, signer);
//!
//! // At this point we should have a client capable of sending signed SIG(0) records.
//!
//! // Now we can send updates... let's create a new Record
//! let mut record = Record::with(Name::from_str("new.example.com").unwrap(),
//!                               RecordType::A,
//!                               Duration::minutes(5).num_seconds() as u32);
//! record.set_rdata(RData::A(Ipv4Addr::new(100, 10, 100, 10)));
//!
//! // the server must be authoritative for this zone
//! let origin = Name::from_str("example.com.").unwrap();
//!
//! // Create the record.
//! let result = client.create(record, origin).unwrap();
//! assert_eq!(result.response_code(), ResponseCode::NoError);
//! # }
//! # #[cfg(not(feature = "openssl"))]
//! # fn main() {
//! # }
//! ```
//!
//! *Note*: The dynamic DNS functions defined by TRust-DNS are expressed as atomic operations, but this depends on support of the remote server. For example, the `create` operation shown above, should only succeed if there is no `RecordSet` of the specified type at the specified label. The other update operations are `append`, `compare_and_swap`, `delete_by_rdata`, `delete_rrset`, and `delete_all`. See the documentation for each of these methods on the `Client` trait.

extern crate chrono;
extern crate data_encoding;
#[macro_use]
extern crate data_encoding_macro;
#[macro_use]
extern crate failure;
extern crate futures;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(feature = "native-tls")]
extern crate native_tls;
#[cfg(feature = "openssl")]
extern crate openssl;
extern crate radix_trie;
extern crate rand;
#[cfg(feature = "ring")]
extern crate ring;
extern crate tokio;
#[cfg(feature = "tokio-openssl")]
extern crate tokio_openssl;
extern crate tokio_tcp;
#[cfg(feature = "tokio-tls")]
extern crate tokio_tls;
extern crate trust_dns_proto;
#[cfg(feature = "ring")]
extern crate untrusted;

pub mod client;
pub mod error;
#[cfg(feature = "mdns")]
pub mod multicast;
pub mod op;
pub mod rr;
pub mod serialize;
pub mod tcp;
pub mod udp;

/// A sender to which serialized DNS Messages can be sent
#[deprecated(note = "use [`trust_dns_proto::BufDnsStreamHandle`] instead")]
pub use trust_dns_proto::BufStreamHandle;

/// A sender to which a Message can be sent
// pub type MessageStreamHandle = UnboundedSender<Message>;
#[deprecated(note = "use [`trust_dns_proto::BufDnsStreamHandle`] instead")]
pub use trust_dns_proto::BufDnsStreamHandle as BufClientStreamHandle;

/// Returns a version as specified in Cargo.toml
pub fn version() -> &'static str {
    env!("CARGO_PKG_VERSION")
}
<|endoftext|>


<commit_before>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous code:
//!
//! - [Futures](::Future) (sometimes called promises), which represent a single
//! asychronous computation that may result in a final value or an error.
//!
//! - [Streams](::Stream), which represent a series of values or errors produced asynchronously.
//!
//! - [Sinks](::Sink), which support asynchronous writing of data.
//!
//! - [Executors](::executor), which are responsible for running asynchronous tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](::io) and
//! [cross-task communication](::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![feature(futures_api)]

#![no_std]
#![doc(html_root_url = "https://docs.rs/futures/0.2.0")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

// extern crate futures_async_runtime;
extern crate futures_core;
extern crate futures_channel;
extern crate futures_executor;
extern crate futures_io;
extern crate futures_sink;
extern crate futures_util;

#[cfg(feature = "nightly")] extern crate futures_macro_async;
#[cfg(feature = "nightly")] extern crate futures_macro_await;

pub use futures_core::future::Future;
pub use futures_util::future::FutureExt;
pub use futures_core::stream::Stream;
pub use futures_util::stream::StreamExt;
pub use futures_sink::Sink;
pub use futures_util::sink::SinkExt;

// Macros redefined here because macro re-exports are unstable.

/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes in propagation of both errors and `Pending` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::prelude::Async::Ready(t)) => t,
        Ok($crate::prelude::Async::Pending) => return Ok($crate::prelude::Async::Pending),
        Err(e) => return Err(From::from(e)),
    })
}

/// A macro to create a `static` of type `LocalKey`.
///
/// This macro is intentionally similar to the `thread_local!`, and creates a
/// `static` which has a `get_mut` method to access the data on a task.
///
/// The data associated with each task local is per-task, so different tasks
/// will contain different values.
#[macro_export]
macro_rules! task_local {
    (static $NAME:ident: $t:ty = $e:expr) => (
        static $NAME: $crate::task::LocalKey<$t> = {
            fn __init() -> $t { $e }
            fn __key() -> ::std::any::TypeId {
                struct __A;
                ::std::any::TypeId::of::<__A>()
            }
            $crate::task::LocalKey {
                __init: __init,
                __key: __key,
            }
        };
    )
}

pub use futures_core::Poll;

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](::channel::oneshot), a way of sending a single value from
    //! one task to another.
    //!
    //! - [mpsc](::channel::mpsc), a multi-producer, single-consumer channel for
    //! sending values between tasks, analogous to the similarly-named structure
    //! in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](::executor::ThreadPool). A small set of worker threads can handle
    //! a very large set of spawned tasks (which are much lighter weight than
    //! threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](::executor::ThreadPool::run) an initial task on it, which can
    //! then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! # #![feature(pin, arbitrary_self_types, futures_api)]
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app = lazy(|_| 42);
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().expect("Failed to create threadpool").run(my_app);
    //! ```
    //!
    //! The call to [`run`](::executor::ThreadPool::run) will block the current
    //! thread until the future defined by `my_app` completes, and will return
    //! the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //! [`spawn`](::executor::spawn) function or [pulling the executor from the
    //! task context](::task::Context::executor).
    //!
    //! - Spawn onto a specific executor by calling its
    //! [`spawn`](::executor::Executor::spawn) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](::executor::LocalPool) executor. Aside from cutting down
    //! on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local`](::executor::LocalExecutor::spawn_local). The `LocalPool`
    //! is best suited for running I/O-bound tasks that do relatively little
    //! work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.
    // TODO: add docs (or link to apr) for implementing an executor

    pub use futures_executor::{
        BlockingStream,
        Enter, EnterError,
        LocalExecutor, LocalPool,
        Spawn, SpawnWithHandle,
        ThreadPool, ThreadPoolBuilder, JoinHandle,
        block_on, block_on_stream, enter, spawn, spawn_with_handle
    };
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](::Future).
    //!
    //! - The [`FutureExt`](::future::FutureExt) trait, which provides adapters
    //! for chaining and composing futures.
    //!
    //! - Top-level future combinators like [`lazy`](::future::lazy) which
    //! creates a future from a closure that defines its return value, and
    //! [`result`](::future::result), which constructs a future with an
    //! immediate defined value.

    pub use futures_core::future::{
        FutureOption, Future, TryFuture, ReadyFuture, ready
    };
    pub use futures_util::future::{
        Empty, Flatten, FlattenStream, Fuse, Inspect, IntoStream, Lazy,
        Then, Either, PollFn, Map, FutureExt, empty, lazy, poll_fn,
        // AndThen, ErrInto, Join, Join3, Join4, Join5, LoopFn,
        // MapErr, OrElse, Select, Loop, loop_fn,
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        CatchUnwind,
        // JoinAll, SelectAll, SelectOk, Shared, SharedError, SharedItem,
        // join_all, select_all, select_ok
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](::io::AsyncRead) and
    //! [`AsyncWrite`](::io::AsyncWrite), which mirror the `Read` and `Write`
    //! traits of the standard library. However, these traits integrate with the
    //! asynchronous task system, so that if an I/O object isn't ready for
    //! reading (or writing), the thread is not blocked, and instead the current
    //! task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](::io::AsyncWriteExt) extension traits offer a variety
    //! of useful combinators for operating with asynchronous I/O objects,
    //! including ways to work with them using futures, streams and sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the standard
    //! library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use futures_core::{
        Future, TryFuture, Stream, Poll, task
    };

    #[cfg(feature = "nightly")]
    pub use futures_stable::{
        StableFuture,
        StableStream
    };

    #[cfg(all(feature = "nightly", feature = "std"))]
    pub use futures_stable::StableExecutor;

    pub use futures_sink::Sink;

    #[cfg(feature = "std")]
    pub use futures_io::{
        AsyncRead,
        AsyncWrite,
    };

    pub use futures_util::{
        FutureExt,
        TryFutureExt,
        StreamExt,
        SinkExt,
    };

    #[cfg(feature = "std")]
    pub use futures_util::{
        AsyncReadExt,
        AsyncWriteExt,
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_async::{
        async,
        async_stream,
        async_block,
        async_stream_block,
    };

    #[cfg(feature = "nightly")]
    pub use futures_macro_await::{
        await,
        stream_yield,
        await_item
    };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](::Sink), which allows you to asynchronously write data.
    //!
    //! - The [`SinkExt`](::sink::SinkExt) trait, which provides adapters
    //! for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        SinkExt, Fanout,
        // WithFlatMap,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](::Stream), for objects that can asynchronously
    //! produce a sequence of values.
    //!
    //! - The [`StreamExt`](::StreamExt) trait, which provides adapters
    //! for chaining and composing streams.
    //!
    //! - Top-level stream contructors like [`iter_ok`](::stream::iter_ok) which
    //! creates a stream from an iterator, and
    //! [`futures_unordered`](::stream::futures_unordered()), which constructs a
    //! stream from a collection of futures.

    pub use futures_core::stream::Stream;

    pub use futures_util::stream::{
        Chain, Concat, Empty, Filter, FilterMap, Flatten, Fold, ForEach, Fuse,
        Inspect, Map, Once, Peekable, PollFn, Repeat, Select, Skip, SkipWhile,
        StreamFuture, Take, TakeWhile, Then, Unfold, Zip, StreamExt, empty,
        once, poll_fn, repeat, unfold, iter
        // AndThen, Forward, ErrInto, InspectErr MapErr, OrElse
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        CatchUnwind, Chunks, Collect, futures_unordered
        // , select_all, BufferUnordered, Buffered,
        // FuturesUnordered, FuturesOrdered, ReuniteError, SelectAll, SplitSink,
        // SplitStream, futures_ordered,
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](::task::Context), which provides contextual data present
    //! for every task, including a handle for waking up the task.
    //!
    //! - [`Waker`](::task::Waker), a handle for waking up a task.
    //!
    //! - [`LocalKey`](::task::LocalKey), a key for task-local data; you should
    //! use the [`task_local` macro](../macro.task_local.html) to set up such keys.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](::executor). However, you can manually construct a task by
    //! creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, Waker, UnsafeWake,
        Executor,
        TaskObj, LocalTaskObj,
        SpawnErrorKind, SpawnObjError, SpawnLocalObjError,
    };

    #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
    pub use futures_core::task::AtomicWaker;

    #[cfg(feature = "std")]
    pub use futures_core::task::Wake;
}

#[cfg(feature = "nightly")]
pub mod stable {
    pub use futures_stable::{StableFuture, StableStream};

    #[cfg(feature = "std")]
    pub use futures_stable::{StableExecutor, block_on_stable};
}

#[cfg(feature = "nightly")]
#[doc(hidden)]
pub mod __rt {
    #[cfg(feature = "std")]
    pub extern crate std;
    pub use futures_async_runtime::*;
}
<commit_msg>Remove references to already removed crates when nightly is enabled<commit_after>//! Abstractions for asynchronous programming.
//!
//! This crate provides a number of core abstractions for writing asynchronous code:
//!
//! - [Futures](::Future) (sometimes called promises), which represent a single
//! asychronous computation that may result in a final value or an error.
//!
//! - [Streams](::Stream), which represent a series of values or errors produced asynchronously.
//!
//! - [Sinks](::Sink), which support asynchronous writing of data.
//!
//! - [Executors](::executor), which are responsible for running asynchronous tasks.
//!
//! The crate also contains abstractions for [asynchronous I/O](::io) and
//! [cross-task communication](::channel).
//!
//! Underlying all of this is the *task system*, which is a form of lightweight
//! threading. Large asynchronous computations are built up using futures,
//! streams and sinks, and then spawned as independent tasks that are run to
//! completion, but *do not block* the thread running them.

#![feature(futures_api)]

#![no_std]
#![doc(html_root_url = "https://docs.rs/futures/0.2.0")]

#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(feature = "nightly", feature(use_extern_macros))]

// extern crate futures_async_runtime;
extern crate futures_core;
extern crate futures_channel;
extern crate futures_executor;
extern crate futures_io;
extern crate futures_sink;
extern crate futures_util;

pub use futures_core::future::Future;
pub use futures_util::future::FutureExt;
pub use futures_core::stream::Stream;
pub use futures_util::stream::StreamExt;
pub use futures_sink::Sink;
pub use futures_util::sink::SinkExt;

// Macros redefined here because macro re-exports are unstable.

/// A macro for extracting the successful type of a `Poll<T, E>`.
///
/// This macro bakes in propagation of both errors and `Pending` signals by
/// returning early.
#[macro_export]
macro_rules! try_ready {
    ($e:expr) => (match $e {
        Ok($crate::prelude::Async::Ready(t)) => t,
        Ok($crate::prelude::Async::Pending) => return Ok($crate::prelude::Async::Pending),
        Err(e) => return Err(From::from(e)),
    })
}

/// A macro to create a `static` of type `LocalKey`.
///
/// This macro is intentionally similar to the `thread_local!`, and creates a
/// `static` which has a `get_mut` method to access the data on a task.
///
/// The data associated with each task local is per-task, so different tasks
/// will contain different values.
#[macro_export]
macro_rules! task_local {
    (static $NAME:ident: $t:ty = $e:expr) => (
        static $NAME: $crate::task::LocalKey<$t> = {
            fn __init() -> $t { $e }
            fn __key() -> ::std::any::TypeId {
                struct __A;
                ::std::any::TypeId::of::<__A>()
            }
            $crate::task::LocalKey {
                __init: __init,
                __key: __key,
            }
        };
    )
}

pub use futures_core::Poll;

#[cfg(feature = "std")]
pub mod channel {
    //! Cross-task communication.
    //!
    //! Like threads, concurrent tasks sometimes need to communicate with each
    //! other. This module contains two basic abstractions for doing so:
    //!
    //! - [oneshot](::channel::oneshot), a way of sending a single value from
    //! one task to another.
    //!
    //! - [mpsc](::channel::mpsc), a multi-producer, single-consumer channel for
    //! sending values between tasks, analogous to the similarly-named structure
    //! in the standard library.

    pub use futures_channel::{oneshot, mpsc};
}

#[cfg(feature = "std")]
pub mod executor {
    //! Task execution.
    //!
    //! All asynchronous computation occurs within an executor, which is
    //! capable of spawning futures as tasks. This module provides several
    //! built-in executors, as well as tools for building your own.
    //!
    //! # Using a thread pool (M:N task scheduling)
    //!
    //! Most of the time tasks should be executed on a [thread
    //! pool](::executor::ThreadPool). A small set of worker threads can handle
    //! a very large set of spawned tasks (which are much lighter weight than
    //! threads).
    //!
    //! The simplest way to use a thread pool is to
    //! [`run`](::executor::ThreadPool::run) an initial task on it, which can
    //! then spawn further tasks back onto the pool to complete its work:
    //!
    //! ```
    //! # #![feature(pin, arbitrary_self_types, futures_api)]
    //! use futures::executor::ThreadPool;
    //! # use futures::future::{Future, lazy};
    //! # let my_app = lazy(|_| 42);
    //!
    //! // assumping `my_app: Future`
    //! ThreadPool::new().expect("Failed to create threadpool").run(my_app);
    //! ```
    //!
    //! The call to [`run`](::executor::ThreadPool::run) will block the current
    //! thread until the future defined by `my_app` completes, and will return
    //! the result of that future.
    //!
    //! # Spawning additional tasks
    //!
    //! There are two ways to spawn a task:
    //!
    //! - Spawn onto a "default" execuctor by calling the top-level
    //! [`spawn`](::executor::spawn) function or [pulling the executor from the
    //! task context](::task::Context::executor).
    //!
    //! - Spawn onto a specific executor by calling its
    //! [`spawn`](::executor::Executor::spawn) method directly.
    //!
    //! Every task always has an associated default executor, which is usually
    //! the executor on which the task is running.
    //!
    //! # Single-threaded execution
    //!
    //! In addition to thread pools, it's possible to run a task (and the tasks
    //! it spawns) entirely within a single thread via the
    //! [`LocalPool`](::executor::LocalPool) executor. Aside from cutting down
    //! on synchronization costs, this executor also makes it possible to
    //! execute non-`Send` tasks, via
    //! [`spawn_local`](::executor::LocalExecutor::spawn_local). The `LocalPool`
    //! is best suited for running I/O-bound tasks that do relatively little
    //! work between I/O operations.
    //!
    //! There is also a convenience function,
    //! [`block_on`](::executor::block_on), for simply running a future to
    //! completion on the current thread, while routing any spawned tasks
    //! to a global thread pool.
    // TODO: add docs (or link to apr) for implementing an executor

    pub use futures_executor::{
        BlockingStream,
        Enter, EnterError,
        LocalExecutor, LocalPool,
        Spawn, SpawnWithHandle,
        ThreadPool, ThreadPoolBuilder, JoinHandle,
        block_on, block_on_stream, enter, spawn, spawn_with_handle
    };
}

pub mod future {
    //! Asynchronous values.
    //!
    //! This module contains:
    //!
    //! - The [`Future` trait](::Future).
    //!
    //! - The [`FutureExt`](::future::FutureExt) trait, which provides adapters
    //! for chaining and composing futures.
    //!
    //! - Top-level future combinators like [`lazy`](::future::lazy) which
    //! creates a future from a closure that defines its return value, and
    //! [`result`](::future::result), which constructs a future with an
    //! immediate defined value.

    pub use futures_core::future::{
        FutureOption, Future, TryFuture, ReadyFuture, ready
    };
    pub use futures_util::future::{
        Empty, Flatten, FlattenStream, Fuse, Inspect, IntoStream, Lazy,
        Then, Either, PollFn, Map, FutureExt, empty, lazy, poll_fn,
        // AndThen, ErrInto, Join, Join3, Join4, Join5, LoopFn,
        // MapErr, OrElse, Select, Loop, loop_fn,
    };

    #[cfg(feature = "std")]
    pub use futures_util::future::{
        CatchUnwind,
        // JoinAll, SelectAll, SelectOk, Shared, SharedError, SharedItem,
        // join_all, select_all, select_ok
    };
}

#[cfg(feature = "std")]
pub mod io {
    //! Asynchronous I/O.
    //!
    //! This module is the asynchronous version of `std::io`. It defines two
    //! traits, [`AsyncRead`](::io::AsyncRead) and
    //! [`AsyncWrite`](::io::AsyncWrite), which mirror the `Read` and `Write`
    //! traits of the standard library. However, these traits integrate with the
    //! asynchronous task system, so that if an I/O object isn't ready for
    //! reading (or writing), the thread is not blocked, and instead the current
    //! task is queued to be woken when I/O is ready.
    //!
    //! In addition, the [`AsyncReadExt`](::io::AsyncReadExt) and
    //! [`AsyncWriteExt`](::io::AsyncWriteExt) extension traits offer a variety
    //! of useful combinators for operating with asynchronous I/O objects,
    //! including ways to work with them using futures, streams and sinks.

    pub use futures_io::{
        Error, Initializer, IoVec, ErrorKind, AsyncRead, AsyncWrite, Result
    };
    pub use futures_util::io::{
        AsyncReadExt, AsyncWriteExt, AllowStdIo, Close, CopyInto, Flush,
        Read, ReadExact, ReadHalf, ReadToEnd, Window, WriteAll, WriteHalf,
    };
}

pub mod prelude {
    //! A "prelude" for crates using the `futures` crate.
    //!
    //! This prelude is similar to the standard library's prelude in that you'll
    //! almost always want to import its entire contents, but unlike the standard
    //! library's prelude you'll have to do so manually:
    //!
    //! ```
    //! use futures::prelude::*;
    //! ```
    //!
    //! The prelude may grow over time as additional items see ubiquitous use.

    pub use futures_core::{
        Future, TryFuture, Stream, Poll, task
    };

    pub use futures_sink::Sink;

    #[cfg(feature = "std")]
    pub use futures_io::{
        AsyncRead,
        AsyncWrite,
    };

    pub use futures_util::{
        FutureExt,
        TryFutureExt,
        StreamExt,
        SinkExt,
    };

    #[cfg(feature = "std")]
    pub use futures_util::{
        AsyncReadExt,
        AsyncWriteExt,
    };
}

pub mod sink {
    //! Asynchronous sinks.
    //!
    //! This module contains:
    //!
    //! - The [`Sink` trait](::Sink), which allows you to asynchronously write data.
    //!
    //! - The [`SinkExt`](::sink::SinkExt) trait, which provides adapters
    //! for chaining and composing sinks.

    pub use futures_sink::Sink;

    pub use futures_util::sink::{
        Close, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
        SinkExt, Fanout,
        // WithFlatMap,
    };

    #[cfg(feature = "std")]
    pub use futures_util::sink::Buffer;
}

pub mod stream {
    //! Asynchronous streams.
    //!
    //! This module contains:
    //!
    //! - The [`Stream` trait](::Stream), for objects that can asynchronously
    //! produce a sequence of values.
    //!
    //! - The [`StreamExt`](::StreamExt) trait, which provides adapters
    //! for chaining and composing streams.
    //!
    //! - Top-level stream contructors like [`iter_ok`](::stream::iter_ok) which
    //! creates a stream from an iterator, and
    //! [`futures_unordered`](::stream::futures_unordered()), which constructs a
    //! stream from a collection of futures.

    pub use futures_core::stream::Stream;

    pub use futures_util::stream::{
        Chain, Concat, Empty, Filter, FilterMap, Flatten, Fold, ForEach, Fuse,
        Inspect, Map, Once, Peekable, PollFn, Repeat, Select, Skip, SkipWhile,
        StreamFuture, Take, TakeWhile, Then, Unfold, Zip, StreamExt, empty,
        once, poll_fn, repeat, unfold, iter
        // AndThen, Forward, ErrInto, InspectErr MapErr, OrElse
    };

    #[cfg(feature = "std")]
    pub use futures_util::stream::{
        CatchUnwind, Chunks, Collect, futures_unordered
        // , select_all, BufferUnordered, Buffered,
        // FuturesUnordered, FuturesOrdered, ReuniteError, SelectAll, SplitSink,
        // SplitStream, futures_ordered,
    };
}

pub mod task {
    //! Tools for working with tasks.
    //!
    //! This module contains:
    //!
    //! - [`Context`](::task::Context), which provides contextual data present
    //! for every task, including a handle for waking up the task.
    //!
    //! - [`Waker`](::task::Waker), a handle for waking up a task.
    //!
    //! - [`LocalKey`](::task::LocalKey), a key for task-local data; you should
    //! use the [`task_local` macro](../macro.task_local.html) to set up such keys.
    //!
    //! Tasks themselves are generally created by spawning a future onto [an
    //! executor](::executor). However, you can manually construct a task by
    //! creating your own `Context` instance, and polling a future with it.
    //!
    //! The remaining types and traits in the module are used for implementing
    //! executors or dealing with synchronization issues around task wakeup.

    pub use futures_core::task::{
        Context, Waker, UnsafeWake,
        Executor,
        TaskObj, LocalTaskObj,
        SpawnErrorKind, SpawnObjError, SpawnLocalObjError,
    };

    #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
    pub use futures_core::task::AtomicWaker;

    #[cfg(feature = "std")]
    pub use futures_core::task::Wake;
}
<|endoftext|>


<commit_before>use nix::poll::{PollFlags, poll, PollFd};
use nix::unistd::{write, pipe};

#[test]
fn test_poll() {
    let (r, w) = pipe().unwrap();
    let mut fds = [PollFd::new(r, PollFlags::POLLIN)];

    // Poll an idle pipe.  Should timeout
    let nfds = poll(&mut fds, 100).unwrap();
    assert_eq!(nfds, 0);
    assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));

    write(w, b".").unwrap();

    // Poll a readable pipe.  Should return an event.
    let nfds = poll(&mut fds, 100).unwrap();
    assert_eq!(nfds, 1);
    assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
}

// ppoll(2) is the same as poll except for how it handles timeouts and signals.
// Repeating the test for poll(2) should be sufficient to check that our
// bindings are correct.
#[cfg(any(target_os = "android",
          target_os = "dragonfly",
          target_os = "freebsd",
          target_os = "linux"))]
#[test]
fn test_ppoll() {
    use nix::poll::ppoll;
    use nix::sys::signal::SigSet;
    use nix::sys::time::{TimeSpec, TimeValLike};

    let timeout = TimeSpec::milliseconds(1);
    let (r, w) = pipe().unwrap();
    let mut fds = [PollFd::new(r, PollFlags::POLLIN)];

    // Poll an idle pipe.  Should timeout
    let nfds = ppoll(&mut fds, Some(timeout), SigSet::empty()).unwrap();
    assert_eq!(nfds, 0);
    assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));

    write(w, b".").unwrap();

    // Poll a readable pipe.  Should return an event.
    let nfds = ppoll(&mut fds, Some(timeout), SigSet::empty()).unwrap();
    assert_eq!(nfds, 1);
    assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
}
<commit_msg>Make the poll tests resilient against signals<commit_after>use nix::{
    Error,
    errno::Errno,
    poll::{PollFlags, poll, PollFd},
    unistd::{write, pipe}
};

macro_rules! loop_while_eintr {
    ($poll_expr: expr) => {
        loop {
            match $poll_expr {
                Ok(nfds) => break nfds,
                Err(Error::Sys(Errno::EINTR)) => (),
                Err(e) => panic!(e)
            }
        }
    }
}

#[test]
fn test_poll() {
    let (r, w) = pipe().unwrap();
    let mut fds = [PollFd::new(r, PollFlags::POLLIN)];

    // Poll an idle pipe.  Should timeout
    let nfds = loop_while_eintr!(poll(&mut fds, 100));
    assert_eq!(nfds, 0);
    assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));

    write(w, b".").unwrap();

    // Poll a readable pipe.  Should return an event.
    let nfds = poll(&mut fds, 100).unwrap();
    assert_eq!(nfds, 1);
    assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
}

// ppoll(2) is the same as poll except for how it handles timeouts and signals.
// Repeating the test for poll(2) should be sufficient to check that our
// bindings are correct.
#[cfg(any(target_os = "android",
          target_os = "dragonfly",
          target_os = "freebsd",
          target_os = "linux"))]
#[test]
fn test_ppoll() {
    use nix::poll::ppoll;
    use nix::sys::signal::SigSet;
    use nix::sys::time::{TimeSpec, TimeValLike};

    let timeout = TimeSpec::milliseconds(1);
    let (r, w) = pipe().unwrap();
    let mut fds = [PollFd::new(r, PollFlags::POLLIN)];

    // Poll an idle pipe.  Should timeout
    let sigset = SigSet::empty();
    let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), sigset));
    assert_eq!(nfds, 0);
    assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));

    write(w, b".").unwrap();

    // Poll a readable pipe.  Should return an event.
    let nfds = ppoll(&mut fds, Some(timeout), SigSet::empty()).unwrap();
    assert_eq!(nfds, 1);
    assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;

extern crate futures;
extern crate tokio_core;
extern crate byteorder;

use std::thread;
use std::sync::mpsc::channel;
//use futures::stream::Stream;
//use tokio_core::reactor::Core;
//use tokio_core::net::TcpListener;
use std::net::TcpStream;
use std::net::TcpListener;
use std::collections::HashMap;
use std::io::Write;
use std::time::Duration;
use std::option::Option;
//use std::io::Read;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
//use futures::Future;
use std::sync::{Arc, Mutex};
use std::io::{Error, ErrorKind};
use std::str;
use std::io::Cursor;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

mod userchannel;
mod messaging;
use messaging::*;

fn read_n<R>(reader: R, bytes_to_read: u64) -> (Result<usize, Error>, Vec<u8>)
where R: Read,
{
    let mut buf = vec![];
    let mut chunk = reader.take(bytes_to_read);
    let status = chunk.read_to_end(&mut buf);
    /*
    match status {
        Ok(n) => assert_eq!(bytes_to_read as usize, n),
        Ok(0) => ,
        Err(_) => return vec![]
    }*/
    (status, buf)
 }

fn read_hdr_type(hdr: &[u8]) -> u32 {
    let mut buf = Cursor::new(&hdr[..]);
    let num = buf.read_u32::<BigEndian>().unwrap();
    num >> 24
}

fn read_hdr_len(hdr: &[u8]) -> usize {
    let mut buf = Cursor::new(&hdr[..]);
    let num = buf.read_u32::<BigEndian>().unwrap();
    (num & 0xfff) as usize
}

fn write_hdr(len: usize) -> Vec<u8> {
    let hdr = (('M' as u32) << 24) | len as u32;
    let mut msgv = vec![];
    msgv.write_u32::<BigEndian>(hdr).unwrap();
    msgv
}

fn main() {
    let address = "0.0.0.0:8081";
    let listener = TcpListener::bind(&address).unwrap();
    let mut spawned = HashMap::new();
    let option: Option<Duration> = Some(Duration::from_millis(50));
    let mut cnt = 0;

    let addr = listener.local_addr().unwrap();
    println!("Listening for connections on {}", addr);
    let (tx, rx) = channel();
    let (removedtx, removedrx) = channel();

    for socket in listener.incoming() {
        /* Check first has anybody removed channels */
        match removedrx.try_recv() {
            Ok(val) => {
                let removed_channel: Vec<u8> = val;
                println!("Removing unused channel {}", String::from_utf8_lossy(removed_channel.as_slice()).into_owned().as_str());
                spawned.remove(&removed_channel);
            },
            Err(_) => {}
        }
        /* 1. Read incoming msg channel
         * 2. If it does not exist, spawn new thread
         * 3. Send socket to thread
         */
        let mut socket = socket.unwrap();
        let mut stream = socket.try_clone().unwrap();
        let tuple = read_n(&stream, 4);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(n) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        if 0 == buf.len() {
            continue;
        }
        if read_hdr_type(buf.as_slice()) != 'M' as u32 {
            println!("Incorrect payload type");
            continue;
        }
        println!("Payload len {}", read_hdr_len(buf.as_slice()));
        let tuple = read_n(&stream, read_hdr_len(buf.as_slice()) as u64);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(n) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        let decoded_msg = messaging::message_decode(buf.as_slice());
        if 0 == decoded_msg.message.len() {
            continue;
        }
        socket.set_nodelay(true);
        socket.set_read_timeout(option);
        if !spawned.contains_key(&decoded_msg.message[1]) {
            let tx = tx.clone();
            let removedtx = removedtx.clone();
            let this_channel = decoded_msg.message[1].clone();
            //let user = String::from_utf8_lossy(decoded_msg.message[0].clone().as_slice()).into_owned().as_str();
            //println!("Got {}", user);
            thread::spawn(move|| {
                let (thr_tx, thr_rx) = channel();
                println!("Spawned: New channel created!");
                let mut users = HashMap::new();
                let mut messages: Vec<Vec<u8>> = Vec::new();
                tx.send(thr_tx.clone()).unwrap();
                loop {
                    let mut removals = Vec::new();
                    match thr_rx.try_recv() {
                        Ok(val) => {
                            let mut thr: TcpStream = val;
                            cnt += 1;
                            println!("Adding {}", cnt);
                            users.insert(cnt, thr.try_clone().unwrap());

                            /* If a new user, all push messages to her */
                            for buf in &messages {
                                println!("Historial msg is {:?}", buf);
                                thr.write(buf.as_slice()).unwrap();
                            }
                        },
                        Err(_) => {}
                    }
                    for (user, thr_socket) in &users {
                        let stream = thr_socket.try_clone().unwrap();
                        let tuple = read_n(&stream, 4);
                        let status = tuple.0;
                        match status {
                            Ok(0) => {
                                removals.push(user.clone());
                            },
                            _ => {}
                        }
                        let mut buf = tuple.1;
                        if 0 == buf.len() {
                            continue;
                        }
                        println!("Got buf len {}", buf.len());
                        if read_hdr_type(buf.as_slice()) != 'M' as u32 {
                            continue;
                        }
                        println!("Ok hdr type");
                        let hdr_len = read_hdr_len(buf.as_slice()) as u64;
                        println!("Hdr_len {}", hdr_len);
                        if 0 == hdr_len {
                            continue;
                        }
                        let tuple = read_n(&stream, hdr_len);
                        let status = tuple.0;
                        match status {
                            Ok(0) => {
                                removals.push(user.clone());
                            },
                            _ => {}
                        }
                        let payload = tuple.1;
                        println!("Payload len {}", payload.len());
                        if payload.len() != (hdr_len as usize) {
                            continue;
                        }
                        buf.extend(payload);
                        for (another_user, mut thr_sock) in &users {
                            if user != another_user {
                                println!("Msg is {:?}", buf);
                                thr_sock.write(buf.as_slice()).unwrap();
                            }
                        }
                        /* Add to local db */
                        messages.push(buf);
                    }
                    for removal in &removals {
                        println!("Removing user {}", removal);
                        users.remove(removal);
                    }
                    if cnt > 0 && users.is_empty() {
                        removedtx.send(this_channel).unwrap();
                        break;
                    }
                }
            });
            let thr_feed = rx.recv().unwrap();
            println!("Channel {}", String::from_utf8_lossy(decoded_msg.message[1].as_slice()).into_owned().as_str());
            spawned.insert(decoded_msg.message[1].clone(), thr_feed);
        }
        let thr_socket = spawned.get_mut(&decoded_msg.message[1]).unwrap();
        thr_socket.send(socket).unwrap();
    }
}
<commit_msg>Several removals fixed.<commit_after>#[macro_use]
extern crate serde_derive;

extern crate futures;
extern crate tokio_core;
extern crate byteorder;

use std::thread;
use std::sync::mpsc::channel;
//use futures::stream::Stream;
//use tokio_core::reactor::Core;
//use tokio_core::net::TcpListener;
use std::net::TcpStream;
use std::net::TcpListener;
use std::collections::HashMap;
use std::io::Write;
use std::time::Duration;
use std::option::Option;
//use std::io::Read;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
//use futures::Future;
use std::sync::{Arc, Mutex};
use std::io::{Error, ErrorKind};
use std::str;
use std::io::Cursor;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

mod userchannel;
mod messaging;
use messaging::*;

fn read_n<R>(reader: R, bytes_to_read: u64) -> (Result<usize, Error>, Vec<u8>)
where R: Read,
{
    let mut buf = vec![];
    let mut chunk = reader.take(bytes_to_read);
    let status = chunk.read_to_end(&mut buf);
    /*
    match status {
        Ok(n) => assert_eq!(bytes_to_read as usize, n),
        Ok(0) => ,
        Err(_) => return vec![]
    }*/
    (status, buf)
 }

fn read_hdr_type(hdr: &[u8]) -> u32 {
    let mut buf = Cursor::new(&hdr[..]);
    let num = buf.read_u32::<BigEndian>().unwrap();
    num >> 24
}

fn read_hdr_len(hdr: &[u8]) -> usize {
    let mut buf = Cursor::new(&hdr[..]);
    let num = buf.read_u32::<BigEndian>().unwrap();
    (num & 0xfff) as usize
}

fn write_hdr(len: usize) -> Vec<u8> {
    let hdr = (('M' as u32) << 24) | len as u32;
    let mut msgv = vec![];
    msgv.write_u32::<BigEndian>(hdr).unwrap();
    msgv
}

fn main() {
    let address = "0.0.0.0:8081";
    let listener = TcpListener::bind(&address).unwrap();
    let mut spawned = HashMap::new();
    let option: Option<Duration> = Some(Duration::from_millis(50));
    let mut cnt = 0;

    let addr = listener.local_addr().unwrap();
    println!("Listening for connections on {}", addr);
    let (tx, rx) = channel();
    let (removedtx, removedrx) = channel();

    for socket in listener.incoming() {
        /* Check first has anybody removed channels */
        let mut remrx = false;
        match removedrx.try_recv() {
            Ok(val) => {
                let removed_channel: Vec<u8> = val;
                println!("Removing unused channel {}", String::from_utf8_lossy(removed_channel.as_slice()).into_owned().as_str());
                spawned.remove(&removed_channel);
                remrx = true;
            },
            Err(_) => {}
        }
        while (remrx) {
            match removedrx.try_recv() {
                Ok(val) => {
                    let removed_channel: Vec<u8> = val;
                    println!("Removing unused channel {}", String::from_utf8_lossy(removed_channel.as_slice()).into_owned().as_str());
                    spawned.remove(&removed_channel);
                    remrx = true;
                },
                Err(_) => { remrx = false; }
            }
        }
        /* 1. Read incoming msg channel
         * 2. If it does not exist, spawn new thread
         * 3. Send socket to thread
         */
        let mut socket = socket.unwrap();
        let mut stream = socket.try_clone().unwrap();
        let tuple = read_n(&stream, 4);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(n) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        if 0 == buf.len() {
            continue;
        }
        if read_hdr_type(buf.as_slice()) != 'M' as u32 {
            println!("Incorrect payload type");
            continue;
        }
        println!("Payload len {}", read_hdr_len(buf.as_slice()));
        let tuple = read_n(&stream, read_hdr_len(buf.as_slice()) as u64);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(n) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        let decoded_msg = messaging::message_decode(buf.as_slice());
        if 0 == decoded_msg.message.len() {
            continue;
        }
        socket.set_nodelay(true);
        socket.set_read_timeout(option);
        if !spawned.contains_key(&decoded_msg.message[1]) {
            let tx = tx.clone();
            let removedtx = removedtx.clone();
            let this_channel = decoded_msg.message[1].clone();
            //let user = String::from_utf8_lossy(decoded_msg.message[0].clone().as_slice()).into_owned().as_str();
            //println!("Got {}", user);
            thread::spawn(move|| {
                let (thr_tx, thr_rx) = channel();
                println!("Spawned: New channel created!");
                let mut users = HashMap::new();
                let mut messages: Vec<Vec<u8>> = Vec::new();
                tx.send(thr_tx.clone()).unwrap();
                loop {
                    let mut removals = Vec::new();
                    match thr_rx.try_recv() {
                        Ok(val) => {
                            let mut thr: TcpStream = val;
                            cnt += 1;
                            println!("Adding {}", cnt);
                            users.insert(cnt, thr.try_clone().unwrap());

                            /* If a new user, all push messages to her */
                            for buf in &messages {
                                println!("Historial msg is {:?}", buf);
                                thr.write(buf.as_slice()).unwrap();
                            }
                        },
                        Err(_) => {}
                    }
                    for (user, thr_socket) in &users {
                        let stream = thr_socket.try_clone().unwrap();
                        let tuple = read_n(&stream, 4);
                        let status = tuple.0;
                        match status {
                            Ok(0) => {
                                removals.push(user.clone());
                            },
                            _ => {}
                        }
                        let mut buf = tuple.1;
                        if 0 == buf.len() {
                            continue;
                        }
                        println!("Got buf len {}", buf.len());
                        if read_hdr_type(buf.as_slice()) != 'M' as u32 {
                            continue;
                        }
                        println!("Ok hdr type");
                        let hdr_len = read_hdr_len(buf.as_slice()) as u64;
                        println!("Hdr_len {}", hdr_len);
                        if 0 == hdr_len {
                            continue;
                        }
                        let tuple = read_n(&stream, hdr_len);
                        let status = tuple.0;
                        match status {
                            Ok(0) => {
                                removals.push(user.clone());
                            },
                            _ => {}
                        }
                        let payload = tuple.1;
                        println!("Payload len {}", payload.len());
                        if payload.len() != (hdr_len as usize) {
                            continue;
                        }
                        buf.extend(payload);
                        for (another_user, mut thr_sock) in &users {
                            if user != another_user {
                                println!("Msg is {:?}", buf);
                                thr_sock.write(buf.as_slice()).unwrap();
                            }
                        }
                        /* Add to local db */
                        messages.push(buf);
                    }
                    for removal in &removals {
                        println!("Removing user {}", removal);
                        users.remove(removal);
                    }
                    if cnt > 0 && users.is_empty() {
                        removedtx.send(this_channel).unwrap();
                        break;
                    }
                }
            });
            let thr_feed = rx.recv().unwrap();
            println!("Channel {}", String::from_utf8_lossy(decoded_msg.message[1].as_slice()).into_owned().as_str());
            spawned.insert(decoded_msg.message[1].clone(), thr_feed);
        }
        let thr_socket = spawned.get_mut(&decoded_msg.message[1]).unwrap();
        thr_socket.send(socket).unwrap();
    }
}
<|endoftext|>


<commit_before>#![warn(warnings)]

extern crate cobalt;
extern crate env_logger;
extern crate ghp;
extern crate hyper;
extern crate notify;
extern crate serde_yaml;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;

mod args;
mod build;
mod debug;
mod error;
mod new;
mod serve;

use clap::{App, AppSettings};

use error::*;

quick_main!(run);

fn run() -> Result<()> {
    let app_cli = App::new("Cobalt")
        .version(crate_version!())
        .author("Benny Klotz <r3qnbenni@gmail.com>, Johann Hofmann")
        .about("A static site generator written in Rust.")
        .setting(AppSettings::SubcommandRequired)
        .setting(AppSettings::GlobalVersion)
        .args(&args::get_logging_args())
        .subcommand(new::init_command_args())
        .subcommand(new::new_command_args())
        .subcommand(new::rename_command_args())
        .subcommand(new::publish_command_args())
        .subcommand(build::build_command_args())
        .subcommand(build::clean_command_args())
        .subcommand(serve::serve_command_args())
        .subcommand(build::import_command_args())
        .subcommand(debug::debug_command_args());

    let global_matches = app_cli.get_matches();

    let (command, matches) = match global_matches.subcommand() {
        (command, Some(matches)) => (command, matches),
        (_, None) => unreachable!(),
    };

    let mut builder = args::get_logging(&global_matches, matches)?;
    builder.init();

    match command {
        "init" => new::init_command(matches),
        "new" => new::new_command(matches),
        "rename" => new::rename_command(matches),
        "publish" => new::publish_command(matches),
        "build" => build::build_command(matches),
        "clean" => build::clean_command(matches),
        "serve" => serve::serve_command(matches),
        "import" => build::import_command(matches),
        "debug" => debug::debug_command(matches),
        _ => {
            bail!(global_matches.usage());
        }
    }.chain_err(|| format!("{} command failed", command))?;

    Ok(())
}
<commit_msg>perf: Switch to system allocator<commit_after>#![warn(warnings)]

extern crate cobalt;
extern crate env_logger;
extern crate ghp;
extern crate hyper;
extern crate notify;
extern crate serde_yaml;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate clap;

#[macro_use]
extern crate log;

mod args;
mod build;
mod debug;
mod error;
mod new;
mod serve;

use std::alloc;

use clap::{App, AppSettings};

use error::*;

#[global_allocator]
static GLOBAL: alloc::System = alloc::System;

quick_main!(run);

fn run() -> Result<()> {
    let app_cli = App::new("Cobalt")
        .version(crate_version!())
        .author("Benny Klotz <r3qnbenni@gmail.com>, Johann Hofmann")
        .about("A static site generator written in Rust.")
        .setting(AppSettings::SubcommandRequired)
        .setting(AppSettings::GlobalVersion)
        .args(&args::get_logging_args())
        .subcommand(new::init_command_args())
        .subcommand(new::new_command_args())
        .subcommand(new::rename_command_args())
        .subcommand(new::publish_command_args())
        .subcommand(build::build_command_args())
        .subcommand(build::clean_command_args())
        .subcommand(serve::serve_command_args())
        .subcommand(build::import_command_args())
        .subcommand(debug::debug_command_args());

    let global_matches = app_cli.get_matches();

    let (command, matches) = match global_matches.subcommand() {
        (command, Some(matches)) => (command, matches),
        (_, None) => unreachable!(),
    };

    let mut builder = args::get_logging(&global_matches, matches)?;
    builder.init();

    match command {
        "init" => new::init_command(matches),
        "new" => new::new_command(matches),
        "rename" => new::rename_command(matches),
        "publish" => new::publish_command(matches),
        "build" => build::build_command(matches),
        "clean" => build::clean_command(matches),
        "serve" => serve::serve_command(matches),
        "import" => build::import_command(matches),
        "debug" => debug::debug_command(matches),
        _ => {
            bail!(global_matches.usage());
        }
    }.chain_err(|| format!("{} command failed", command))?;

    Ok(())
}
<|endoftext|>