//! This library provides a toolkit for rapid protocol development and usage,
//! working with the rest of the Tokio stack.
//!
//! You can find extensive documentation and tutorials in addition to this
//! documentation at [https://tokio.rs](https://tokio.rs)
//!
//! # Protocols
//!
//! Here, a **protocol** is a way of providing or consuming a service. Protocols
//! are implemented via traits, which are arranged into a taxonomy:
//!
//! - `pipeline::{ClientProto, ServerProto}`
//! - `multiplex::{ClientProto, ServerProto}`
//! - `streaming::pipeline::{ClientProto, ServerProto}`
//! - `streaming::multiplex::{ClientProto, ServerProto}`
//!
//! ### Pipeline vs multiplex
//!
//! By default, protocols allow a client to transmit multiple requests without
//! waiting for the corresponding responses, which is commonly used to improve
//! the throughput of single connections.
//!
//! In a **pipelined protocol**, the server responds to client requests in the
//! order they were sent. Example pipelined protocols include HTTP/1.1 and Redis.
//! Pipelining with the max number of in-flight requests set to 1 implies that
//! for each request, the response must be received before sending another
//! request on the same connection.
//!
//! In a **multiplexed protocol**, the server responds to client requests in the
//! order of completion. Request IDs are used to match responses back to requests.
//!
//! In both cases, if multiple requests are sent, the service running on the
//! server *may* process them concurrently, although many services will impose
//! some restrictions depending on the request type.
//!
//! ### Streaming
//!
//! In a non-streaming protocols, the client sends a complete request in a
//! single message, and the server provides a complete response in a single
//! message. Protocol tools in this style are available in the top-level `pipeline`
//! and `multiplex` modules.
//!
//! In a **streaming protocol**, requests and responses can carry **body
//! streams**, which allows partial processing before the complete body has been
//! transferred. Streaming protocol tools are found within the `streaming`
//! submodule.
//!
//! # Transports
//!
//! A key part of any protocol is its **transport**, which is the way that it
//! sends and receives *frames* on its connection. For simple protocols, these
//! frames correspond directly to complete requests and responses. For more
//! complicated protocols, they carry additional metadata, and may only be one
//! part of a request or response body.
//!
//! Transports are defined by implementing the `transport::Transport` trait. The
//! `transport::CodecTransport` type can be used to wrap a `Codec` (from
//! `tokio-core`), which is a simple way to build a transport.
//!
//! # An example server
//!
//! The following code shows how to implement a simple server that receives
//! newline-separated integer values, doubles them, and returns them. It
//! illustrates several aspects of the Tokio stack:
//!
//! - Implementing a codec `IntCodec` for reading and writing integers from a
//! byte buffer.
//! - Implementing a server protocol `IntProto` using this codec as a transport.
//! - Implementing a service `Doubler` for doubling integers.
//! - Spinning up this service on a local port (in `main`).
//!
//! ```no_run
//! extern crate futures;
//! extern crate tokio_core;
//! extern crate tokio_proto;
//! extern crate tokio_service;
//!
//! use std::str;
//! use std::io::{self, ErrorKind, Write};
//!
//! use futures::{future, Future, BoxFuture};
//! use tokio_core::io::{Io, Codec, Framed, EasyBuf};
//! use tokio_proto::TcpServer;
//! use tokio_proto::pipeline::ServerProto;
//! use tokio_service::Service;
//!
//! // First, we implement a *codec*, which provides a way of encoding and
//! // decoding messages for the protocol. See the documentation for `Codec` in
//! // `tokio-core` for more details on how that works.
//!
//! #[derive(Default)]
//! pub struct IntCodec;
//!
//! fn parse_u64(from: &[u8]) -> Result<u64, io::Error> {
//! Ok(str::from_utf8(from)
//! .map_err(|e| io::Error::new(ErrorKind::InvalidData, e))?
//! .parse()
//! .map_err(|e| io::Error::new(ErrorKind::InvalidData, e))?)
//! }
//!
//! impl Codec for IntCodec {
//! type In = u64;
//! type Out = u64;
//!
//! // Attempt to decode a message from the given buffer if a complete
//! // message is available; returns `Ok(None)` if the buffer does not yet
//! // hold a complete message.
//! fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<u64>, io::Error> {
//! if let Some(i) = buf.as_slice().iter().position(|&b| b == b'\n') {
//! // remove the line, including the '\n', from the buffer
//! let full_line = buf.drain_to(i + 1);
//!
//! // strip the'`\n'
//! let slice = &full_line.as_slice()[..i];
//!
//! Ok(Some(parse_u64(slice)?))
//! } else {
//! Ok(None)
//! }
//! }
//!
//! // Attempt to decode a message assuming that the given buffer contains
//! // *all* remaining input data.
//! fn decode_eof(&mut self, buf: &mut EasyBuf) -> io::Result<u64> {
//! let amt = buf.len();
//! Ok(parse_u64(buf.drain_to(amt).as_slice())?)
//! }
//!
//! fn encode(&mut self, item: u64, into: &mut Vec<u8>) -> io::Result<()> {
//! writeln!(into, "{}", item);
//! Ok(())
//! }
//! }
//!
//! // Next, we implement the server protocol, which just hooks up the codec above.
//!
//! pub struct IntProto;
//!
//! impl<T: Io + 'static> ServerProto<T> for IntProto {
//! type Request = u64;
//! type Response = u64;
//! type Transport = Framed<T, IntCodec>;
//! type BindTransport = Result<Self::Transport, io::Error>;
//!
//! fn bind_transport(&self, io: T) -> Self::BindTransport {
//! Ok(io.framed(IntCodec))
//! }
//! }
//!
//! // Now we implement a service we'd like to run on top of this protocol
//!
//! pub struct Doubler;
//!
//! impl Service for Doubler {
//! type Request = u64;
//! type Response = u64;
//! type Error = io::Error;
//! type Future = BoxFuture<u64, io::Error>;
//!
//! fn call(&self, req: u64) -> Self::Future {
//! // Just return the request, doubled
//! future::finished(req * 2).boxed()
//! }
//! }
//!
//! // Finally, we can actually host this service locally!
//! fn main() {
//! let addr = "0.0.0.0:12345".parse().unwrap();
//! TcpServer::new(IntProto, addr)
//! .serve(|| Ok(Doubler));
//! }
//! ```
// TODO remove this
extern crate net2;
extern crate rand;
extern crate slab;
extern crate smallvec;
extern crate take;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_service;
extern crate futures;
extern crate log;
pub use ;
pub use ;
pub use TcpServer;
use Handle;
use Service;
// TODO: move this into futures-rs
/// Binds a service to an I/O object.
///
/// This trait is not intended to be implemented directly; instead, implement
/// one of the server protocol traits:
///
/// - `pipeline::ServerProto`
/// - `multiplex::ServerProto`
/// - `streaming::pipeline::ServerProto`
/// - `streaming::multiplex::ServerProto`
///
/// See the crate documentation for more details on those traits.
///
/// The `Kind` parameter, in particular, is a zero-sized type used to allow
/// blanket implementation from the various protocol traits. Any additional
/// implementations of this trait should use their own zero-sized kind type to
/// distinguish them.