diff --git a/lib/rs/src/autogen.rs b/lib/rs/src/autogen.rs
new file mode 100644
index 0000000..289c7be
--- /dev/null
+++ b/lib/rs/src/autogen.rs
@@ -0,0 +1,45 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+//! Thrift compiler auto-generated support.
+//!
+//!
+//! Types and functions used internally by the Thrift compiler's Rust plugin
+//! to implement required functionality. Users should never have to use code
+//! in this module directly.
+
+use ::protocol::{TInputProtocol, TOutputProtocol};
+
+/// Specifies the minimum functionality an auto-generated client should provide
+/// to communicate with a Thrift server.
+pub trait TThriftClient {
+    /// Returns the input protocol used to read serialized Thrift messages
+    /// from the Thrift server.
+    fn i_prot_mut(&mut self) -> &mut TInputProtocol;
+    /// Returns the output protocol used to write serialized Thrift messages
+    /// to the Thrift server.
+    fn o_prot_mut(&mut self) -> &mut TOutputProtocol;
+    /// Returns the sequence number of the last message written to the Thrift
+    /// server. Returns `0` if no messages have been written. Sequence
+    /// numbers should *never* be negative, and this method returns an `i32`
+    /// simply because the Thrift protocol encodes sequence numbers as `i32` on
+    /// the wire.
+    fn sequence_number(&self) -> i32; // FIXME: consider returning a u32
+    /// Increments the sequence number, indicating that a message with that
+    /// number has been sent to the Thrift server.
+    fn increment_sequence_number(&mut self) -> i32;
+}
diff --git a/lib/rs/src/errors.rs b/lib/rs/src/errors.rs
new file mode 100644
index 0000000..a6049d5
--- /dev/null
+++ b/lib/rs/src/errors.rs
@@ -0,0 +1,678 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::convert::{From, Into};
+use std::error::Error as StdError;
+use std::fmt::{Debug, Display, Formatter};
+use std::{error, fmt, io, string};
+use try_from::TryFrom;
+
+use ::protocol::{TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType};
+
+// FIXME: should all my error structs impl error::Error as well?
+// FIXME: should all fields in TransportError, ProtocolError and ApplicationError be optional?
+
+/// Error type returned by all runtime library functions.
+///
+/// `thrift::Error` is used throughout this crate as well as in auto-generated
+/// Rust code. It consists of four variants defined by convention across Thrift
+/// implementations:
+///
+/// 1. `Transport`: errors encountered while operating on I/O channels
+/// 2. `Protocol`: errors encountered during runtime-library processing
+/// 3. `Application`: errors encountered within auto-generated code
+/// 4. `User`: IDL-defined exception structs
+///
+/// The `Application` variant also functions as a catch-all: all handler errors
+/// are automatically turned into application errors.
+///
+/// All error variants except `Error::User` take an eponymous struct with two
+/// required fields:
+///
+/// 1. `kind`: variant-specific enum identifying the error sub-type
+/// 2. `message`: human-readable error info string
+///
+/// `kind` is defined by convention while `message` is freeform. If none of the
+/// enumerated kinds are suitable use `Unknown`.
+///
+/// To simplify error creation convenience constructors are defined for all
+/// variants, and conversions from their structs (`thrift::TransportError`,
+/// `thrift::ProtocolError` and `thrift::ApplicationError` into `thrift::Error`.
+///
+/// # Examples
+///
+/// Create a `TransportError`.
+///
+/// ```
+/// use thrift;
+/// use thrift::{TransportError, TransportErrorKind};
+///
+/// // explicit
+/// let err0: thrift::Result<()> = Err(
+///   thrift::Error::Transport(
+///     TransportError {
+///       kind: TransportErrorKind::TimedOut,
+///       message: format!("connection to server timed out")
+///     }
+///   )
+/// );
+///
+/// // use conversion
+/// let err1: thrift::Result<()> = Err(
+///   thrift::Error::from(
+///     TransportError {
+///       kind: TransportErrorKind::TimedOut,
+///       message: format!("connection to server timed out")
+///     }
+///   )
+/// );
+///
+/// // use struct constructor
+/// let err2: thrift::Result<()> = Err(
+///   thrift::Error::Transport(
+///     TransportError::new(
+///       TransportErrorKind::TimedOut,
+///       "connection to server timed out"
+///     )
+///   )
+/// );
+///
+///
+/// // use error variant constructor
+/// let err3: thrift::Result<()> = Err(
+///   thrift::new_transport_error(
+///     TransportErrorKind::TimedOut,
+///     "connection to server timed out"
+///   )
+/// );
+/// ```
+///
+/// Create an error from a string.
+///
+/// ```
+/// use thrift;
+/// use thrift::{ApplicationError, ApplicationErrorKind};
+///
+/// // we just use `From::from` to convert a `String` into a `thrift::Error`
+/// let err0: thrift::Result<()> = Err(
+///   thrift::Error::from("This is an error")
+/// );
+///
+/// // err0 is equivalent to...
+/// let err1: thrift::Result<()> = Err(
+///   thrift::Error::Application(
+///     ApplicationError {
+///       kind: ApplicationErrorKind::Unknown,
+///       message: format!("This is an error")
+///     }
+///   )
+/// );
+/// ```
+///
+/// Return an IDL-defined exception.
+///
+/// ```text
+/// // Thrift IDL exception definition.
+/// exception Xception {
+///   1: i32 errorCode,
+///   2: string message
+/// }
+/// ```
+///
+/// ```
+/// use std::convert::From;
+/// use std::error::Error;
+/// use std::fmt;
+/// use std::fmt::{Display, Formatter};
+///
+/// // auto-generated by the Thrift compiler
+/// #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+/// pub struct Xception {
+///   pub error_code: Option<i32>,
+///   pub message: Option<String>,
+/// }
+///
+/// // auto-generated by the Thrift compiler
+/// impl Error for Xception {
+///   fn description(&self) -> &str {
+///     "remote service threw Xception"
+///   }
+/// }
+///
+/// // auto-generated by the Thrift compiler
+/// impl From<Xception> for thrift::Error {
+///   fn from(e: Xception) -> Self {
+///     thrift::Error::User(Box::new(e))
+///   }
+/// }
+///
+/// // auto-generated by the Thrift compiler
+/// impl Display for Xception {
+///   fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+///     self.description().fmt(f)
+///   }
+/// }
+///
+/// // in user code...
+/// let err: thrift::Result<()> = Err(
+///   thrift::Error::from(Xception { error_code: Some(1), message: None })
+/// );
+/// ```
+pub enum Error {
+    /// Errors encountered while operating on I/O channels.
+    ///
+    /// These include *connection closed* and *bind failure*.
+    Transport(TransportError),
+    /// Errors encountered during runtime-library processing.
+    ///
+    /// These include *message too large* and *unsupported protocol version*.
+    Protocol(ProtocolError),
+    /// Errors encountered within auto-generated code, or when incoming
+    /// or outgoing messages violate the Thrift spec.
+    ///
+    /// These include *out-of-order messages* and *missing required struct
+    /// fields*.
+    ///
+    /// This variant also functions as a catch-all: errors from handler
+    /// functions are automatically returned as an `ApplicationError`.
+    Application(ApplicationError),
+    /// IDL-defined exception structs.
+    User(Box<error::Error + Sync + Send>),
+}
+
+impl Error {
+    /// Create an `ApplicationError` from its wire representation.
+    ///
+    /// Application code **should never** call this method directly.
+    pub fn read_application_error_from_in_protocol(i: &mut TInputProtocol)
+                                                   -> ::Result<ApplicationError> {
+        let mut message = "general remote error".to_owned();
+        let mut kind = ApplicationErrorKind::Unknown;
+
+        i.read_struct_begin()?;
+
+        loop {
+            let field_ident = i.read_field_begin()?;
+
+            if field_ident.field_type == TType::Stop {
+                break;
+            }
+
+            let id = field_ident.id.expect("sender should always specify id for non-STOP field");
+
+            match id {
+                1 => {
+                    let remote_message = i.read_string()?;
+                    i.read_field_end()?;
+                    message = remote_message;
+                }
+                2 => {
+                    let remote_type_as_int = i.read_i32()?;
+                    let remote_kind: ApplicationErrorKind = TryFrom::try_from(remote_type_as_int)
+                        .unwrap_or(ApplicationErrorKind::Unknown);
+                    i.read_field_end()?;
+                    kind = remote_kind;
+                }
+                _ => {
+                    i.skip(field_ident.field_type)?;
+                }
+            }
+        }
+
+        i.read_struct_end()?;
+
+        Ok(ApplicationError {
+            kind: kind,
+            message: message,
+        })
+    }
+
+    /// Convert an `ApplicationError` into its wire representation and write
+    /// it to the remote.
+    ///
+    /// Application code **should never** call this method directly.
+    pub fn write_application_error_to_out_protocol(e: &ApplicationError,
+                                                   o: &mut TOutputProtocol)
+                                                   -> ::Result<()> {
+        o.write_struct_begin(&TStructIdentifier { name: "TApplicationException".to_owned() })?;
+
+        let message_field = TFieldIdentifier::new("message", TType::String, 1);
+        let type_field = TFieldIdentifier::new("type", TType::I32, 2);
+
+        o.write_field_begin(&message_field)?;
+        o.write_string(&e.message)?;
+        o.write_field_end()?;
+
+        o.write_field_begin(&type_field)?;
+        o.write_i32(e.kind as i32)?;
+        o.write_field_end()?;
+
+        o.write_field_stop()?;
+        o.write_struct_end()?;
+
+        o.flush()
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        match *self {
+            Error::Transport(ref e) => TransportError::description(e),
+            Error::Protocol(ref e) => ProtocolError::description(e),
+            Error::Application(ref e) => ApplicationError::description(e),
+            Error::User(ref e) => e.description(),
+        }
+    }
+}
+
+impl Debug for Error {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            Error::Transport(ref e) => Debug::fmt(e, f),
+            Error::Protocol(ref e) => Debug::fmt(e, f),
+            Error::Application(ref e) => Debug::fmt(e, f),
+            Error::User(ref e) => Debug::fmt(e, f),
+        }
+    }
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            Error::Transport(ref e) => Display::fmt(e, f),
+            Error::Protocol(ref e) => Display::fmt(e, f),
+            Error::Application(ref e) => Display::fmt(e, f),
+            Error::User(ref e) => Display::fmt(e, f),
+        }
+    }
+}
+
+impl From<String> for Error {
+    fn from(s: String) -> Self {
+        Error::Application(ApplicationError {
+            kind: ApplicationErrorKind::Unknown,
+            message: s,
+        })
+    }
+}
+
+impl<'a> From<&'a str> for Error {
+    fn from(s: &'a str) -> Self {
+        Error::Application(ApplicationError {
+            kind: ApplicationErrorKind::Unknown,
+            message: String::from(s),
+        })
+    }
+}
+
+impl From<TransportError> for Error {
+    fn from(e: TransportError) -> Self {
+        Error::Transport(e)
+    }
+}
+
+impl From<ProtocolError> for Error {
+    fn from(e: ProtocolError) -> Self {
+        Error::Protocol(e)
+    }
+}
+
+impl From<ApplicationError> for Error {
+    fn from(e: ApplicationError) -> Self {
+        Error::Application(e)
+    }
+}
+
+/// Create a new `Error` instance of type `Transport` that wraps a
+/// `TransportError`.
+pub fn new_transport_error<S: Into<String>>(kind: TransportErrorKind, message: S) -> Error {
+    Error::Transport(TransportError::new(kind, message))
+}
+
+/// Information about I/O errors.
+#[derive(Debug)]
+pub struct TransportError {
+    /// I/O error variant.
+    ///
+    /// If a specific `TransportErrorKind` does not apply use
+    /// `TransportErrorKind::Unknown`.
+    pub kind: TransportErrorKind,
+    /// Human-readable error message.
+    pub message: String,
+}
+
+impl TransportError {
+    /// Create a new `TransportError`.
+    pub fn new<S: Into<String>>(kind: TransportErrorKind, message: S) -> TransportError {
+        TransportError {
+            kind: kind,
+            message: message.into(),
+        }
+    }
+}
+
+/// I/O error categories.
+///
+/// This list may grow, and it is not recommended to match against it.
+#[derive(Clone, Copy, Eq, Debug, PartialEq)]
+pub enum TransportErrorKind {
+    /// Catch-all I/O error.
+    Unknown = 0,
+    /// An I/O operation was attempted when the transport channel was not open.
+    NotOpen = 1,
+    /// The transport channel cannot be opened because it was opened previously.
+    AlreadyOpen = 2,
+    /// An I/O operation timed out.
+    TimedOut = 3,
+    /// A read could not complete because no bytes were available.
+    EndOfFile = 4,
+    /// An invalid (buffer/message) size was requested or received.
+    NegativeSize = 5,
+    /// Too large a buffer or message size was requested or received.
+    SizeLimit = 6,
+}
+
+impl TransportError {
+    fn description(&self) -> &str {
+        match self.kind {
+            TransportErrorKind::Unknown => "transport error",
+            TransportErrorKind::NotOpen => "not open",
+            TransportErrorKind::AlreadyOpen => "already open",
+            TransportErrorKind::TimedOut => "timed out",
+            TransportErrorKind::EndOfFile => "end of file",
+            TransportErrorKind::NegativeSize => "negative size message",
+            TransportErrorKind::SizeLimit => "message too long",
+        }
+    }
+}
+
+impl Display for TransportError {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        write!(f, "{}", self.description())
+    }
+}
+
+impl TryFrom<i32> for TransportErrorKind {
+    type Err = Error;
+    fn try_from(from: i32) -> Result<Self, Self::Err> {
+        match from {
+            0 => Ok(TransportErrorKind::Unknown),
+            1 => Ok(TransportErrorKind::NotOpen),
+            2 => Ok(TransportErrorKind::AlreadyOpen),
+            3 => Ok(TransportErrorKind::TimedOut),
+            4 => Ok(TransportErrorKind::EndOfFile),
+            5 => Ok(TransportErrorKind::NegativeSize),
+            6 => Ok(TransportErrorKind::SizeLimit),
+            _ => {
+                Err(Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::Unknown,
+                    message: format!("cannot convert {} to TransportErrorKind", from),
+                }))
+            }
+        }
+    }
+}
+
+impl From<io::Error> for Error {
+    fn from(err: io::Error) -> Self {
+        match err.kind() {
+            io::ErrorKind::ConnectionReset |
+            io::ErrorKind::ConnectionRefused |
+            io::ErrorKind::NotConnected => {
+                Error::Transport(TransportError {
+                    kind: TransportErrorKind::NotOpen,
+                    message: err.description().to_owned(),
+                })
+            }
+            io::ErrorKind::AlreadyExists => {
+                Error::Transport(TransportError {
+                    kind: TransportErrorKind::AlreadyOpen,
+                    message: err.description().to_owned(),
+                })
+            }
+            io::ErrorKind::TimedOut => {
+                Error::Transport(TransportError {
+                    kind: TransportErrorKind::TimedOut,
+                    message: err.description().to_owned(),
+                })
+            }
+            io::ErrorKind::UnexpectedEof => {
+                Error::Transport(TransportError {
+                    kind: TransportErrorKind::EndOfFile,
+                    message: err.description().to_owned(),
+                })
+            }
+            _ => {
+                Error::Transport(TransportError {
+                    kind: TransportErrorKind::Unknown,
+                    message: err.description().to_owned(), // FIXME: use io error's debug string
+                })
+            }
+        }
+    }
+}
+
+impl From<string::FromUtf8Error> for Error {
+    fn from(err: string::FromUtf8Error) -> Self {
+        Error::Protocol(ProtocolError {
+            kind: ProtocolErrorKind::InvalidData,
+            message: err.description().to_owned(), // FIXME: use fmt::Error's debug string
+        })
+    }
+}
+
+/// Create a new `Error` instance of type `Protocol` that wraps a
+/// `ProtocolError`.
+pub fn new_protocol_error<S: Into<String>>(kind: ProtocolErrorKind, message: S) -> Error {
+    Error::Protocol(ProtocolError::new(kind, message))
+}
+
+/// Information about errors that occur in the runtime library.
+#[derive(Debug)]
+pub struct ProtocolError {
+    /// Protocol error variant.
+    ///
+    /// If a specific `ProtocolErrorKind` does not apply use
+    /// `ProtocolErrorKind::Unknown`.
+    pub kind: ProtocolErrorKind,
+    /// Human-readable error message.
+    pub message: String,
+}
+
+impl ProtocolError {
+    /// Create a new `ProtocolError`.
+    pub fn new<S: Into<String>>(kind: ProtocolErrorKind, message: S) -> ProtocolError {
+        ProtocolError {
+            kind: kind,
+            message: message.into(),
+        }
+    }
+}
+
+/// Runtime library error categories.
+///
+/// This list may grow, and it is not recommended to match against it.
+#[derive(Clone, Copy, Eq, Debug, PartialEq)]
+pub enum ProtocolErrorKind {
+    /// Catch-all runtime-library error.
+    Unknown = 0,
+    /// An invalid argument was supplied to a library function, or invalid data
+    /// was received from a Thrift endpoint.
+    InvalidData = 1,
+    /// An invalid size was received in an encoded field.
+    NegativeSize = 2,
+    /// Thrift message or field was too long.
+    SizeLimit = 3,
+    /// Unsupported or unknown Thrift protocol version.
+    BadVersion = 4,
+    /// Unsupported Thrift protocol, server or field type.
+    NotImplemented = 5,
+    /// Reached the maximum nested depth to which an encoded Thrift field could
+    /// be skipped.
+    DepthLimit = 6,
+}
+
+impl ProtocolError {
+    fn description(&self) -> &str {
+        match self.kind {
+            ProtocolErrorKind::Unknown => "protocol error",
+            ProtocolErrorKind::InvalidData => "bad data",
+            ProtocolErrorKind::NegativeSize => "negative message size",
+            ProtocolErrorKind::SizeLimit => "message too long",
+            ProtocolErrorKind::BadVersion => "invalid thrift version",
+            ProtocolErrorKind::NotImplemented => "not implemented",
+            ProtocolErrorKind::DepthLimit => "maximum skip depth reached",
+        }
+    }
+}
+
+impl Display for ProtocolError {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        write!(f, "{}", self.description())
+    }
+}
+
+impl TryFrom<i32> for ProtocolErrorKind {
+    type Err = Error;
+    fn try_from(from: i32) -> Result<Self, Self::Err> {
+        match from {
+            0 => Ok(ProtocolErrorKind::Unknown),
+            1 => Ok(ProtocolErrorKind::InvalidData),
+            2 => Ok(ProtocolErrorKind::NegativeSize),
+            3 => Ok(ProtocolErrorKind::SizeLimit),
+            4 => Ok(ProtocolErrorKind::BadVersion),
+            5 => Ok(ProtocolErrorKind::NotImplemented),
+            6 => Ok(ProtocolErrorKind::DepthLimit),
+            _ => {
+                Err(Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::Unknown,
+                    message: format!("cannot convert {} to ProtocolErrorKind", from),
+                }))
+            }
+        }
+    }
+}
+
+/// Create a new `Error` instance of type `Application` that wraps an
+/// `ApplicationError`.
+pub fn new_application_error<S: Into<String>>(kind: ApplicationErrorKind, message: S) -> Error {
+    Error::Application(ApplicationError::new(kind, message))
+}
+
+/// Information about errors in auto-generated code or in user-implemented
+/// service handlers.
+#[derive(Debug)]
+pub struct ApplicationError {
+    /// Application error variant.
+    ///
+    /// If a specific `ApplicationErrorKind` does not apply use
+    /// `ApplicationErrorKind::Unknown`.
+    pub kind: ApplicationErrorKind,
+    /// Human-readable error message.
+    pub message: String,
+}
+
+impl ApplicationError {
+    /// Create a new `ApplicationError`.
+    pub fn new<S: Into<String>>(kind: ApplicationErrorKind, message: S) -> ApplicationError {
+        ApplicationError {
+            kind: kind,
+            message: message.into(),
+        }
+    }
+}
+
+/// Auto-generated or user-implemented code error categories.
+///
+/// This list may grow, and it is not recommended to match against it.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum ApplicationErrorKind {
+    /// Catch-all application error.
+    Unknown = 0,
+    /// Made service call to an unknown service method.
+    UnknownMethod = 1,
+    /// Received an unknown Thrift message type. That is, not one of the
+    /// `thrift::protocol::TMessageType` variants.
+    InvalidMessageType = 2,
+    /// Method name in a service reply does not match the name of the
+    /// receiving service method.
+    WrongMethodName = 3,
+    /// Received an out-of-order Thrift message.
+    BadSequenceId = 4,
+    /// Service reply is missing required fields.
+    MissingResult = 5,
+    /// Auto-generated code failed unexpectedly.
+    InternalError = 6,
+    /// Thrift protocol error. When possible use `Error::ProtocolError` with a
+    /// specific `ProtocolErrorKind` instead.
+    ProtocolError = 7,
+    /// *Unknown*. Included only for compatibility with existing Thrift implementations.
+    InvalidTransform = 8, // ??
+    /// Thrift endpoint requested, or is using, an unsupported encoding.
+    InvalidProtocol = 9, // ??
+    /// Thrift endpoint requested, or is using, an unsupported auto-generated client type.
+    UnsupportedClientType = 10, // ??
+}
+
+impl ApplicationError {
+    fn description(&self) -> &str {
+        match self.kind {
+            ApplicationErrorKind::Unknown => "service error",
+            ApplicationErrorKind::UnknownMethod => "unknown service method",
+            ApplicationErrorKind::InvalidMessageType => "wrong message type received",
+            ApplicationErrorKind::WrongMethodName => "unknown method reply received",
+            ApplicationErrorKind::BadSequenceId => "out of order sequence id",
+            ApplicationErrorKind::MissingResult => "missing method result",
+            ApplicationErrorKind::InternalError => "remote service threw exception",
+            ApplicationErrorKind::ProtocolError => "protocol error",
+            ApplicationErrorKind::InvalidTransform => "invalid transform",
+            ApplicationErrorKind::InvalidProtocol => "invalid protocol requested",
+            ApplicationErrorKind::UnsupportedClientType => "unsupported protocol client",
+        }
+    }
+}
+
+impl Display for ApplicationError {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        write!(f, "{}", self.description())
+    }
+}
+
+impl TryFrom<i32> for ApplicationErrorKind {
+    type Err = Error;
+    fn try_from(from: i32) -> Result<Self, Self::Err> {
+        match from {
+            0 => Ok(ApplicationErrorKind::Unknown),
+            1 => Ok(ApplicationErrorKind::UnknownMethod),
+            2 => Ok(ApplicationErrorKind::InvalidMessageType),
+            3 => Ok(ApplicationErrorKind::WrongMethodName),
+            4 => Ok(ApplicationErrorKind::BadSequenceId),
+            5 => Ok(ApplicationErrorKind::MissingResult),
+            6 => Ok(ApplicationErrorKind::InternalError),
+            7 => Ok(ApplicationErrorKind::ProtocolError),
+            8 => Ok(ApplicationErrorKind::InvalidTransform),
+            9 => Ok(ApplicationErrorKind::InvalidProtocol),
+            10 => Ok(ApplicationErrorKind::UnsupportedClientType),
+            _ => {
+                Err(Error::Application(ApplicationError {
+                    kind: ApplicationErrorKind::Unknown,
+                    message: format!("cannot convert {} to ApplicationErrorKind", from),
+                }))
+            }
+        }
+    }
+}
diff --git a/lib/rs/src/lib.rs b/lib/rs/src/lib.rs
new file mode 100644
index 0000000..ad18721
--- /dev/null
+++ b/lib/rs/src/lib.rs
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+//! Rust runtime library for the Apache Thrift RPC system.
+//!
+//! This crate implements the components required to build a working
+//! Thrift server and client. It is divided into the following modules:
+//!
+//! 1. errors
+//! 2. protocol
+//! 3. transport
+//! 4. server
+//! 5. autogen
+//!
+//! The modules are layered as shown in the diagram below. The `generated`
+//! layer is generated by the Thrift compiler's Rust plugin. It uses the
+//! types and functions defined in this crate to serialize and deserialize
+//! messages and implement RPC. Users interact with these types and services
+//! by writing their own code on top.
+//!
+//! ```text
+//! +-----------+
+//! | user app  |
+//! +-----------+
+//! | autogen'd | (uses errors, autogen)
+//! +-----------+
+//! |  protocol |
+//! +-----------+
+//! | transport |
+//! +-----------+
+//! ```
+
+#![crate_type = "lib"]
+#![doc(test(attr(allow(unused_variables), deny(warnings))))]
+
+extern crate byteorder;
+extern crate integer_encoding;
+extern crate try_from;
+
+#[macro_use]
+extern crate log;
+
+// NOTE: this macro has to be defined before any modules. See:
+// https://danielkeep.github.io/quick-intro-to-macros.html#some-more-gotchas
+
+/// Assert that an expression returning a `Result` is a success. If it is,
+/// return the value contained in the result, i.e. `expr.unwrap()`.
+#[cfg(test)]
+macro_rules! assert_success {
+    ($e: expr) => {
+        {
+            let res = $e;
+            assert!(res.is_ok());
+            res.unwrap()
+        }
+    }
+}
+
+pub mod protocol;
+pub mod server;
+pub mod transport;
+
+mod errors;
+pub use errors::*;
+
+mod autogen;
+pub use autogen::*;
+
+/// Result type returned by all runtime library functions.
+///
+/// As is convention this is a typedef of `std::result::Result`
+/// with `E` defined as the `thrift::Error` type.
+pub type Result<T> = std::result::Result<T, self::Error>;
diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
new file mode 100644
index 0000000..f3c9ea2
--- /dev/null
+++ b/lib/rs/src/protocol/binary.rs
@@ -0,0 +1,817 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
+use std::cell::RefCell;
+use std::convert::From;
+use std::io::{Read, Write};
+use std::rc::Rc;
+use try_from::TryFrom;
+
+use ::{ProtocolError, ProtocolErrorKind};
+use ::transport::TTransport;
+use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
+            TMapIdentifier, TMessageIdentifier, TMessageType};
+use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
+
+const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
+
+/// Read messages encoded in the Thrift simple binary encoding.
+///
+/// There are two available modes: `strict` and `non-strict`, where the
+/// `non-strict` version does not check for the protocol version in the
+/// received message header.
+///
+/// # Examples
+///
+/// Create and use a `TBinaryInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TBinaryInputProtocol::new(transport, true);
+///
+/// let recvd_bool = i_prot.read_bool().unwrap();
+/// let recvd_string = i_prot.read_string().unwrap();
+/// ```
+pub struct TBinaryInputProtocol {
+    strict: bool,
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TBinaryInputProtocol {
+    /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
+    ///
+    /// Set `strict` to `true` if all incoming messages contain the protocol
+    /// version number in the protocol header.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>, strict: bool) -> TBinaryInputProtocol {
+        TBinaryInputProtocol {
+            strict: strict,
+            transport: transport,
+        }
+    }
+}
+
+impl TInputProtocol for TBinaryInputProtocol {
+    #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        let mut first_bytes = vec![0; 4];
+        self.transport.borrow_mut().read_exact(&mut first_bytes[..])?;
+
+        // the thrift version header is intentionally negative
+        // so the first check we'll do is see if the sign bit is set
+        // and if so - assume it's the protocol-version header
+        if first_bytes[0] >= 8 {
+            // apparently we got a protocol-version header - check
+            // it, and if it matches, read the rest of the fields
+            if first_bytes[0..2] != [0x80, 0x01] {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::BadVersion,
+                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
+                }))
+            } else {
+                let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
+                let name = self.read_string()?;
+                let sequence_number = self.read_i32()?;
+                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
+            }
+        } else {
+            // apparently we didn't get a protocol-version header,
+            // which happens if the sender is not using the strict protocol
+            if self.strict {
+                // we're in strict mode however, and that always
+                // requires the protocol-version header to be written first
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::BadVersion,
+                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
+                }))
+            } else {
+                // in the non-strict version the first message field
+                // is the message name. strings (byte arrays) are length-prefixed,
+                // so we've just read the length in the first 4 bytes
+                let name_size = BigEndian::read_i32(&first_bytes) as usize;
+                let mut name_buf: Vec<u8> = Vec::with_capacity(name_size);
+                self.transport.borrow_mut().read_exact(&mut name_buf)?;
+                let name = String::from_utf8(name_buf)?;
+
+                // read the rest of the fields
+                let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
+                let sequence_number = self.read_i32()?;
+                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
+            }
+        }
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        Ok(None)
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        let field_type_byte = self.read_byte()?;
+        let field_type = field_type_from_u8(field_type_byte)?;
+        let id = match field_type {
+            TType::Stop => Ok(0),
+            _ => self.read_i16(),
+        }?;
+        Ok(TFieldIdentifier::new::<Option<String>, String, i16>(None, field_type, id))
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        let num_bytes = self.transport.borrow_mut().read_i32::<BigEndian>()? as usize;
+        let mut buf = vec![0u8; num_bytes];
+        self.transport.borrow_mut().read_exact(&mut buf).map(|_| buf).map_err(From::from)
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        let b = self.read_i8()?;
+        match b {
+            0 => Ok(false),
+            _ => Ok(true),
+        }
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.transport.borrow_mut().read_i8().map_err(From::from)
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.transport.borrow_mut().read_i16::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.transport.borrow_mut().read_i32::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.transport.borrow_mut().read_i64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.transport.borrow_mut().read_f64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        let bytes = self.read_bytes()?;
+        String::from_utf8(bytes).map_err(From::from)
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TListIdentifier::new(element_type, size))
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TSetIdentifier::new(element_type, size))
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TMapIdentifier::new(key_type, value_type, size))
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        self.transport.borrow_mut().read_u8().map_err(From::from)
+    }
+}
+
+/// Factory for creating instances of `TBinaryInputProtocol`.
+#[derive(Default)]
+pub struct TBinaryInputProtocolFactory;
+
+impl TBinaryInputProtocolFactory {
+    /// Create a `TBinaryInputProtocolFactory`.
+    pub fn new() -> TBinaryInputProtocolFactory {
+        TBinaryInputProtocolFactory {}
+    }
+}
+
+impl TInputProtocolFactory for TBinaryInputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol> {
+        Box::new(TBinaryInputProtocol::new(transport, true)) as Box<TInputProtocol>
+    }
+}
+
+/// Write messages using the Thrift simple binary encoding.
+///
+/// There are two available modes: `strict` and `non-strict`, where the
+/// `strict` version writes the protocol version number in the outgoing message
+/// header and the `non-strict` version does not.
+///
+/// # Examples
+///
+/// Create and use a `TBinaryOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TBinaryOutputProtocol::new(transport, true);
+///
+/// o_prot.write_bool(true).unwrap();
+/// o_prot.write_string("test_string").unwrap();
+/// ```
+pub struct TBinaryOutputProtocol {
+    strict: bool,
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TBinaryOutputProtocol {
+    /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
+    ///
+    /// Set `strict` to `true` if all outgoing messages should contain the
+    /// protocol version number in the protocol header.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>, strict: bool) -> TBinaryOutputProtocol {
+        TBinaryOutputProtocol {
+            strict: strict,
+            transport: transport,
+        }
+    }
+
+    fn write_transport(&mut self, buf: &[u8]) -> ::Result<()> {
+        self.transport.borrow_mut().write(buf).map(|_| ()).map_err(From::from)
+    }
+}
+
+impl TOutputProtocol for TBinaryOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        if self.strict {
+            let message_type: u8 = identifier.message_type.into();
+            let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
+            self.transport.borrow_mut().write_u32::<BigEndian>(header)?;
+            self.write_string(&identifier.name)?;
+            self.write_i32(identifier.sequence_number)
+        } else {
+            self.write_string(&identifier.name)?;
+            self.write_byte(identifier.message_type.into())?;
+            self.write_i32(identifier.sequence_number)
+        }
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        if identifier.id.is_none() && identifier.field_type != TType::Stop {
+            return Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::Unknown,
+                message: format!("cannot write identifier {:?} without sequence number",
+                                 &identifier),
+            }));
+        }
+
+        self.write_byte(field_type_to_u8(identifier.field_type))?;
+        if let Some(id) = identifier.id {
+            self.write_i16(id)
+        } else {
+            Ok(())
+        }
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(TType::Stop))
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.write_i32(b.len() as i32)?;
+        self.write_transport(b)
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        if b {
+            self.write_i8(1)
+        } else {
+            self.write_i8(0)
+        }
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.transport.borrow_mut().write_i8(i).map_err(From::from)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.transport.borrow_mut().write_i16::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.transport.borrow_mut().write_i32::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.transport.borrow_mut().write_i64::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.transport.borrow_mut().write_f64::<BigEndian>(d).map_err(From::from)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.write_bytes(s.as_bytes())
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(identifier.element_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(identifier.element_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        let key_type = identifier.key_type
+            .expect("map identifier to write should contain key type");
+        self.write_byte(field_type_to_u8(key_type))?;
+        let val_type = identifier.value_type
+            .expect("map identifier to write should contain value type");
+        self.write_byte(field_type_to_u8(val_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.transport.borrow_mut().flush().map_err(From::from)
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.transport.borrow_mut().write_u8(b).map_err(From::from)
+    }
+}
+
+/// Factory for creating instances of `TBinaryOutputProtocol`.
+#[derive(Default)]
+pub struct TBinaryOutputProtocolFactory;
+
+impl TBinaryOutputProtocolFactory {
+    /// Create a `TBinaryOutputProtocolFactory`.
+    pub fn new() -> TBinaryOutputProtocolFactory {
+        TBinaryOutputProtocolFactory {}
+    }
+}
+
+impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol> {
+        Box::new(TBinaryOutputProtocol::new(transport, true)) as Box<TOutputProtocol>
+    }
+}
+
+fn field_type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Stop => 0x00,
+        TType::Void => 0x01,
+        TType::Bool => 0x02,
+        TType::I08 => 0x03, // equivalent to TType::Byte
+        TType::Double => 0x04,
+        TType::I16 => 0x06,
+        TType::I32 => 0x08,
+        TType::I64 => 0x0A,
+        TType::String | TType::Utf7 => 0x0B,
+        TType::Struct => 0x0C,
+        TType::Map => 0x0D,
+        TType::Set => 0x0E,
+        TType::List => 0x0F,
+        TType::Utf8 => 0x10,
+        TType::Utf16 => 0x11,
+    }
+}
+
+fn field_type_from_u8(b: u8) -> ::Result<TType> {
+    match b {
+        0x00 => Ok(TType::Stop),
+        0x01 => Ok(TType::Void),
+        0x02 => Ok(TType::Bool),
+        0x03 => Ok(TType::I08), // Equivalent to TType::Byte
+        0x04 => Ok(TType::Double),
+        0x06 => Ok(TType::I16),
+        0x08 => Ok(TType::I32),
+        0x0A => Ok(TType::I64),
+        0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
+        0x0C => Ok(TType::Struct),
+        0x0D => Ok(TType::Map),
+        0x0E => Ok(TType::Set),
+        0x0F => Ok(TType::List),
+        0x10 => Ok(TType::Utf8),
+        0x11 => Ok(TType::Utf16),
+        unkn => {
+            Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::InvalidData,
+                message: format!("cannot convert {} to TType", unkn),
+            }))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::rc::Rc;
+    use std::cell::RefCell;
+
+    use ::protocol::{TFieldIdentifier, TMessageIdentifier, TMessageType, TInputProtocol,
+                     TListIdentifier, TMapIdentifier, TOutputProtocol, TSetIdentifier,
+                     TStructIdentifier, TType};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_call_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
+        assert!(o_prot.write_message_begin(&ident).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+
+        let expected: [u8; 16] = [0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65,
+                                  0x73, 0x74, 0x00, 0x00, 0x00, 0x01];
+
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+
+    #[test]
+    fn must_write_message_reply_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
+        assert!(o_prot.write_message_begin(&ident).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+
+        let expected: [u8; 16] = [0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65,
+                                  0x73, 0x74, 0x00, 0x00, 0x00, 0x0A];
+
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_strict_message_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
+        assert!(o_prot.write_message_begin(&sent_ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_message_begin());
+        assert_eq!(&received_ident, &sent_ident);
+    }
+
+    #[test]
+    fn must_write_message_end() {
+        assert_no_write(|o| o.write_message_end());
+    }
+
+    #[test]
+    fn must_write_struct_begin() {
+        assert_no_write(|o| o.write_struct_begin(&TStructIdentifier::new("foo")));
+    }
+
+    #[test]
+    fn must_write_struct_end() {
+        assert_no_write(|o| o.write_struct_end());
+    }
+
+    #[test]
+    fn must_write_field_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
+            .is_ok());
+
+        let expected: [u8; 3] = [0x0B, 0x00, 0x16];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_field_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
+        assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let expected_ident = TFieldIdentifier {
+            name: None,
+            field_type: TType::I64,
+            id: Some(20),
+        }; // no name
+        let received_ident = assert_success!(i_prot.read_field_begin());
+        assert_eq!(&received_ident, &expected_ident);
+    }
+
+    #[test]
+    fn must_write_stop_field() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_stop().is_ok());
+
+        let expected: [u8; 1] = [0x00];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_field_stop() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_stop().is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let expected_ident = TFieldIdentifier {
+            name: None,
+            field_type: TType::Stop,
+            id: Some(0),
+        }; // we get id 0
+
+        let received_ident = assert_success!(i_prot.read_field_begin());
+        assert_eq!(&received_ident, &expected_ident);
+    }
+
+    #[test]
+    fn must_write_field_end() {
+        assert_no_write(|o| o.write_field_end());
+    }
+
+    #[test]
+    fn must_write_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_list_begin(&TListIdentifier::new(TType::Bool, 5)).is_ok());
+
+        let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::List, 900);
+        assert!(o_prot.write_list_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&received_ident, &ident);
+    }
+
+    #[test]
+    fn must_write_list_end() {
+        assert_no_write(|o| o.write_list_end());
+    }
+
+    #[test]
+    fn must_write_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_set_begin(&TSetIdentifier::new(TType::I16, 7)).is_ok());
+
+        let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::I64, 2000);
+        assert!(o_prot.write_set_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident_result = i_prot.read_set_begin();
+        assert!(received_ident_result.is_ok());
+        assert_eq!(&received_ident_result.unwrap(), &ident);
+    }
+
+    #[test]
+    fn must_write_set_end() {
+        assert_no_write(|o| o.write_set_end());
+    }
+
+    #[test]
+    fn must_write_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
+            .is_ok());
+
+        let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
+        assert!(o_prot.write_map_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&received_ident, &ident);
+    }
+
+    #[test]
+    fn must_write_map_end() {
+        assert_no_write(|o| o.write_map_end());
+    }
+
+    #[test]
+    fn must_write_bool_true() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_bool(true).is_ok());
+
+        let expected: [u8; 1] = [0x01];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_write_bool_false() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_bool(false).is_ok());
+
+        let expected: [u8; 1] = [0x00];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_read_bool_true() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0x01]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, true);
+    }
+
+    #[test]
+    fn must_read_bool_false() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0x00]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, false);
+    }
+
+    #[test]
+    fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0xAC]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, true);
+    }
+
+    #[test]
+    fn must_write_bytes() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
+
+        assert!(o_prot.write_bytes(&bytes).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
+        assert_eq!(&buf[4..], bytes); // actual bytes
+    }
+
+    #[test]
+    fn must_round_trip_bytes() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let bytes: [u8; 25] = [0x20, 0xFD, 0x18, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF, 0x34,
+                               0xDC, 0x98, 0xA4, 0x6D, 0xF3, 0x99, 0xB4, 0xB7, 0xD4, 0x9C, 0xA5,
+                               0xB3, 0xC9, 0x88];
+
+        assert!(o_prot.write_bytes(&bytes).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_bytes = assert_success!(i_prot.read_bytes());
+        assert_eq!(&received_bytes, &bytes);
+    }
+
+    fn test_objects
+        ()
+        -> (Rc<RefCell<Box<TBufferTransport>>>, TBinaryInputProtocol, TBinaryOutputProtocol)
+    {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(40, 40))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let i_prot = TBinaryInputProtocol::new(inner.clone(), true);
+        let o_prot = TBinaryOutputProtocol::new(inner.clone(), true);
+
+        (mem, i_prot, o_prot)
+    }
+
+    fn assert_no_write<F: FnMut(&mut TBinaryOutputProtocol) -> ::Result<()>>(mut write_fn: F) {
+        let (trans, _, mut o_prot) = test_objects();
+        assert!(write_fn(&mut o_prot).is_ok());
+        assert_eq!(trans.borrow().write_buffer_as_ref().len(), 0);
+    }
+}
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
new file mode 100644
index 0000000..96fa8ef
--- /dev/null
+++ b/lib/rs/src/protocol/compact.rs
@@ -0,0 +1,2085 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
+use integer_encoding::{VarIntReader, VarIntWriter};
+use std::cell::RefCell;
+use std::convert::From;
+use std::rc::Rc;
+use std::io::{Read, Write};
+use try_from::TryFrom;
+
+use ::transport::TTransport;
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
+            TInputProtocol, TInputProtocolFactory};
+use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
+
+const COMPACT_PROTOCOL_ID: u8 = 0x82;
+const COMPACT_VERSION: u8 = 0x01;
+const COMPACT_VERSION_MASK: u8 = 0x1F;
+
+/// Read messages encoded in the Thrift compact protocol.
+///
+/// # Examples
+///
+/// Create and use a `TCompactInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TCompactInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TCompactInputProtocol::new(transport);
+///
+/// let recvd_bool = i_prot.read_bool().unwrap();
+/// let recvd_string = i_prot.read_string().unwrap();
+/// ```
+pub struct TCompactInputProtocol {
+    // Identifier of the last field deserialized for a struct.
+    last_read_field_id: i16,
+    // Stack of the last read field ids (a new entry is added each time a nested struct is read).
+    read_field_id_stack: Vec<i16>,
+    // Boolean value for a field.
+    // Saved because boolean fields and their value are encoded in a single byte,
+    // and reading the field only occurs after the field id is read.
+    pending_read_bool_value: Option<bool>,
+    // Underlying transport used for byte-level operations.
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TCompactInputProtocol {
+    /// Create a `TCompactInputProtocol` that reads bytes from `transport`.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>) -> TCompactInputProtocol {
+        TCompactInputProtocol {
+            last_read_field_id: 0,
+            read_field_id_stack: Vec::new(),
+            pending_read_bool_value: None,
+            transport: transport,
+        }
+    }
+
+    fn read_list_set_begin(&mut self) -> ::Result<(TType, i32)> {
+        let header = self.read_byte()?;
+        let element_type = collection_u8_to_type(header & 0x0F)?;
+
+        let element_count;
+        let possible_element_count = (header & 0xF0) >> 4;
+        if possible_element_count != 15 {
+            // high bits set high if count and type encoded separately
+            element_count = possible_element_count as i32;
+        } else {
+            element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
+        }
+
+        Ok((element_type, element_count))
+    }
+}
+
+impl TInputProtocol for TCompactInputProtocol {
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        let compact_id = self.read_byte()?;
+        if compact_id != COMPACT_PROTOCOL_ID {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::BadVersion,
+                message: format!("invalid compact protocol header {:?}", compact_id),
+            }))
+        } else {
+            Ok(())
+        }?;
+
+        let type_and_byte = self.read_byte()?;
+        let received_version = type_and_byte & COMPACT_VERSION_MASK;
+        if received_version != COMPACT_VERSION {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::BadVersion,
+                message: format!("cannot process compact protocol version {:?}",
+                                 received_version),
+            }))
+        } else {
+            Ok(())
+        }?;
+
+        // NOTE: unsigned right shift will pad with 0s
+        let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
+        let sequence_number = self.read_i32()?;
+        let service_call_name = self.read_string()?;
+
+        self.last_read_field_id = 0;
+
+        Ok(TMessageIdentifier::new(service_call_name, message_type, sequence_number))
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        self.read_field_id_stack.push(self.last_read_field_id);
+        self.last_read_field_id = 0;
+        Ok(None)
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        self.last_read_field_id = self.read_field_id_stack
+            .pop()
+            .expect("should have previous field ids");
+        Ok(())
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        // we can read at least one byte, which is:
+        // - the type
+        // - the field delta and the type
+        let field_type = self.read_byte()?;
+        let field_delta = (field_type & 0xF0) >> 4;
+        let field_type = match field_type & 0x0F {
+            0x01 => {
+                self.pending_read_bool_value = Some(true);
+                Ok(TType::Bool)
+            }
+            0x02 => {
+                self.pending_read_bool_value = Some(false);
+                Ok(TType::Bool)
+            }
+            ttu8 => u8_to_type(ttu8),
+        }?;
+
+        match field_type {
+            TType::Stop => {
+                Ok(TFieldIdentifier::new::<Option<String>, String, Option<i16>>(None,
+                                                                                TType::Stop,
+                                                                                None))
+            }
+            _ => {
+                if field_delta != 0 {
+                    self.last_read_field_id += field_delta as i16;
+                } else {
+                    self.last_read_field_id = self.read_i16()?;
+                };
+
+                Ok(TFieldIdentifier {
+                    name: None,
+                    field_type: field_type,
+                    id: Some(self.last_read_field_id),
+                })
+            }
+        }
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        match self.pending_read_bool_value.take() {
+            Some(b) => Ok(b),
+            None => {
+                let b = self.read_byte()?;
+                match b {
+                    0x01 => Ok(true),
+                    0x02 => Ok(false),
+                    unkn => {
+                        Err(::Error::Protocol(::ProtocolError {
+                            kind: ::ProtocolErrorKind::InvalidData,
+                            message: format!("cannot convert {} into bool", unkn),
+                        }))
+                    }
+                }
+            }
+        }
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        let len = self.transport.borrow_mut().read_varint::<u32>()?;
+        let mut buf = vec![0u8; len as usize];
+        self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf)
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.read_byte().map(|i| i as i8)
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.transport.borrow_mut().read_varint::<i16>().map_err(From::from)
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.transport.borrow_mut().read_varint::<i32>().map_err(From::from)
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.transport.borrow_mut().read_varint::<i64>().map_err(From::from)
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.transport.borrow_mut().read_f64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        let bytes = self.read_bytes()?;
+        String::from_utf8(bytes).map_err(From::from)
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        let (element_type, element_count) = self.read_list_set_begin()?;
+        Ok(TListIdentifier::new(element_type, element_count))
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        let (element_type, element_count) = self.read_list_set_begin()?;
+        Ok(TSetIdentifier::new(element_type, element_count))
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        let element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
+        if element_count == 0 {
+            Ok(TMapIdentifier::new(None, None, 0))
+        } else {
+            let type_header = self.read_byte()?;
+            let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?;
+            let val_type = collection_u8_to_type(type_header & 0x0F)?;
+            Ok(TMapIdentifier::new(key_type, val_type, element_count))
+        }
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        let mut buf = [0u8; 1];
+        self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf[0])
+    }
+}
+
+/// Factory for creating instances of `TCompactInputProtocol`.
+#[derive(Default)]
+pub struct TCompactInputProtocolFactory;
+
+impl TCompactInputProtocolFactory {
+    /// Create a `TCompactInputProtocolFactory`.
+    pub fn new() -> TCompactInputProtocolFactory {
+        TCompactInputProtocolFactory {}
+    }
+}
+
+impl TInputProtocolFactory for TCompactInputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol> {
+        Box::new(TCompactInputProtocol::new(transport)) as Box<TInputProtocol>
+    }
+}
+
+/// Write messages using the Thrift compact protocol.
+///
+/// # Examples
+///
+/// Create and use a `TCompactOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TCompactOutputProtocol::new(transport);
+///
+/// o_prot.write_bool(true).unwrap();
+/// o_prot.write_string("test_string").unwrap();
+/// ```
+pub struct TCompactOutputProtocol {
+    // Identifier of the last field serialized for a struct.
+    last_write_field_id: i16,
+    // Stack of the last written field ids (a new entry is added each time a nested struct is written).
+    write_field_id_stack: Vec<i16>,
+    // Field identifier of the boolean field to be written.
+    // Saved because boolean fields and their value are encoded in a single byte
+    pending_write_bool_field_identifier: Option<TFieldIdentifier>,
+    // Underlying transport used for byte-level operations.
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TCompactOutputProtocol {
+    /// Create a `TCompactOutputProtocol` that writes bytes to `transport`.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>) -> TCompactOutputProtocol {
+        TCompactOutputProtocol {
+            last_write_field_id: 0,
+            write_field_id_stack: Vec::new(),
+            pending_write_bool_field_identifier: None,
+            transport: transport,
+        }
+    }
+
+    // FIXME: field_type as unconstrained u8 is bad
+    fn write_field_header(&mut self, field_type: u8, field_id: i16) -> ::Result<()> {
+        let field_delta = field_id - self.last_write_field_id;
+        if field_delta > 0 && field_delta < 15 {
+            self.write_byte(((field_delta as u8) << 4) | field_type)?;
+        } else {
+            self.write_byte(field_type)?;
+            self.write_i16(field_id)?;
+        }
+        self.last_write_field_id = field_id;
+        Ok(())
+    }
+
+    fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> ::Result<()> {
+        let elem_identifier = collection_type_to_u8(element_type);
+        if element_count <= 14 {
+            let header = (element_count as u8) << 4 | elem_identifier;
+            self.write_byte(header)
+        } else {
+            let header = 0xF0 | elem_identifier;
+            self.write_byte(header)?;
+            self.transport
+                .borrow_mut()
+                .write_varint(element_count as u32)
+                .map_err(From::from)
+                .map(|_| ())
+        }
+    }
+
+    fn assert_no_pending_bool_write(&self) {
+        if let Some(ref f) = self.pending_write_bool_field_identifier {
+            panic!("pending bool field {:?} not written", f)
+        }
+    }
+}
+
+impl TOutputProtocol for TCompactOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        self.write_byte(COMPACT_PROTOCOL_ID)?;
+        self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
+        self.write_i32(identifier.sequence_number)?;
+        self.write_string(&identifier.name)?;
+        Ok(())
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        Ok(())
+    }
+
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+        self.write_field_id_stack.push(self.last_write_field_id);
+        self.last_write_field_id = 0;
+        Ok(())
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        self.last_write_field_id =
+            self.write_field_id_stack.pop().expect("should have previous field ids");
+        Ok(())
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        match identifier.field_type {
+            TType::Bool => {
+                if self.pending_write_bool_field_identifier.is_some() {
+                    panic!("should not have a pending bool while writing another bool with id: \
+                            {:?}",
+                           identifier)
+                }
+                self.pending_write_bool_field_identifier = Some(identifier.clone());
+                Ok(())
+            }
+            _ => {
+                let field_type = type_to_u8(identifier.field_type);
+                let field_id = identifier.id.expect("non-stop field should have field id");
+                self.write_field_header(field_type, field_id)
+            }
+        }
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        Ok(())
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        self.write_byte(type_to_u8(TType::Stop))
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        match self.pending_write_bool_field_identifier.take() {
+            Some(pending) => {
+                let field_id = pending.id.expect("bool field should have a field id");
+                let field_type_as_u8 = if b { 0x01 } else { 0x02 };
+                self.write_field_header(field_type_as_u8, field_id)
+            }
+            None => {
+                if b {
+                    self.write_byte(0x01)
+                } else {
+                    self.write_byte(0x02)
+                }
+            }
+        }
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(b.len() as u32)?;
+        self.transport.borrow_mut().write_all(b).map_err(From::from)
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.write_byte(i as u8)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.transport.borrow_mut().write_f64::<BigEndian>(d).map_err(From::from)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.write_bytes(s.as_bytes())
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.write_list_set_begin(identifier.element_type, identifier.size)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.write_list_set_begin(identifier.element_type, identifier.size)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        if identifier.size == 0 {
+            self.write_byte(0)
+        } else {
+            self.transport.borrow_mut().write_varint(identifier.size as u32)?;
+
+            let key_type = identifier.key_type
+                .expect("map identifier to write should contain key type");
+            let key_type_byte = collection_type_to_u8(key_type) << 4;
+
+            let val_type = identifier.value_type
+                .expect("map identifier to write should contain value type");
+            let val_type_byte = collection_type_to_u8(val_type);
+
+            let map_type_header = key_type_byte | val_type_byte;
+            self.write_byte(map_type_header)
+        }
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.transport.borrow_mut().flush().map_err(From::from)
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.transport.borrow_mut().write(&[b]).map_err(From::from).map(|_| ())
+    }
+}
+
+/// Factory for creating instances of `TCompactOutputProtocol`.
+#[derive(Default)]
+pub struct TCompactOutputProtocolFactory;
+
+impl TCompactOutputProtocolFactory {
+    /// Create a `TCompactOutputProtocolFactory`.
+    pub fn new() -> TCompactOutputProtocolFactory {
+        TCompactOutputProtocolFactory {}
+    }
+}
+
+impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol> {
+        Box::new(TCompactOutputProtocol::new(transport)) as Box<TOutputProtocol>
+    }
+}
+
+fn collection_type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Bool => 0x01,
+        f => type_to_u8(f),
+    }
+}
+
+fn type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Stop => 0x00,
+        TType::I08 => 0x03, // equivalent to TType::Byte
+        TType::I16 => 0x04,
+        TType::I32 => 0x05,
+        TType::I64 => 0x06,
+        TType::Double => 0x07,
+        TType::String => 0x08,
+        TType::List => 0x09,
+        TType::Set => 0x0A,
+        TType::Map => 0x0B,
+        TType::Struct => 0x0C,
+        _ => panic!(format!("should not have attempted to convert {} to u8", field_type)),
+    }
+}
+
+fn collection_u8_to_type(b: u8) -> ::Result<TType> {
+    match b {
+        0x01 => Ok(TType::Bool),
+        o => u8_to_type(o),
+    }
+}
+
+fn u8_to_type(b: u8) -> ::Result<TType> {
+    match b {
+        0x00 => Ok(TType::Stop),
+        0x03 => Ok(TType::I08), // equivalent to TType::Byte
+        0x04 => Ok(TType::I16),
+        0x05 => Ok(TType::I32),
+        0x06 => Ok(TType::I64),
+        0x07 => Ok(TType::Double),
+        0x08 => Ok(TType::String),
+        0x09 => Ok(TType::List),
+        0x0A => Ok(TType::Set),
+        0x0B => Ok(TType::Map),
+        0x0C => Ok(TType::Struct),
+        unkn => {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::InvalidData,
+                message: format!("cannot convert {} into TType", unkn),
+            }))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::rc::Rc;
+    use std::cell::RefCell;
+
+    use ::protocol::{TFieldIdentifier, TMessageIdentifier, TMessageType, TInputProtocol,
+                     TListIdentifier, TMapIdentifier, TOutputProtocol, TSetIdentifier,
+                     TStructIdentifier, TType};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_begin_0() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("foo", TMessageType::Call, 431)));
+
+        let expected: [u8; 8] =
+            [0x82 /* protocol ID */, 0x21 /* message type | protocol version */, 0xDE,
+             0x06 /* zig-zag varint sequence number */, 0x03 /* message-name length */,
+             0x66, 0x6F, 0x6F /* "foo" */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_write_message_begin_1() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("bar", TMessageType::Reply, 991828)));
+
+        let expected: [u8; 9] =
+            [0x82 /* protocol ID */, 0x41 /* message type | protocol version */, 0xA8,
+             0x89, 0x79 /* zig-zag varint sequence number */,
+             0x03 /* message-name length */, 0x62, 0x61, 0x72 /* "bar" */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_message_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1283948);
+
+        assert_success!(o_prot.write_message_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_message_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_message_end() {
+        assert_no_write(|o| o.write_message_end());
+    }
+
+    // NOTE: structs and fields are tested together
+    //
+
+    #[test]
+    fn must_write_struct_with_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 5] = [0x03 /* field type */, 0x00 /* first field id */,
+                                 0x44 /* field delta (4) | field type */,
+                                 0x59 /* field delta (5) | field type */,
+                                 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_non_zero_initial_field_and_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 4] = [0x15 /* field delta (1) | field type */,
+                                 0x1A /* field delta (1) | field type */,
+                                 0x48 /* field delta (4) | field type */,
+                                 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_long_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 8] =
+            [0x05 /* field type */, 0x00 /* first field id */,
+             0x06 /* field type */, 0x20 /* zig-zag varint field id */,
+             0x0A /* field type */, 0xC6, 0x01 /* zig-zag varint field id */,
+             0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_long_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_mix_of_long_and_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this is only 3 up from the previous it is recorded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 10] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */, 0x0A /* field type */, 0xD0,
+             0x0F /* zig-zag varint field id */, 0x0A /* field type */, 0xA2,
+             0x1F /* zig-zag varint field id */,
+             0x3A /* field delta (3) | field type */, 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_mix_of_long_and_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        let struct_ident = TStructIdentifier::new("foo");
+        assert_success!(o_prot.write_struct_begin(&struct_ident));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // since this is only 3 up from the previous it is recorded as a delta
+        let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004);
+        assert_success!(o_prot.write_field_begin(&field_ident_5));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_5 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_5,
+                   TFieldIdentifier { name: None, ..field_ident_5 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_0() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a delta
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */,
+             0x73 /* field delta (7) | field type */, 0x07 /* field type */,
+             0x30 /* zig-zag varint field id */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_0() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a delta
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_1() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a full write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */, 0x07 /* field type */,
+             0x30 /* zig-zag varint field id */,
+             0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_1() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a full write
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_2() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a delta write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
+             0x2A /* zig-zag varint field id */, 0x77 /* field delta(7) | field type */,
+             0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_2() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_3() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a full write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 8] =
+            [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
+             0x2A /* zig-zag varint field id */, 0x07 /* field type */,
+             0x2A /* zig-zag varint field id */,
+             0x63 /* field delta (6) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_3() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a full write
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_bool_field() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 16 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9)));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45)));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] = [0x11 /* field delta (1) | true */,
+                                 0x82 /* field delta (8) | false */, 0x01 /* true */,
+                                 0x34 /* field id */, 0x02 /* false */,
+                                 0x5A /* field id */, 0x00 /* stop field */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_bool_field() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        let struct_ident = TStructIdentifier::new("foo");
+        assert_success!(o_prot.write_struct_begin(&struct_ident));
+
+        // write two fields
+
+        // since the delta is > 0 and < 16 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        let read_value_1 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_1, true);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        let read_value_2 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_2, false);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        let read_value_3 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_3, true);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        let read_value_4 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_4, false);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_5 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_5,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_field_end_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_field_end().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_stop_field_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_field_stop().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_struct_end_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_struct_end().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_struct_end_without_any_fields() {
+        let (_, _, mut o_prot) = test_objects();
+        o_prot.write_struct_end().unwrap();
+    }
+
+    #[test]
+    fn must_write_field_end() {
+        assert_no_write(|o| o.write_field_end());
+    }
+
+    #[test]
+    fn must_write_small_sized_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4)));
+
+        let expected: [u8; 1] = [0x46 /* size | elem_type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_small_sized_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::I08, 10);
+
+        assert_success!(o_prot.write_list_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_large_sized_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999));
+        assert!(res.is_ok());
+
+        let expected: [u8; 3] = [0xF9 /* 0xF0 | elem_type */, 0x8F,
+                                 0x4E /* size as varint */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_large_sized_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::Set, 47381);
+
+        assert_success!(o_prot.write_list_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_list_end() {
+        assert_no_write(|o| o.write_list_end());
+    }
+
+    #[test]
+    fn must_write_small_sized_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2)));
+
+        let expected: [u8; 1] = [0x2C /* size | elem_type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_small_sized_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::I16, 7);
+
+        assert_success!(o_prot.write_set_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_set_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_large_sized_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891)));
+
+        let expected: [u8; 4] = [0xF7 /* 0xF0 | elem_type */, 0xD3, 0xBA,
+                                 0x01 /* size as varint */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_large_sized_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::Map, 3928429);
+
+        assert_success!(o_prot.write_set_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_set_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_set_end() {
+        assert_no_write(|o| o.write_set_end());
+    }
+
+    #[test]
+    fn must_write_zero_sized_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0)));
+
+        let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_read_zero_sized_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0)));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&res,
+                   &TMapIdentifier {
+                       key_type: None,
+                       value_type: None,
+                       size: 0,
+                   });
+    }
+
+    #[test]
+    fn must_write_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::String, 238)));
+
+        let expected: [u8; 3] = [0xEE, 0x01 /* size as varint */,
+                                 0x78 /* key type | val type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMapIdentifier::new(TType::Map, TType::List, 1928349);
+
+        assert_success!(o_prot.write_map_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_map_end() {
+        assert_no_write(|o| o.write_map_end());
+    }
+
+    #[test]
+    fn must_write_map_with_bool_key_and_value() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_map_end());
+
+        let expected: [u8; 4] = [0x01 /* size as varint */,
+                                 0x11 /* key type | val type */, 0x01 /* key: true */,
+                                 0x02 /* val: false */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_map_with_bool_value() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2);
+        assert_success!(o_prot.write_map_begin(&map_ident));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_map_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // map header
+        let rcvd_ident = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&rcvd_ident, &map_ident);
+        // key 1
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, true);
+        // val 1
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, false);
+        // key 2
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, false);
+        // val 2
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, true);
+        // map end
+        assert_success!(i_prot.read_map_end());
+    }
+
+    #[test]
+    fn must_read_map_end() {
+        let (_, mut i_prot, _) = test_objects();
+        assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
+    }
+
+    fn test_objects
+        ()
+        -> (Rc<RefCell<Box<TBufferTransport>>>, TCompactInputProtocol, TCompactOutputProtocol)
+    {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(80, 80))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let i_prot = TCompactInputProtocol::new(inner.clone());
+        let o_prot = TCompactOutputProtocol::new(inner.clone());
+
+        (mem, i_prot, o_prot)
+    }
+
+    fn assert_no_write<F: FnMut(&mut TCompactOutputProtocol) -> ::Result<()>>(mut write_fn: F) {
+        let (trans, _, mut o_prot) = test_objects();
+        assert!(write_fn(&mut o_prot).is_ok());
+        assert_eq!(trans.borrow().write_buffer_as_ref().len(), 0);
+    }
+}
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
new file mode 100644
index 0000000..b230d63
--- /dev/null
+++ b/lib/rs/src/protocol/mod.rs
@@ -0,0 +1,709 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+//! Types used to send and receive primitives between a Thrift client and server.
+//!
+//! # Examples
+//!
+//! Create and use a `TOutputProtocol`.
+//!
+//! ```no_run
+//! use std::cell::RefCell;
+//! use std::rc::Rc;
+//! use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
+//! use thrift::transport::{TTcpTransport, TTransport};
+//!
+//! // create the I/O channel
+//! let mut transport = TTcpTransport::new();
+//! transport.open("127.0.0.1:9090").unwrap();
+//! let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+//!
+//! // create the protocol to encode types into bytes
+//! let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+//!
+//! // write types
+//! o_prot.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
+//! o_prot.write_string("foo").unwrap();
+//! o_prot.write_field_end().unwrap();
+//! ```
+//!
+//! Create and use a `TInputProtocol`.
+//!
+//! ```no_run
+//! use std::cell::RefCell;
+//! use std::rc::Rc;
+//! use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+//! use thrift::transport::{TTcpTransport, TTransport};
+//!
+//! // create the I/O channel
+//! let mut transport = TTcpTransport::new();
+//! transport.open("127.0.0.1:9090").unwrap();
+//! let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+//!
+//! // create the protocol to decode bytes into types
+//! let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+//!
+//! // read types from the wire
+//! let field_identifier = i_prot.read_field_begin().unwrap();
+//! let field_contents = i_prot.read_string().unwrap();
+//! let field_end = i_prot.read_field_end().unwrap();
+//! ```
+
+use std::cell::RefCell;
+use std::fmt;
+use std::fmt::{Display, Formatter};
+use std::convert::From;
+use std::rc::Rc;
+use try_from::TryFrom;
+
+use ::{ProtocolError, ProtocolErrorKind};
+use ::transport::TTransport;
+
+mod binary;
+mod compact;
+mod multiplexed;
+mod stored;
+
+pub use self::binary::{TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol,
+                       TBinaryOutputProtocolFactory};
+pub use self::compact::{TCompactInputProtocol, TCompactInputProtocolFactory,
+                        TCompactOutputProtocol, TCompactOutputProtocolFactory};
+pub use self::multiplexed::TMultiplexedOutputProtocol;
+pub use self::stored::TStoredInputProtocol;
+
+// Default maximum depth to which `TInputProtocol::skip` will skip a Thrift
+// field. A default is necessary because Thrift structs or collections may
+// contain nested structs and collections, which could result in indefinite
+// recursion.
+const MAXIMUM_SKIP_DEPTH: i8 = 64;
+
+/// Converts a stream of bytes into Thrift identifiers, primitives,
+/// containers, or structs.
+///
+/// This trait does not deal with higher-level Thrift concepts like structs or
+/// exceptions - only with primitives and message or container boundaries. Once
+/// bytes are read they are deserialized and an identifier (for example
+/// `TMessageIdentifier`) or a primitive is returned.
+///
+/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
+/// instance and its underlying transport should be terminated.
+///
+/// # Examples
+///
+/// Create and use a `TInputProtocol`
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+///
+/// let field_identifier = i_prot.read_field_begin().unwrap();
+/// let field_contents = i_prot.read_string().unwrap();
+/// let field_end = i_prot.read_field_end().unwrap();
+/// ```
+pub trait TInputProtocol {
+    /// Read the beginning of a Thrift message.
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier>;
+    /// Read the end of a Thrift message.
+    fn read_message_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a Thrift struct.
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>>;
+    /// Read the end of a Thrift struct.
+    fn read_struct_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a Thrift struct field.
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier>;
+    /// Read the end of a Thrift struct field.
+    fn read_field_end(&mut self) -> ::Result<()>;
+    /// Read a bool.
+    fn read_bool(&mut self) -> ::Result<bool>;
+    /// Read a fixed-length byte array.
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>>;
+    /// Read a word.
+    fn read_i8(&mut self) -> ::Result<i8>;
+    /// Read a 16-bit signed integer.
+    fn read_i16(&mut self) -> ::Result<i16>;
+    /// Read a 32-bit signed integer.
+    fn read_i32(&mut self) -> ::Result<i32>;
+    /// Read a 64-bit signed integer.
+    fn read_i64(&mut self) -> ::Result<i64>;
+    /// Read a 64-bit float.
+    fn read_double(&mut self) -> ::Result<f64>;
+    /// Read a fixed-length string (not null terminated).
+    fn read_string(&mut self) -> ::Result<String>;
+    /// Read the beginning of a list.
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier>;
+    /// Read the end of a list.
+    fn read_list_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a set.
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier>;
+    /// Read the end of a set.
+    fn read_set_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a map.
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier>;
+    /// Read the end of a map.
+    fn read_map_end(&mut self) -> ::Result<()>;
+    /// Skip a field with type `field_type` recursively until the default
+    /// maximum skip depth is reached.
+    fn skip(&mut self, field_type: TType) -> ::Result<()> {
+        self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH)
+    }
+    /// Skip a field with type `field_type` recursively up to `depth` levels.
+    fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> ::Result<()> {
+        if depth == 0 {
+            return Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::DepthLimit,
+                message: format!("cannot parse past {:?}", field_type),
+            }));
+        }
+
+        match field_type {
+            TType::Bool => self.read_bool().map(|_| ()),
+            TType::I08 => self.read_i8().map(|_| ()),
+            TType::I16 => self.read_i16().map(|_| ()),
+            TType::I32 => self.read_i32().map(|_| ()),
+            TType::I64 => self.read_i64().map(|_| ()),
+            TType::Double => self.read_double().map(|_| ()),
+            TType::String => self.read_string().map(|_| ()),
+            TType::Struct => {
+                self.read_struct_begin()?;
+                loop {
+                    let field_ident = self.read_field_begin()?;
+                    if field_ident.field_type == TType::Stop {
+                        break;
+                    }
+                    self.skip_till_depth(field_ident.field_type, depth - 1)?;
+                }
+                self.read_struct_end()
+            }
+            TType::List => {
+                let list_ident = self.read_list_begin()?;
+                for _ in 0..list_ident.size {
+                    self.skip_till_depth(list_ident.element_type, depth - 1)?;
+                }
+                self.read_list_end()
+            }
+            TType::Set => {
+                let set_ident = self.read_set_begin()?;
+                for _ in 0..set_ident.size {
+                    self.skip_till_depth(set_ident.element_type, depth - 1)?;
+                }
+                self.read_set_end()
+            }
+            TType::Map => {
+                let map_ident = self.read_map_begin()?;
+                for _ in 0..map_ident.size {
+                    let key_type = map_ident.key_type
+                        .expect("non-zero sized map should contain key type");
+                    let val_type = map_ident.value_type
+                        .expect("non-zero sized map should contain value type");
+                    self.skip_till_depth(key_type, depth - 1)?;
+                    self.skip_till_depth(val_type, depth - 1)?;
+                }
+                self.read_map_end()
+            }
+            u => {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::Unknown,
+                    message: format!("cannot skip field type {:?}", &u),
+                }))
+            }
+        }
+    }
+
+    // utility (DO NOT USE IN GENERATED CODE!!!!)
+    //
+
+    /// Read an unsigned byte.
+    ///
+    /// This method should **never** be used in generated code.
+    fn read_byte(&mut self) -> ::Result<u8>;
+}
+
+/// Converts Thrift identifiers, primitives, containers or structs into a
+/// stream of bytes.
+///
+/// This trait does not deal with higher-level Thrift concepts like structs or
+/// exceptions - only with primitives and message or container boundaries.
+/// Write methods take an identifier (for example, `TMessageIdentifier`) or a
+/// primitive. Any or all of the fields in an identifier may be omitted when
+/// writing to the transport. Write methods may even be noops. All of this is
+/// transparent to the caller; as long as a matching `TInputProtocol`
+/// implementation is used, received messages will be decoded correctly.
+///
+/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
+/// instance and its underlying transport should be terminated.
+///
+/// # Examples
+///
+/// Create and use a `TOutputProtocol`
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+///
+/// o_prot.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
+/// o_prot.write_string("foo").unwrap();
+/// o_prot.write_field_end().unwrap();
+/// ```
+pub trait TOutputProtocol {
+    /// Write the beginning of a Thrift message.
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift message.
+    fn write_message_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a Thrift struct.
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift struct.
+    fn write_struct_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a Thrift field.
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift field.
+    fn write_field_end(&mut self) -> ::Result<()>;
+    /// Write a STOP field indicating that all the fields in a struct have been
+    /// written.
+    fn write_field_stop(&mut self) -> ::Result<()>;
+    /// Write a bool.
+    fn write_bool(&mut self, b: bool) -> ::Result<()>;
+    /// Write a fixed-length byte array.
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()>;
+    /// Write an 8-bit signed integer.
+    fn write_i8(&mut self, i: i8) -> ::Result<()>;
+    /// Write a 16-bit signed integer.
+    fn write_i16(&mut self, i: i16) -> ::Result<()>;
+    /// Write a 32-bit signed integer.
+    fn write_i32(&mut self, i: i32) -> ::Result<()>;
+    /// Write a 64-bit signed integer.
+    fn write_i64(&mut self, i: i64) -> ::Result<()>;
+    /// Write a 64-bit float.
+    fn write_double(&mut self, d: f64) -> ::Result<()>;
+    /// Write a fixed-length string.
+    fn write_string(&mut self, s: &str) -> ::Result<()>;
+    /// Write the beginning of a list.
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()>;
+    /// Write the end of a list.
+    fn write_list_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a set.
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()>;
+    /// Write the end of a set.
+    fn write_set_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a map.
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()>;
+    /// Write the end of a map.
+    fn write_map_end(&mut self) -> ::Result<()>;
+    /// Flush buffered bytes to the underlying transport.
+    fn flush(&mut self) -> ::Result<()>;
+
+    // utility (DO NOT USE IN GENERATED CODE!!!!)
+    //
+
+    /// Write an unsigned byte.
+    ///
+    /// This method should **never** be used in generated code.
+    fn write_byte(&mut self, b: u8) -> ::Result<()>; // FIXME: REMOVE
+}
+
+/// Helper type used by servers to create `TInputProtocol` instances for
+/// accepted client connections.
+///
+/// # Examples
+///
+/// Create a `TInputProtocolFactory` and use it to create a `TInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocolFactory, TInputProtocolFactory};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_proto_factory = TBinaryInputProtocolFactory::new();
+/// let i_prot = i_proto_factory.create(transport);
+/// ```
+pub trait TInputProtocolFactory {
+    /// Create a `TInputProtocol` that reads bytes from `transport`.
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol>;
+}
+
+/// Helper type used by servers to create `TOutputProtocol` instances for
+/// accepted client connections.
+///
+/// # Examples
+///
+/// Create a `TOutputProtocolFactory` and use it to create a `TOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocolFactory, TOutputProtocolFactory};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_proto_factory = TBinaryOutputProtocolFactory::new();
+/// let o_prot = o_proto_factory.create(transport);
+/// ```
+pub trait TOutputProtocolFactory {
+    /// Create a `TOutputProtocol` that writes bytes to `transport`.
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol>;
+}
+
+/// Thrift message identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TMessageIdentifier {
+    /// Service call the message is associated with.
+    pub name: String,
+    /// Message type.
+    pub message_type: TMessageType,
+    /// Ordered sequence number identifying the message.
+    pub sequence_number: i32,
+}
+
+impl TMessageIdentifier {
+    /// Create a `TMessageIdentifier` for a Thrift service-call named `name`
+    /// with message type `message_type` and sequence number `sequence_number`.
+    pub fn new<S: Into<String>>(name: S,
+                                message_type: TMessageType,
+                                sequence_number: i32)
+                                -> TMessageIdentifier {
+        TMessageIdentifier {
+            name: name.into(),
+            message_type: message_type,
+            sequence_number: sequence_number,
+        }
+    }
+}
+
+/// Thrift struct identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TStructIdentifier {
+    /// Name of the encoded Thrift struct.
+    pub name: String,
+}
+
+impl TStructIdentifier {
+    /// Create a `TStructIdentifier` for a struct named `name`.
+    pub fn new<S: Into<String>>(name: S) -> TStructIdentifier {
+        TStructIdentifier { name: name.into() }
+    }
+}
+
+/// Thrift field identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TFieldIdentifier {
+    /// Name of the Thrift field.
+    ///
+    /// `None` if it's not sent over the wire.
+    pub name: Option<String>,
+    /// Field type.
+    ///
+    /// This may be a primitive, container, or a struct.
+    pub field_type: TType,
+    /// Thrift field id.
+    ///
+    /// `None` only if `field_type` is `TType::Stop`.
+    pub id: Option<i16>,
+}
+
+impl TFieldIdentifier {
+    /// Create a `TFieldIdentifier` for a field named `name` with type
+    /// `field_type` and field id `id`.
+    ///
+    /// `id` should be `None` if `field_type` is `TType::Stop`.
+    pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier
+        where N: Into<Option<S>>,
+              S: Into<String>,
+              I: Into<Option<i16>>
+    {
+        TFieldIdentifier {
+            name: name.into().map(|n| n.into()),
+            field_type: field_type,
+            id: id.into(),
+        }
+    }
+}
+
+/// Thrift list identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TListIdentifier {
+    /// Type of the elements in the list.
+    pub element_type: TType,
+    /// Number of elements in the list.
+    pub size: i32,
+}
+
+impl TListIdentifier {
+    /// Create a `TListIdentifier` for a list with `size` elements of type
+    /// `element_type`.
+    pub fn new(element_type: TType, size: i32) -> TListIdentifier {
+        TListIdentifier {
+            element_type: element_type,
+            size: size,
+        }
+    }
+}
+
+/// Thrift set identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TSetIdentifier {
+    /// Type of the elements in the set.
+    pub element_type: TType,
+    /// Number of elements in the set.
+    pub size: i32,
+}
+
+impl TSetIdentifier {
+    /// Create a `TSetIdentifier` for a set with `size` elements of type
+    /// `element_type`.
+    pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
+        TSetIdentifier {
+            element_type: element_type,
+            size: size,
+        }
+    }
+}
+
+/// Thrift map identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TMapIdentifier {
+    /// Map key type.
+    pub key_type: Option<TType>,
+    /// Map value type.
+    pub value_type: Option<TType>,
+    /// Number of entries in the map.
+    pub size: i32,
+}
+
+impl TMapIdentifier {
+    /// Create a `TMapIdentifier` for a map with `size` entries of type
+    /// `key_type -> value_type`.
+    pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier
+        where K: Into<Option<TType>>,
+              V: Into<Option<TType>>
+    {
+        TMapIdentifier {
+            key_type: key_type.into(),
+            value_type: value_type.into(),
+            size: size,
+        }
+    }
+}
+
+/// Thrift message types.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum TMessageType {
+    /// Service-call request.
+    Call,
+    /// Service-call response.
+    Reply,
+    /// Unexpected error in the remote service.
+    Exception,
+    /// One-way service-call request (no response is expected).
+    OneWay,
+}
+
+impl Display for TMessageType {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            TMessageType::Call => write!(f, "Call"),
+            TMessageType::Reply => write!(f, "Reply"),
+            TMessageType::Exception => write!(f, "Exception"),
+            TMessageType::OneWay => write!(f, "OneWay"),
+        }
+    }
+}
+
+impl From<TMessageType> for u8 {
+    fn from(message_type: TMessageType) -> Self {
+        match message_type {
+            TMessageType::Call => 0x01,
+            TMessageType::Reply => 0x02,
+            TMessageType::Exception => 0x03,
+            TMessageType::OneWay => 0x04,
+        }
+    }
+}
+
+impl TryFrom<u8> for TMessageType {
+    type Err = ::Error;
+    fn try_from(b: u8) -> ::Result<Self> {
+        match b {
+            0x01 => Ok(TMessageType::Call),
+            0x02 => Ok(TMessageType::Reply),
+            0x03 => Ok(TMessageType::Exception),
+            0x04 => Ok(TMessageType::OneWay),
+            unkn => {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::InvalidData,
+                    message: format!("cannot convert {} to TMessageType", unkn),
+                }))
+            }
+        }
+    }
+}
+
+/// Thrift struct-field types.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum TType {
+    /// Indicates that there are no more serialized fields in this Thrift struct.
+    Stop,
+    /// Void (`()`) field.
+    Void,
+    /// Boolean.
+    Bool,
+    /// Signed 8-bit int.
+    I08,
+    /// Double-precision number.
+    Double,
+    /// Signed 16-bit int.
+    I16,
+    /// Signed 32-bit int.
+    I32,
+    /// Signed 64-bit int.
+    I64,
+    /// UTF-8 string.
+    String,
+    /// UTF-7 string. *Unsupported*.
+    Utf7,
+    /// Thrift struct.
+    Struct,
+    /// Map.
+    Map,
+    /// Set.
+    Set,
+    /// List.
+    List,
+    /// UTF-8 string.
+    Utf8,
+    /// UTF-16 string. *Unsupported*.
+    Utf16,
+}
+
+impl Display for TType {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            TType::Stop => write!(f, "STOP"),
+            TType::Void => write!(f, "void"),
+            TType::Bool => write!(f, "bool"),
+            TType::I08 => write!(f, "i08"),
+            TType::Double => write!(f, "double"),
+            TType::I16 => write!(f, "i16"),
+            TType::I32 => write!(f, "i32"),
+            TType::I64 => write!(f, "i64"),
+            TType::String => write!(f, "string"),
+            TType::Utf7 => write!(f, "UTF7"),
+            TType::Struct => write!(f, "struct"),
+            TType::Map => write!(f, "map"),
+            TType::Set => write!(f, "set"),
+            TType::List => write!(f, "list"),
+            TType::Utf8 => write!(f, "UTF8"),
+            TType::Utf16 => write!(f, "UTF16"),
+        }
+    }
+}
+
+/// Compare the expected message sequence number `expected` with the received
+/// message sequence number `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::BadSequenceId,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Compare the expected service-call name `expected` with the received
+/// service-call name `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_service_call(expected: &str, actual: &str) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::WrongMethodName,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Compare the expected message type `expected` with the received message type
+/// `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::InvalidMessageType,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Check if a required Thrift struct field exists.
+///
+/// Return `()` if it does, `Err` otherwise.
+pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> ::Result<()> {
+    match *field {
+        Some(_) => Ok(()),
+        None => {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::Unknown,
+                message: format!("missing required field {}", field_name),
+            }))
+        }
+    }
+}
+
+/// Extract the field id from a Thrift field identifier.
+///
+/// `field_ident` must *not* have `TFieldIdentifier.field_type` of type `TType::Stop`.
+///
+/// Return `TFieldIdentifier.id` if an id exists, `Err` otherwise.
+pub fn field_id(field_ident: &TFieldIdentifier) -> ::Result<i16> {
+    field_ident.id.ok_or_else(|| {
+        ::Error::Protocol(::ProtocolError {
+            kind: ::ProtocolErrorKind::Unknown,
+            message: format!("missing field in in {:?}", field_ident),
+        })
+    })
+}
diff --git a/lib/rs/src/protocol/multiplexed.rs b/lib/rs/src/protocol/multiplexed.rs
new file mode 100644
index 0000000..15fe608
--- /dev/null
+++ b/lib/rs/src/protocol/multiplexed.rs
@@ -0,0 +1,219 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
+            TOutputProtocol, TSetIdentifier, TStructIdentifier};
+
+/// `TOutputProtocol` that prefixes the service name to all outgoing Thrift
+/// messages.
+///
+/// A `TMultiplexedOutputProtocol` should be used when multiple Thrift services
+/// send messages over a single I/O channel. By prefixing service identifiers
+/// to outgoing messages receivers are able to demux them and route them to the
+/// appropriate service processor. Rust receivers must use a `TMultiplexedProcessor`
+/// to process incoming messages, while other languages must use their
+/// corresponding multiplexed processor implementations.
+///
+/// For example, given a service `TestService` and a service call `test_call`,
+/// this implementation would identify messages as originating from
+/// `TestService:test_call`.
+///
+/// # Examples
+///
+/// Create and use a `TMultiplexedOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TMessageIdentifier, TMessageType, TOutputProtocol};
+/// use thrift::protocol::{TBinaryOutputProtocol, TMultiplexedOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let o_prot = TBinaryOutputProtocol::new(transport, true);
+/// let mut o_prot = TMultiplexedOutputProtocol::new("service_name", Box::new(o_prot));
+///
+/// let ident = TMessageIdentifier::new("svc_call", TMessageType::Call, 1);
+/// o_prot.write_message_begin(&ident).unwrap();
+/// ```
+pub struct TMultiplexedOutputProtocol {
+    service_name: String,
+    inner: Box<TOutputProtocol>,
+}
+
+impl TMultiplexedOutputProtocol {
+    /// Create a `TMultiplexedOutputProtocol` that identifies outgoing messages
+    /// as originating from a service named `service_name` and sends them over
+    /// the `wrapped` `TOutputProtocol`. Outgoing messages are encoded and sent
+    /// by `wrapped`, not by this instance.
+    pub fn new(service_name: &str, wrapped: Box<TOutputProtocol>) -> TMultiplexedOutputProtocol {
+        TMultiplexedOutputProtocol {
+            service_name: service_name.to_owned(),
+            inner: wrapped,
+        }
+    }
+}
+
+// FIXME: avoid passthrough methods
+impl TOutputProtocol for TMultiplexedOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        match identifier.message_type { // FIXME: is there a better way to override identifier here?
+            TMessageType::Call | TMessageType::OneWay => {
+                let identifier = TMessageIdentifier {
+                    name: format!("{}:{}", self.service_name, identifier.name),
+                    ..*identifier
+                };
+                self.inner.write_message_begin(&identifier)
+            }
+            _ => self.inner.write_message_begin(identifier),
+        }
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        self.inner.write_message_end()
+    }
+
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()> {
+        self.inner.write_struct_begin(identifier)
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        self.inner.write_struct_end()
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        self.inner.write_field_begin(identifier)
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        self.inner.write_field_end()
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.inner.write_field_stop()
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.inner.write_bytes(b)
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        self.inner.write_bool(b)
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.inner.write_i8(i)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.inner.write_i16(i)
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.inner.write_i32(i)
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.inner.write_i64(i)
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.inner.write_double(d)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.inner.write_string(s)
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.inner.write_list_begin(identifier)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        self.inner.write_list_end()
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.inner.write_set_begin(identifier)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        self.inner.write_set_end()
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        self.inner.write_map_begin(identifier)
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        self.inner.write_map_end()
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.inner.flush()
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.inner.write_byte(b)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::cell::RefCell;
+    use std::rc::Rc;
+
+    use ::protocol::{TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_begin_with_prefixed_service_name() {
+        let (trans, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("bar", TMessageType::Call, 2);
+        assert_success!(o_prot.write_message_begin(&ident));
+
+        let expected: [u8; 19] =
+            [0x80, 0x01 /* protocol identifier */, 0x00, 0x01 /* message type */, 0x00,
+             0x00, 0x00, 0x07, 0x66, 0x6F, 0x6F /* "foo" */, 0x3A /* ":" */, 0x62, 0x61,
+             0x72 /* "bar" */, 0x00, 0x00, 0x00, 0x02 /* sequence number */];
+
+        assert_eq!(&trans.borrow().write_buffer_to_vec(), &expected);
+    }
+
+    fn test_objects() -> (Rc<RefCell<Box<TBufferTransport>>>, TMultiplexedOutputProtocol) {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(40, 40))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let o_prot = TBinaryOutputProtocol::new(inner.clone(), true);
+        let o_prot = TMultiplexedOutputProtocol::new("foo", Box::new(o_prot));
+
+        (mem, o_prot)
+    }
+}
diff --git a/lib/rs/src/protocol/stored.rs b/lib/rs/src/protocol/stored.rs
new file mode 100644
index 0000000..6826c00
--- /dev/null
+++ b/lib/rs/src/protocol/stored.rs
@@ -0,0 +1,191 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::convert::Into;
+
+use ::ProtocolErrorKind;
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TInputProtocol,
+            TSetIdentifier, TStructIdentifier};
+
+/// `TInputProtocol` required to use a `TMultiplexedProcessor`.
+///
+/// A `TMultiplexedProcessor` reads incoming message identifiers to determine to
+/// which `TProcessor` requests should be forwarded. However, once read, those
+/// message identifier bytes are no longer on the wire. Since downstream
+/// processors expect to read message identifiers from the given input protocol
+/// we need some way of supplying a `TMessageIdentifier` with the service-name
+/// stripped. This implementation stores the received `TMessageIdentifier`
+/// (without the service name) and passes it to the wrapped `TInputProtocol`
+/// when `TInputProtocol::read_message_begin(...)` is called. It delegates all
+/// other calls directly to the wrapped `TInputProtocol`.
+///
+/// This type **should not** be used by application code.
+///
+/// # Examples
+///
+/// Create and use a `TStoredInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift;
+/// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+/// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
+/// use thrift::server::TProcessor;
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// // sample processor
+/// struct ActualProcessor;
+/// impl TProcessor for ActualProcessor {
+///     fn process(
+///         &mut self,
+///         _: &mut TInputProtocol,
+///         _: &mut TOutputProtocol
+///     ) -> thrift::Result<()> {
+///         unimplemented!()
+///     }
+/// }
+/// let mut processor = ActualProcessor {};
+///
+/// // construct the shared transport
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// // construct the actual input and output protocols
+/// let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+/// let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+///
+/// // message identifier received from remote and modified to remove the service name
+/// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
+///
+/// // construct the proxy input protocol
+/// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
+/// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
+/// ```
+pub struct TStoredInputProtocol<'a> {
+    inner: &'a mut TInputProtocol,
+    message_ident: Option<TMessageIdentifier>,
+}
+
+impl<'a> TStoredInputProtocol<'a> {
+    /// Create a `TStoredInputProtocol` that delegates all calls other than
+    /// `TInputProtocol::read_message_begin(...)` to a `wrapped`
+    /// `TInputProtocol`. `message_ident` is the modified message identifier -
+    /// with service name stripped - that will be passed to
+    /// `wrapped.read_message_begin(...)`.
+    pub fn new(wrapped: &mut TInputProtocol,
+               message_ident: TMessageIdentifier)
+               -> TStoredInputProtocol {
+        TStoredInputProtocol {
+            inner: wrapped,
+            message_ident: message_ident.into(),
+        }
+    }
+}
+
+impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        self.message_ident.take().ok_or_else(|| {
+            ::errors::new_protocol_error(ProtocolErrorKind::Unknown,
+                                         "message identifier already read")
+        })
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        self.inner.read_message_end()
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        self.inner.read_struct_begin()
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        self.inner.read_struct_end()
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        self.inner.read_field_begin()
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        self.inner.read_field_end()
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        self.inner.read_bytes()
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        self.inner.read_bool()
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.inner.read_i8()
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.inner.read_i16()
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.inner.read_i32()
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.inner.read_i64()
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.inner.read_double()
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        self.inner.read_string()
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        self.inner.read_list_begin()
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        self.inner.read_list_end()
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        self.inner.read_set_begin()
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        self.inner.read_set_end()
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        self.inner.read_map_begin()
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        self.inner.read_map_end()
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        self.inner.read_byte()
+    }
+}
diff --git a/lib/rs/src/server/mod.rs b/lib/rs/src/server/mod.rs
new file mode 100644
index 0000000..ceac18a
--- /dev/null
+++ b/lib/rs/src/server/mod.rs
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+//! Types required to implement a Thrift server.
+
+use ::protocol::{TInputProtocol, TOutputProtocol};
+
+mod simple;
+mod multiplexed;
+
+pub use self::simple::TSimpleServer;
+pub use self::multiplexed::TMultiplexedProcessor;
+
+/// Handles incoming Thrift messages and dispatches them to the user-defined
+/// handler functions.
+///
+/// An implementation is auto-generated for each Thrift service. When used by a
+/// server (for example, a `TSimpleServer`), it will demux incoming service
+/// calls and invoke the corresponding user-defined handler function.
+///
+/// # Examples
+///
+/// Create and start a server using the auto-generated `TProcessor` for
+/// a Thrift service `SimpleService`.
+///
+/// ```no_run
+/// use thrift;
+/// use thrift::protocol::{TInputProtocol, TOutputProtocol};
+/// use thrift::server::TProcessor;
+///
+/// //
+/// // auto-generated
+/// //
+///
+/// // processor for `SimpleService`
+/// struct SimpleServiceSyncProcessor;
+/// impl SimpleServiceSyncProcessor {
+///     fn new<H: SimpleServiceSyncHandler>(processor: H) -> SimpleServiceSyncProcessor {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // `TProcessor` implementation for `SimpleService`
+/// impl TProcessor for SimpleServiceSyncProcessor {
+///     fn process(&mut self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> thrift::Result<()> {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // service functions for SimpleService
+/// trait SimpleServiceSyncHandler {
+///     fn service_call(&mut self) -> thrift::Result<()>;
+/// }
+///
+/// //
+/// // user-code follows
+/// //
+///
+/// // define a handler that will be invoked when `service_call` is received
+/// struct SimpleServiceHandlerImpl;
+/// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl {
+///     fn service_call(&mut self) -> thrift::Result<()> {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // instantiate the processor
+/// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {});
+///
+/// // at this point you can pass the processor to the server
+/// // let server = TSimpleServer::new(..., processor);
+/// ```
+pub trait TProcessor {
+    /// Process a Thrift service call.
+    ///
+    /// Reads arguments from `i`, executes the user's handler code, and writes
+    /// the response to `o`.
+    ///
+    /// Returns `()` if the handler was executed; `Err` otherwise.
+    fn process(&mut self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> ::Result<()>;
+}
diff --git a/lib/rs/src/server/multiplexed.rs b/lib/rs/src/server/multiplexed.rs
new file mode 100644
index 0000000..d2314a1
--- /dev/null
+++ b/lib/rs/src/server/multiplexed.rs
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::collections::HashMap;
+use std::convert::Into;
+
+use ::{new_application_error, ApplicationErrorKind};
+use ::protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol};
+
+use super::TProcessor;
+
+/// A `TProcessor` that can demux service calls to multiple underlying
+/// Thrift services.
+///
+/// Users register service-specific `TProcessor` instances with a
+/// `TMultiplexedProcessor`, and then register that processor with a server
+/// implementation. Following that, all incoming service calls are automatically
+/// routed to the service-specific `TProcessor`.
+///
+/// A `TMultiplexedProcessor` can only handle messages sent by a
+/// `TMultiplexedOutputProtocol`.
+pub struct TMultiplexedProcessor {
+    processors: HashMap<String, Box<TProcessor>>,
+}
+
+impl TMultiplexedProcessor {
+    /// Register a service-specific `processor` for the service named
+    /// `service_name`.
+    ///
+    /// Return `true` if this is the first registration for `service_name`.
+    ///
+    /// Return `false` if a mapping previously existed (the previous mapping is
+    /// *not* overwritten).
+    #[cfg_attr(feature = "cargo-clippy", allow(map_entry))]
+    pub fn register_processor<S: Into<String>>(&mut self,
+                                               service_name: S,
+                                               processor: Box<TProcessor>)
+                                               -> bool {
+        let name = service_name.into();
+        if self.processors.contains_key(&name) {
+            false
+        } else {
+            self.processors.insert(name, processor);
+            true
+        }
+    }
+}
+
+impl TProcessor for TMultiplexedProcessor {
+    fn process(&mut self,
+               i_prot: &mut TInputProtocol,
+               o_prot: &mut TOutputProtocol)
+               -> ::Result<()> {
+        let msg_ident = i_prot.read_message_begin()?;
+        let sep_index = msg_ident.name
+            .find(':')
+            .ok_or_else(|| {
+                new_application_error(ApplicationErrorKind::Unknown,
+                                      "no service separator found in incoming message")
+            })?;
+
+        let (svc_name, svc_call) = msg_ident.name.split_at(sep_index);
+
+        match self.processors.get_mut(svc_name) {
+            Some(ref mut processor) => {
+                let new_msg_ident = TMessageIdentifier::new(svc_call,
+                                                            msg_ident.message_type,
+                                                            msg_ident.sequence_number);
+                let mut proxy_i_prot = TStoredInputProtocol::new(i_prot, new_msg_ident);
+                processor.process(&mut proxy_i_prot, o_prot)
+            }
+            None => {
+                Err(new_application_error(ApplicationErrorKind::Unknown,
+                                          format!("no processor found for service {}", svc_name)))
+            }
+        }
+    }
+}
diff --git a/lib/rs/src/server/simple.rs b/lib/rs/src/server/simple.rs
new file mode 100644
index 0000000..89ed977
--- /dev/null
+++ b/lib/rs/src/server/simple.rs
@@ -0,0 +1,189 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::cell::RefCell;
+use std::net::{TcpListener, TcpStream};
+use std::rc::Rc;
+
+use ::{ApplicationError, ApplicationErrorKind};
+use ::protocol::{TInputProtocolFactory, TOutputProtocolFactory};
+use ::transport::{TTcpTransport, TTransport, TTransportFactory};
+
+use super::TProcessor;
+
+/// Single-threaded blocking Thrift socket server.
+///
+/// A `TSimpleServer` listens on a given address and services accepted
+/// connections *synchronously* and *sequentially* - i.e. in a blocking manner,
+/// one at a time - on the main thread. Each accepted connection has an input
+/// half and an output half, each of which uses a `TTransport` and `TProtocol`
+/// to translate messages to and from byes. Any combination of `TProtocol` and
+/// `TTransport` may be used.
+///
+/// # Examples
+///
+/// Creating and running a `TSimpleServer` using Thrift-compiler-generated
+/// service code.
+///
+/// ```no_run
+/// use thrift;
+/// use thrift::protocol::{TInputProtocolFactory, TOutputProtocolFactory};
+/// use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory};
+/// use thrift::protocol::{TInputProtocol, TOutputProtocol};
+/// use thrift::transport::{TBufferedTransportFactory, TTransportFactory};
+/// use thrift::server::{TProcessor, TSimpleServer};
+///
+/// //
+/// // auto-generated
+/// //
+///
+/// // processor for `SimpleService`
+/// struct SimpleServiceSyncProcessor;
+/// impl SimpleServiceSyncProcessor {
+///     fn new<H: SimpleServiceSyncHandler>(processor: H) -> SimpleServiceSyncProcessor {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // `TProcessor` implementation for `SimpleService`
+/// impl TProcessor for SimpleServiceSyncProcessor {
+///     fn process(&mut self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> thrift::Result<()> {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // service functions for SimpleService
+/// trait SimpleServiceSyncHandler {
+///     fn service_call(&mut self) -> thrift::Result<()>;
+/// }
+///
+/// //
+/// // user-code follows
+/// //
+///
+/// // define a handler that will be invoked when `service_call` is received
+/// struct SimpleServiceHandlerImpl;
+/// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl {
+///     fn service_call(&mut self) -> thrift::Result<()> {
+///         unimplemented!();
+///     }
+/// }
+///
+/// // instantiate the processor
+/// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {});
+///
+/// // instantiate the server
+/// let i_tr_fact: Box<TTransportFactory> = Box::new(TBufferedTransportFactory::new());
+/// let i_pr_fact: Box<TInputProtocolFactory> = Box::new(TBinaryInputProtocolFactory::new());
+/// let o_tr_fact: Box<TTransportFactory> = Box::new(TBufferedTransportFactory::new());
+/// let o_pr_fact: Box<TOutputProtocolFactory> = Box::new(TBinaryOutputProtocolFactory::new());
+///
+/// let mut server = TSimpleServer::new(
+///     i_tr_fact,
+///     i_pr_fact,
+///     o_tr_fact,
+///     o_pr_fact,
+///     processor
+/// );
+///
+/// // start listening for incoming connections
+/// match server.listen("127.0.0.1:8080") {
+///   Ok(_)  => println!("listen completed"),
+///   Err(e) => println!("listen failed with error {:?}", e),
+/// }
+/// ```
+pub struct TSimpleServer<PR: TProcessor> {
+    i_trans_factory: Box<TTransportFactory>,
+    i_proto_factory: Box<TInputProtocolFactory>,
+    o_trans_factory: Box<TTransportFactory>,
+    o_proto_factory: Box<TOutputProtocolFactory>,
+    processor: PR,
+}
+
+impl<PR: TProcessor> TSimpleServer<PR> {
+    /// Create a `TSimpleServer`.
+    ///
+    /// Each accepted connection has an input and output half, each of which
+    /// requires a `TTransport` and `TProtocol`. `TSimpleServer` uses
+    /// `input_transport_factory` and `input_protocol_factory` to create
+    /// implementations for the input, and `output_transport_factory` and
+    /// `output_protocol_factory` to create implementations for the output.
+    pub fn new(input_transport_factory: Box<TTransportFactory>,
+               input_protocol_factory: Box<TInputProtocolFactory>,
+               output_transport_factory: Box<TTransportFactory>,
+               output_protocol_factory: Box<TOutputProtocolFactory>,
+               processor: PR)
+               -> TSimpleServer<PR> {
+        TSimpleServer {
+            i_trans_factory: input_transport_factory,
+            i_proto_factory: input_protocol_factory,
+            o_trans_factory: output_transport_factory,
+            o_proto_factory: output_protocol_factory,
+            processor: processor,
+        }
+    }
+
+    /// Listen for incoming connections on `listen_address`.
+    ///
+    /// `listen_address` should be in the form `host:port`,
+    /// for example: `127.0.0.1:8080`.
+    ///
+    /// Return `()` if successful.
+    ///
+    /// Return `Err` when the server cannot bind to `listen_address` or there
+    /// is an unrecoverable error.
+    pub fn listen(&mut self, listen_address: &str) -> ::Result<()> {
+        let listener = TcpListener::bind(listen_address)?;
+        for stream in listener.incoming() {
+            match stream {
+                Ok(s) => self.handle_incoming_connection(s),
+                Err(e) => warn!("failed to accept remote connection with error {:?}", e),
+            }
+        }
+
+        Err(::Error::Application(ApplicationError {
+            kind: ApplicationErrorKind::Unknown,
+            message: "aborted listen loop".into(),
+        }))
+    }
+
+    fn handle_incoming_connection(&mut self, stream: TcpStream) {
+        // create the shared tcp stream
+        let stream = TTcpTransport::with_stream(stream);
+        let stream: Box<TTransport> = Box::new(stream);
+        let stream = Rc::new(RefCell::new(stream));
+
+        // input protocol and transport
+        let i_tran = self.i_trans_factory.create(stream.clone());
+        let i_tran = Rc::new(RefCell::new(i_tran));
+        let mut i_prot = self.i_proto_factory.create(i_tran);
+
+        // output protocol and transport
+        let o_tran = self.o_trans_factory.create(stream.clone());
+        let o_tran = Rc::new(RefCell::new(o_tran));
+        let mut o_prot = self.o_proto_factory.create(o_tran);
+
+        // process loop
+        loop {
+            let r = self.processor.process(&mut *i_prot, &mut *o_prot);
+            if let Err(e) = r {
+                warn!("processor failed with error: {:?}", e);
+                break; // FIXME: close here
+            }
+        }
+    }
+}
diff --git a/lib/rs/src/transport/buffered.rs b/lib/rs/src/transport/buffered.rs
new file mode 100644
index 0000000..3f240d8
--- /dev/null
+++ b/lib/rs/src/transport/buffered.rs
@@ -0,0 +1,400 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::cell::RefCell;
+use std::cmp;
+use std::io;
+use std::io::{Read, Write};
+use std::rc::Rc;
+
+use super::{TTransport, TTransportFactory};
+
+/// Default capacity of the read buffer in bytes.
+const DEFAULT_RBUFFER_CAPACITY: usize = 4096;
+
+/// Default capacity of the write buffer in bytes..
+const DEFAULT_WBUFFER_CAPACITY: usize = 4096;
+
+/// Transport that communicates with endpoints using a byte stream.
+///
+/// A `TBufferedTransport` maintains a fixed-size internal write buffer. All
+/// writes are made to this buffer and are sent to the wrapped transport only
+/// when `TTransport::flush()` is called. On a flush a fixed-length header with a
+/// count of the buffered bytes is written, followed by the bytes themselves.
+///
+/// A `TBufferedTransport` also maintains a fixed-size internal read buffer.
+/// On a call to `TTransport::read(...)` one full message - both fixed-length
+/// header and bytes - is read from the wrapped transport and buffered.
+/// Subsequent read calls are serviced from the internal buffer until it is
+/// exhausted, at which point the next full message is read from the wrapped
+/// transport.
+///
+/// # Examples
+///
+/// Create and use a `TBufferedTransport`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use std::io::{Read, Write};
+/// use thrift::transport::{TBufferedTransport, TTcpTransport, TTransport};
+///
+/// let mut t = TTcpTransport::new();
+/// t.open("localhost:9090").unwrap();
+///
+/// let t = Rc::new(RefCell::new(Box::new(t) as Box<TTransport>));
+/// let mut t = TBufferedTransport::new(t);
+///
+/// // read
+/// t.read(&mut vec![0u8; 1]).unwrap();
+///
+/// // write
+/// t.write(&[0x00]).unwrap();
+/// t.flush().unwrap();
+/// ```
+pub struct TBufferedTransport {
+    rbuf: Box<[u8]>,
+    rpos: usize,
+    rcap: usize,
+    wbuf: Vec<u8>,
+    inner: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TBufferedTransport {
+    /// Create a `TBufferedTransport` with default-sized internal read and
+    /// write buffers that wraps an `inner` `TTransport`.
+    pub fn new(inner: Rc<RefCell<Box<TTransport>>>) -> TBufferedTransport {
+        TBufferedTransport::with_capacity(DEFAULT_RBUFFER_CAPACITY, DEFAULT_WBUFFER_CAPACITY, inner)
+    }
+
+    /// Create a `TBufferedTransport` with an internal read buffer of size
+    /// `read_buffer_capacity` and an internal write buffer of size
+    /// `write_buffer_capacity` that wraps an `inner` `TTransport`.
+    pub fn with_capacity(read_buffer_capacity: usize,
+                         write_buffer_capacity: usize,
+                         inner: Rc<RefCell<Box<TTransport>>>)
+                         -> TBufferedTransport {
+        TBufferedTransport {
+            rbuf: vec![0; read_buffer_capacity].into_boxed_slice(),
+            rpos: 0,
+            rcap: 0,
+            wbuf: Vec::with_capacity(write_buffer_capacity),
+            inner: inner,
+        }
+    }
+
+    fn get_bytes(&mut self) -> io::Result<&[u8]> {
+        if self.rcap - self.rpos == 0 {
+            self.rpos = 0;
+            self.rcap = self.inner.borrow_mut().read(&mut self.rbuf)?;
+        }
+
+        Ok(&self.rbuf[self.rpos..self.rcap])
+    }
+
+    fn consume(&mut self, consumed: usize) {
+        // TODO: was a bug here += <-- test somehow
+        self.rpos = cmp::min(self.rcap, self.rpos + consumed);
+    }
+}
+
+impl Read for TBufferedTransport {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let mut bytes_read = 0;
+
+        loop {
+            let nread = {
+                let avail_bytes = self.get_bytes()?;
+                let avail_space = buf.len() - bytes_read;
+                let nread = cmp::min(avail_space, avail_bytes.len());
+                buf[bytes_read..(bytes_read + nread)].copy_from_slice(&avail_bytes[..nread]);
+                nread
+            };
+
+            self.consume(nread);
+            bytes_read += nread;
+
+            if bytes_read == buf.len() || nread == 0 {
+                break;
+            }
+        }
+
+        Ok(bytes_read)
+    }
+}
+
+impl Write for TBufferedTransport {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        let avail_bytes = cmp::min(buf.len(), self.wbuf.capacity() - self.wbuf.len());
+        self.wbuf.extend_from_slice(&buf[..avail_bytes]);
+        assert!(self.wbuf.len() <= self.wbuf.capacity(),
+                "copy overflowed buffer");
+        Ok(avail_bytes)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.inner.borrow_mut().write_all(&self.wbuf)?;
+        self.inner.borrow_mut().flush()?;
+        self.wbuf.clear();
+        Ok(())
+    }
+}
+
+/// Factory for creating instances of `TBufferedTransport`
+#[derive(Default)]
+pub struct TBufferedTransportFactory;
+
+impl TBufferedTransportFactory {
+    /// Create a `TBufferedTransportFactory`.
+    pub fn new() -> TBufferedTransportFactory {
+        TBufferedTransportFactory {}
+    }
+}
+
+impl TTransportFactory for TBufferedTransportFactory {
+    fn create(&self, inner: Rc<RefCell<Box<TTransport>>>) -> Box<TTransport> {
+        Box::new(TBufferedTransport::new(inner)) as Box<TTransport>
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::cell::RefCell;
+    use std::io::{Read, Write};
+    use std::rc::Rc;
+
+    use super::*;
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    macro_rules! new_transports {
+        ($wbc:expr, $rbc:expr) => (
+            {
+                let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity($wbc, $rbc))));
+                let thru: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+                let thru = Rc::new(RefCell::new(thru));
+                (mem, thru)
+            }
+        );
+    }
+
+    #[test]
+    fn must_return_zero_if_read_buffer_is_empty() {
+        let (_, thru) = new_transports!(10, 0);
+        let mut t = TBufferedTransport::with_capacity(10, 0, thru);
+
+        let mut b = vec![0; 10];
+        let read_result = t.read(&mut b);
+
+        assert_eq!(read_result.unwrap(), 0);
+    }
+
+    #[test]
+    fn must_return_zero_if_caller_reads_into_zero_capacity_buffer() {
+        let (_, thru) = new_transports!(10, 0);
+        let mut t = TBufferedTransport::with_capacity(10, 0, thru);
+
+        let read_result = t.read(&mut []);
+
+        assert_eq!(read_result.unwrap(), 0);
+    }
+
+    #[test]
+    fn must_return_zero_if_nothing_more_can_be_read() {
+        let (mem, thru) = new_transports!(4, 0);
+        let mut t = TBufferedTransport::with_capacity(4, 0, thru);
+
+        mem.borrow_mut().set_readable_bytes(&[0, 1, 2, 3]);
+
+        // read buffer is exactly the same size as bytes available
+        let mut buf = vec![0u8; 4];
+        let read_result = t.read(&mut buf);
+
+        // we've read exactly 4 bytes
+        assert_eq!(read_result.unwrap(), 4);
+        assert_eq!(&buf, &[0, 1, 2, 3]);
+
+        // try read again
+        let buf_again = vec![0u8; 4];
+        let read_result = t.read(&mut buf);
+
+        // this time, 0 bytes and we haven't changed the buffer
+        assert_eq!(read_result.unwrap(), 0);
+        assert_eq!(&buf_again, &[0, 0, 0, 0])
+    }
+
+    #[test]
+    fn must_fill_user_buffer_with_only_as_many_bytes_as_available() {
+        let (mem, thru) = new_transports!(4, 0);
+        let mut t = TBufferedTransport::with_capacity(4, 0, thru);
+
+        mem.borrow_mut().set_readable_bytes(&[0, 1, 2, 3]);
+
+        // read buffer is much larger than the bytes available
+        let mut buf = vec![0u8; 8];
+        let read_result = t.read(&mut buf);
+
+        // we've read exactly 4 bytes
+        assert_eq!(read_result.unwrap(), 4);
+        assert_eq!(&buf[..4], &[0, 1, 2, 3]);
+
+        // try read again
+        let read_result = t.read(&mut buf[4..]);
+
+        // this time, 0 bytes and we haven't changed the buffer
+        assert_eq!(read_result.unwrap(), 0);
+        assert_eq!(&buf, &[0, 1, 2, 3, 0, 0, 0, 0])
+    }
+
+    #[test]
+    fn must_read_successfully() {
+        // this test involves a few loops within the buffered transport
+        // itself where it has to drain the underlying transport in order
+        // to service a read
+
+        // we have a much smaller buffer than the
+        // underlying transport has bytes available
+        let (mem, thru) = new_transports!(10, 0);
+        let mut t = TBufferedTransport::with_capacity(2, 0, thru);
+
+        // fill the underlying transport's byte buffer
+        let mut readable_bytes = [0u8; 10];
+        for i in 0..10 {
+            readable_bytes[i] = i as u8;
+        }
+        mem.borrow_mut().set_readable_bytes(&readable_bytes);
+
+        // we ask to read into a buffer that's much larger
+        // than the one the buffered transport has; as a result
+        // it's going to have to keep asking the underlying
+        // transport for more bytes
+        let mut buf = [0u8; 8];
+        let read_result = t.read(&mut buf);
+
+        // we should have read 8 bytes
+        assert_eq!(read_result.unwrap(), 8);
+        assert_eq!(&buf, &[0, 1, 2, 3, 4, 5, 6, 7]);
+
+        // let's clear out the buffer and try read again
+        for i in 0..8 {
+            buf[i] = 0;
+        }
+        let read_result = t.read(&mut buf);
+
+        // this time we were only able to read 2 bytes
+        // (all that's remaining from the underlying transport)
+        // let's also check that the remaining bytes are untouched
+        assert_eq!(read_result.unwrap(), 2);
+        assert_eq!(&buf[0..2], &[8, 9]);
+        assert_eq!(&buf[2..], &[0, 0, 0, 0, 0, 0]);
+
+        // try read again (we should get 0)
+        // and all the existing bytes were untouched
+        let read_result = t.read(&mut buf);
+        assert_eq!(read_result.unwrap(), 0);
+        assert_eq!(&buf[0..2], &[8, 9]);
+        assert_eq!(&buf[2..], &[0, 0, 0, 0, 0, 0]);
+    }
+
+    #[test]
+    fn must_return_zero_if_nothing_can_be_written() {
+        let (_, thru) = new_transports!(0, 0);
+        let mut t = TBufferedTransport::with_capacity(0, 0, thru);
+
+        let b = vec![0; 10];
+        let r = t.write(&b);
+
+        assert_eq!(r.unwrap(), 0);
+    }
+
+    #[test]
+    fn must_return_zero_if_caller_calls_write_with_empty_buffer() {
+        let (mem, thru) = new_transports!(0, 10);
+        let mut t = TBufferedTransport::with_capacity(0, 10, thru);
+
+        let r = t.write(&[]);
+
+        assert_eq!(r.unwrap(), 0);
+        assert_eq!(mem.borrow_mut().write_buffer_as_ref(), &[]);
+    }
+
+    #[test]
+    fn must_return_zero_if_write_buffer_full() {
+        let (_, thru) = new_transports!(0, 0);
+        let mut t = TBufferedTransport::with_capacity(0, 4, thru);
+
+        let b = [0x00, 0x01, 0x02, 0x03];
+
+        // we've now filled the write buffer
+        let r = t.write(&b);
+        assert_eq!(r.unwrap(), 4);
+
+        // try write the same bytes again - nothing should be writable
+        let r = t.write(&b);
+        assert_eq!(r.unwrap(), 0);
+    }
+
+    #[test]
+    fn must_only_write_to_inner_transport_on_flush() {
+        let (mem, thru) = new_transports!(10, 10);
+        let mut t = TBufferedTransport::new(thru);
+
+        let b: [u8; 5] = [0, 1, 2, 3, 4];
+        assert_eq!(t.write(&b).unwrap(), 5);
+        assert_eq!(mem.borrow_mut().write_buffer_as_ref().len(), 0);
+
+        assert!(t.flush().is_ok());
+
+        {
+            let inner = mem.borrow_mut();
+            let underlying_buffer = inner.write_buffer_as_ref();
+            assert_eq!(b, underlying_buffer);
+        }
+    }
+
+    #[test]
+    fn must_write_successfully_after_flush() {
+        let (mem, thru) = new_transports!(0, 5);
+        let mut t = TBufferedTransport::with_capacity(0, 5, thru);
+
+        // write and flush
+        let b: [u8; 5] = [0, 1, 2, 3, 4];
+        assert_eq!(t.write(&b).unwrap(), 5);
+        assert!(t.flush().is_ok());
+
+        // check the flushed bytes
+        {
+            let inner = mem.borrow_mut();
+            let underlying_buffer = inner.write_buffer_as_ref();
+            assert_eq!(b, underlying_buffer);
+        }
+
+        // reset our underlying transport
+        mem.borrow_mut().empty_write_buffer();
+
+        // write and flush again
+        assert_eq!(t.write(&b).unwrap(), 5);
+        assert!(t.flush().is_ok());
+
+        // check the flushed bytes
+        {
+            let inner = mem.borrow_mut();
+            let underlying_buffer = inner.write_buffer_as_ref();
+            assert_eq!(b, underlying_buffer);
+        }
+    }
+}
diff --git a/lib/rs/src/transport/framed.rs b/lib/rs/src/transport/framed.rs
new file mode 100644
index 0000000..75c12f4
--- /dev/null
+++ b/lib/rs/src/transport/framed.rs
@@ -0,0 +1,187 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
+use std::cell::RefCell;
+use std::cmp;
+use std::io;
+use std::io::{ErrorKind, Read, Write};
+use std::rc::Rc;
+
+use super::{TTransport, TTransportFactory};
+
+/// Default capacity of the read buffer in bytes.
+const WRITE_BUFFER_CAPACITY: usize = 4096;
+
+/// Default capacity of the write buffer in bytes..
+const DEFAULT_WBUFFER_CAPACITY: usize = 4096;
+
+/// Transport that communicates with endpoints using framed messages.
+///
+/// A `TFramedTransport` maintains a fixed-size internal write buffer. All
+/// writes are made to this buffer and are sent to the wrapped transport only
+/// when `TTransport::flush()` is called. On a flush a fixed-length header with a
+/// count of the buffered bytes is written, followed by the bytes themselves.
+///
+/// A `TFramedTransport` also maintains a fixed-size internal read buffer.
+/// On a call to `TTransport::read(...)` one full message - both fixed-length
+/// header and bytes - is read from the wrapped transport and buffered.
+/// Subsequent read calls are serviced from the internal buffer until it is
+/// exhausted, at which point the next full message is read from the wrapped
+/// transport.
+///
+/// # Examples
+///
+/// Create and use a `TFramedTransport`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use std::io::{Read, Write};
+/// use thrift::transport::{TFramedTransport, TTcpTransport, TTransport};
+///
+/// let mut t = TTcpTransport::new();
+/// t.open("localhost:9090").unwrap();
+///
+/// let t = Rc::new(RefCell::new(Box::new(t) as Box<TTransport>));
+/// let mut t = TFramedTransport::new(t);
+///
+/// // read
+/// t.read(&mut vec![0u8; 1]).unwrap();
+///
+/// // write
+/// t.write(&[0x00]).unwrap();
+/// t.flush().unwrap();
+/// ```
+pub struct TFramedTransport {
+    rbuf: Box<[u8]>,
+    rpos: usize,
+    rcap: usize,
+    wbuf: Box<[u8]>,
+    wpos: usize,
+    inner: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TFramedTransport {
+    /// Create a `TFramedTransport` with default-sized internal read and
+    /// write buffers that wraps an `inner` `TTransport`.
+    pub fn new(inner: Rc<RefCell<Box<TTransport>>>) -> TFramedTransport {
+        TFramedTransport::with_capacity(WRITE_BUFFER_CAPACITY, DEFAULT_WBUFFER_CAPACITY, inner)
+    }
+
+    /// Create a `TFramedTransport` with an internal read buffer of size
+    /// `read_buffer_capacity` and an internal write buffer of size
+    /// `write_buffer_capacity` that wraps an `inner` `TTransport`.
+    pub fn with_capacity(read_buffer_capacity: usize,
+                         write_buffer_capacity: usize,
+                         inner: Rc<RefCell<Box<TTransport>>>)
+                         -> TFramedTransport {
+        TFramedTransport {
+            rbuf: vec![0; read_buffer_capacity].into_boxed_slice(),
+            rpos: 0,
+            rcap: 0,
+            wbuf: vec![0; write_buffer_capacity].into_boxed_slice(),
+            wpos: 0,
+            inner: inner,
+        }
+    }
+}
+
+impl Read for TFramedTransport {
+    fn read(&mut self, b: &mut [u8]) -> io::Result<usize> {
+        if self.rcap - self.rpos == 0 {
+            let message_size = self.inner.borrow_mut().read_i32::<BigEndian>()? as usize;
+            if message_size > self.rbuf.len() {
+                return Err(io::Error::new(ErrorKind::Other,
+                                          format!("bytes to be read ({}) exceeds buffer \
+                                                   capacity ({})",
+                                                  message_size,
+                                                  self.rbuf.len())));
+            }
+            self.inner.borrow_mut().read_exact(&mut self.rbuf[..message_size])?;
+            self.rpos = 0;
+            self.rcap = message_size as usize;
+        }
+
+        let nread = cmp::min(b.len(), self.rcap - self.rpos);
+        b[..nread].clone_from_slice(&self.rbuf[self.rpos..self.rpos + nread]);
+        self.rpos += nread;
+
+        Ok(nread)
+    }
+}
+
+impl Write for TFramedTransport {
+    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
+        if b.len() > (self.wbuf.len() - self.wpos) {
+            return Err(io::Error::new(ErrorKind::Other,
+                                      format!("bytes to be written ({}) exceeds buffer \
+                                               capacity ({})",
+                                              b.len(),
+                                              self.wbuf.len() - self.wpos)));
+        }
+
+        let nwrite = b.len(); // always less than available write buffer capacity
+        self.wbuf[self.wpos..(self.wpos + nwrite)].clone_from_slice(b);
+        self.wpos += nwrite;
+        Ok(nwrite)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        let message_size = self.wpos;
+
+        if let 0 = message_size {
+            return Ok(());
+        } else {
+            self.inner.borrow_mut().write_i32::<BigEndian>(message_size as i32)?;
+        }
+
+        let mut byte_index = 0;
+        while byte_index < self.wpos {
+            let nwrite = self.inner.borrow_mut().write(&self.wbuf[byte_index..self.wpos])?;
+            byte_index = cmp::min(byte_index + nwrite, self.wpos);
+        }
+
+        self.wpos = 0;
+        self.inner.borrow_mut().flush()
+    }
+}
+
+/// Factory for creating instances of `TFramedTransport`.
+#[derive(Default)]
+pub struct TFramedTransportFactory;
+
+impl TFramedTransportFactory {
+    // Create a `TFramedTransportFactory`.
+    pub fn new() -> TFramedTransportFactory {
+        TFramedTransportFactory {}
+    }
+}
+
+impl TTransportFactory for TFramedTransportFactory {
+    fn create(&self, inner: Rc<RefCell<Box<TTransport>>>) -> Box<TTransport> {
+        Box::new(TFramedTransport::new(inner)) as Box<TTransport>
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    //    use std::io::{Read, Write};
+    //
+    //    use super::*;
+    //    use ::transport::mem::TBufferTransport;
+}
diff --git a/lib/rs/src/transport/mem.rs b/lib/rs/src/transport/mem.rs
new file mode 100644
index 0000000..8ec2a98
--- /dev/null
+++ b/lib/rs/src/transport/mem.rs
@@ -0,0 +1,342 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::cmp;
+use std::io;
+
+/// Simple transport that contains both a fixed-length internal read buffer and
+/// a fixed-length internal write buffer.
+///
+/// On a `write` bytes are written to the internal write buffer. Writes are no
+/// longer accepted once this buffer is full. Callers must `empty_write_buffer()`
+/// before subsequent writes are accepted.
+///
+/// You can set readable bytes in the internal read buffer by filling it with
+/// `set_readable_bytes(...)`. Callers can then read until the buffer is
+/// depleted. No further reads are accepted until the internal read buffer is
+/// replenished again.
+pub struct TBufferTransport {
+    rbuf: Box<[u8]>,
+    rpos: usize,
+    ridx: usize,
+    rcap: usize,
+    wbuf: Box<[u8]>,
+    wpos: usize,
+    wcap: usize,
+}
+
+impl TBufferTransport {
+    /// Constructs a new, empty `TBufferTransport` with the given
+    /// read buffer capacity and write buffer capacity.
+    pub fn with_capacity(read_buffer_capacity: usize,
+                         write_buffer_capacity: usize)
+                         -> TBufferTransport {
+        TBufferTransport {
+            rbuf: vec![0; read_buffer_capacity].into_boxed_slice(),
+            ridx: 0,
+            rpos: 0,
+            rcap: read_buffer_capacity,
+            wbuf: vec![0; write_buffer_capacity].into_boxed_slice(),
+            wpos: 0,
+            wcap: write_buffer_capacity,
+        }
+    }
+
+    /// Return a slice containing the bytes held by the internal read buffer.
+    /// Returns an empty slice if no readable bytes are present.
+    pub fn read_buffer(&self) -> &[u8] {
+        &self.rbuf[..self.ridx]
+    }
+
+    // FIXME: do I really need this API call?
+    // FIXME: should this simply reset to the last set of readable bytes?
+    /// Reset the number of readable bytes to zero.
+    ///
+    /// Subsequent calls to `read` will return nothing.
+    pub fn empty_read_buffer(&mut self) {
+        self.rpos = 0;
+        self.ridx = 0;
+    }
+
+    /// Copy bytes from the source buffer `buf` into the internal read buffer,
+    /// overwriting any existing bytes. Returns the number of bytes copied,
+    /// which is `min(buf.len(), internal_read_buf.len())`.
+    pub fn set_readable_bytes(&mut self, buf: &[u8]) -> usize {
+        self.empty_read_buffer();
+        let max_bytes = cmp::min(self.rcap, buf.len());
+        self.rbuf[..max_bytes].clone_from_slice(&buf[..max_bytes]);
+        self.ridx = max_bytes;
+        max_bytes
+    }
+
+    /// Return a slice containing the bytes held by the internal write buffer.
+    /// Returns an empty slice if no bytes were written.
+    pub fn write_buffer_as_ref(&self) -> &[u8] {
+        &self.wbuf[..self.wpos]
+    }
+
+    /// Return a vector with a copy of the bytes held by the internal write buffer.
+    /// Returns an empty vector if no bytes were written.
+    pub fn write_buffer_to_vec(&self) -> Vec<u8> {
+        let mut buf = vec![0u8; self.wpos];
+        buf.copy_from_slice(&self.wbuf[..self.wpos]);
+        buf
+    }
+
+    /// Resets the internal write buffer, making it seem like no bytes were
+    /// written. Calling `write_buffer` after this returns an empty slice.
+    pub fn empty_write_buffer(&mut self) {
+        self.wpos = 0;
+    }
+
+    /// Overwrites the contents of the read buffer with the contents of the
+    /// write buffer. The write buffer is emptied after this operation.
+    pub fn copy_write_buffer_to_read_buffer(&mut self) {
+        let buf = {
+            let b = self.write_buffer_as_ref();
+            let mut b_ret = vec![0; b.len()];
+            b_ret.copy_from_slice(&b);
+            b_ret
+        };
+
+        let bytes_copied = self.set_readable_bytes(&buf);
+        assert_eq!(bytes_copied, buf.len());
+
+        self.empty_write_buffer();
+    }
+}
+
+impl io::Read for TBufferTransport {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let nread = cmp::min(buf.len(), self.ridx - self.rpos);
+        buf[..nread].clone_from_slice(&self.rbuf[self.rpos..self.rpos + nread]);
+        self.rpos += nread;
+        Ok(nread)
+    }
+}
+
+impl io::Write for TBufferTransport {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        let nwrite = cmp::min(buf.len(), self.wcap - self.wpos);
+        self.wbuf[self.wpos..self.wpos + nwrite].clone_from_slice(&buf[..nwrite]);
+        self.wpos += nwrite;
+        Ok(nwrite)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(()) // nothing to do on flush
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io::{Read, Write};
+
+    use super::TBufferTransport;
+
+    #[test]
+    fn must_empty_write_buffer() {
+        let mut t = TBufferTransport::with_capacity(0, 1);
+
+        let bytes_to_write: [u8; 1] = [0x01];
+        let result = t.write(&bytes_to_write);
+        assert_eq!(result.unwrap(), 1);
+        assert_eq!(&t.write_buffer_as_ref(), &bytes_to_write);
+
+        t.empty_write_buffer();
+        assert_eq!(t.write_buffer_as_ref().len(), 0);
+    }
+
+    #[test]
+    fn must_accept_writes_after_buffer_emptied() {
+        let mut t = TBufferTransport::with_capacity(0, 2);
+
+        let bytes_to_write: [u8; 2] = [0x01, 0x02];
+
+        // first write (all bytes written)
+        let result = t.write(&bytes_to_write);
+        assert_eq!(result.unwrap(), 2);
+        assert_eq!(&t.write_buffer_as_ref(), &bytes_to_write);
+
+        // try write again (nothing should be written)
+        let result = t.write(&bytes_to_write);
+        assert_eq!(result.unwrap(), 0);
+        assert_eq!(&t.write_buffer_as_ref(), &bytes_to_write); // still the same as before
+
+        // now reset the buffer
+        t.empty_write_buffer();
+        assert_eq!(t.write_buffer_as_ref().len(), 0);
+
+        // now try write again - the write should succeed
+        let result = t.write(&bytes_to_write);
+        assert_eq!(result.unwrap(), 2);
+        assert_eq!(&t.write_buffer_as_ref(), &bytes_to_write);
+    }
+
+    #[test]
+    fn must_accept_multiple_writes_until_buffer_is_full() {
+        let mut t = TBufferTransport::with_capacity(0, 10);
+
+        // first write (all bytes written)
+        let bytes_to_write_0: [u8; 2] = [0x01, 0x41];
+        let write_0_result = t.write(&bytes_to_write_0);
+        assert_eq!(write_0_result.unwrap(), 2);
+        assert_eq!(t.write_buffer_as_ref(), &bytes_to_write_0);
+
+        // second write (all bytes written, starting at index 2)
+        let bytes_to_write_1: [u8; 7] = [0x24, 0x41, 0x32, 0x33, 0x11, 0x98, 0xAF];
+        let write_1_result = t.write(&bytes_to_write_1);
+        assert_eq!(write_1_result.unwrap(), 7);
+        assert_eq!(&t.write_buffer_as_ref()[2..], &bytes_to_write_1);
+
+        // third write (only 1 byte written - that's all we have space for)
+        let bytes_to_write_2: [u8; 3] = [0xBF, 0xDA, 0x98];
+        let write_2_result = t.write(&bytes_to_write_2);
+        assert_eq!(write_2_result.unwrap(), 1);
+        assert_eq!(&t.write_buffer_as_ref()[9..], &bytes_to_write_2[0..1]); // how does this syntax work?!
+
+        // fourth write (no writes are accepted)
+        let bytes_to_write_3: [u8; 3] = [0xBF, 0xAA, 0xFD];
+        let write_3_result = t.write(&bytes_to_write_3);
+        assert_eq!(write_3_result.unwrap(), 0);
+
+        // check the full write buffer
+        let mut expected: Vec<u8> = Vec::with_capacity(10);
+        expected.extend_from_slice(&bytes_to_write_0);
+        expected.extend_from_slice(&bytes_to_write_1);
+        expected.extend_from_slice(&bytes_to_write_2[0..1]);
+        assert_eq!(t.write_buffer_as_ref(), &expected[..]);
+    }
+
+    #[test]
+    fn must_empty_read_buffer() {
+        let mut t = TBufferTransport::with_capacity(1, 0);
+
+        let bytes_to_read: [u8; 1] = [0x01];
+        let result = t.set_readable_bytes(&bytes_to_read);
+        assert_eq!(result, 1);
+        assert_eq!(&t.read_buffer(), &bytes_to_read);
+
+        t.empty_read_buffer();
+        assert_eq!(t.read_buffer().len(), 0);
+    }
+
+    #[test]
+    fn must_allow_readable_bytes_to_be_set_after_read_buffer_emptied() {
+        let mut t = TBufferTransport::with_capacity(1, 0);
+
+        let bytes_to_read_0: [u8; 1] = [0x01];
+        let result = t.set_readable_bytes(&bytes_to_read_0);
+        assert_eq!(result, 1);
+        assert_eq!(&t.read_buffer(), &bytes_to_read_0);
+
+        t.empty_read_buffer();
+        assert_eq!(t.read_buffer().len(), 0);
+
+        let bytes_to_read_1: [u8; 1] = [0x02];
+        let result = t.set_readable_bytes(&bytes_to_read_1);
+        assert_eq!(result, 1);
+        assert_eq!(&t.read_buffer(), &bytes_to_read_1);
+    }
+
+    #[test]
+    fn must_accept_multiple_reads_until_all_bytes_read() {
+        let mut t = TBufferTransport::with_capacity(10, 0);
+
+        let readable_bytes: [u8; 10] = [0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0x00, 0x1A, 0x2B, 0x3C, 0x4D];
+
+        // check that we're able to set the bytes to be read
+        let result = t.set_readable_bytes(&readable_bytes);
+        assert_eq!(result, 10);
+        assert_eq!(&t.read_buffer(), &readable_bytes);
+
+        // first read
+        let mut read_buf_0 = vec![0; 5];
+        let read_result = t.read(&mut read_buf_0);
+        assert_eq!(read_result.unwrap(), 5);
+        assert_eq!(read_buf_0.as_slice(), &(readable_bytes[0..5]));
+
+        // second read
+        let mut read_buf_1 = vec![0; 4];
+        let read_result = t.read(&mut read_buf_1);
+        assert_eq!(read_result.unwrap(), 4);
+        assert_eq!(read_buf_1.as_slice(), &(readable_bytes[5..9]));
+
+        // third read (only 1 byte remains to be read)
+        let mut read_buf_2 = vec![0; 3];
+        let read_result = t.read(&mut read_buf_2);
+        assert_eq!(read_result.unwrap(), 1);
+        read_buf_2.truncate(1); // FIXME: does the caller have to do this?
+        assert_eq!(read_buf_2.as_slice(), &(readable_bytes[9..]));
+
+        // fourth read (nothing should be readable)
+        let mut read_buf_3 = vec![0; 10];
+        let read_result = t.read(&mut read_buf_3);
+        assert_eq!(read_result.unwrap(), 0);
+        read_buf_3.truncate(0);
+
+        // check that all the bytes we received match the original (again!)
+        let mut bytes_read = Vec::with_capacity(10);
+        bytes_read.extend_from_slice(&read_buf_0);
+        bytes_read.extend_from_slice(&read_buf_1);
+        bytes_read.extend_from_slice(&read_buf_2);
+        bytes_read.extend_from_slice(&read_buf_3);
+        assert_eq!(&bytes_read, &readable_bytes);
+    }
+
+    #[test]
+    fn must_allow_reads_to_succeed_after_read_buffer_replenished() {
+        let mut t = TBufferTransport::with_capacity(3, 0);
+
+        let readable_bytes_0: [u8; 3] = [0x02, 0xAB, 0x33];
+
+        // check that we're able to set the bytes to be read
+        let result = t.set_readable_bytes(&readable_bytes_0);
+        assert_eq!(result, 3);
+        assert_eq!(&t.read_buffer(), &readable_bytes_0);
+
+        let mut read_buf = vec![0; 4];
+
+        // drain the read buffer
+        let read_result = t.read(&mut read_buf);
+        assert_eq!(read_result.unwrap(), 3);
+        assert_eq!(t.read_buffer(), &read_buf[0..3]);
+
+        // check that a subsequent read fails
+        let read_result = t.read(&mut read_buf);
+        assert_eq!(read_result.unwrap(), 0);
+
+        // we don't modify the read buffer on failure
+        let mut expected_bytes = Vec::with_capacity(4);
+        expected_bytes.extend_from_slice(&readable_bytes_0);
+        expected_bytes.push(0x00);
+        assert_eq!(&read_buf, &expected_bytes);
+
+        // replenish the read buffer again
+        let readable_bytes_1: [u8; 2] = [0x91, 0xAA];
+
+        // check that we're able to set the bytes to be read
+        let result = t.set_readable_bytes(&readable_bytes_1);
+        assert_eq!(result, 2);
+        assert_eq!(&t.read_buffer(), &readable_bytes_1);
+
+        // read again
+        let read_result = t.read(&mut read_buf);
+        assert_eq!(read_result.unwrap(), 2);
+        assert_eq!(t.read_buffer(), &read_buf[0..2]);
+    }
+}
diff --git a/lib/rs/src/transport/mod.rs b/lib/rs/src/transport/mod.rs
new file mode 100644
index 0000000..bbabd66
--- /dev/null
+++ b/lib/rs/src/transport/mod.rs
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+//! Types required to send and receive bytes over an I/O channel.
+//!
+//! The core type is the `TTransport` trait, through which a `TProtocol` can
+//! send and receive primitives over the wire. While `TProtocol` instances deal
+//! with primitive types, `TTransport` instances understand only bytes.
+
+use std::cell::RefCell;
+use std::io;
+use std::rc::Rc;
+
+mod buffered;
+mod framed;
+mod passthru;
+mod socket;
+
+#[cfg(test)]
+pub mod mem;
+
+pub use self::buffered::{TBufferedTransport, TBufferedTransportFactory};
+pub use self::framed::{TFramedTransport, TFramedTransportFactory};
+pub use self::passthru::TPassThruTransport;
+pub use self::socket::TTcpTransport;
+
+/// Identifies an I/O channel that can be used to send and receive bytes.
+pub trait TTransport: io::Read + io::Write {}
+impl<I: io::Read + io::Write> TTransport for I {}
+
+/// Helper type used by servers to create `TTransport` instances for accepted
+/// client connections.
+pub trait TTransportFactory {
+    /// Create a `TTransport` that wraps an `inner` transport, thus creating
+    /// a transport stack.
+    fn create(&self, inner: Rc<RefCell<Box<TTransport>>>) -> Box<TTransport>;
+}
diff --git a/lib/rs/src/transport/passthru.rs b/lib/rs/src/transport/passthru.rs
new file mode 100644
index 0000000..60dc3a6
--- /dev/null
+++ b/lib/rs/src/transport/passthru.rs
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::io;
+use std::io::{Read, Write};
+
+use super::TTransport;
+
+/// Proxy that wraps an inner `TTransport` and delegates all calls to it.
+///
+/// Unlike other `TTransport` wrappers, `TPassThruTransport` is generic with
+/// regards to the wrapped transport. This allows callers to use methods
+/// specific to the type being wrapped instead of being constrained to methods
+/// on the `TTransport` trait.
+///
+/// # Examples
+///
+/// Create and use a `TPassThruTransport`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::transport::{TPassThruTransport, TTcpTransport};
+///
+/// let t = TTcpTransport::new();
+/// let t = TPassThruTransport::new(Rc::new(RefCell::new(Box::new(t))));
+///
+/// // since the type parameter is maintained, we are able
+/// // to use functions specific to `TTcpTransport`
+/// t.inner.borrow_mut().open("localhost:9090").unwrap();
+/// ```
+pub struct TPassThruTransport<I: TTransport> {
+    pub inner: Rc<RefCell<Box<I>>>,
+}
+
+impl<I: TTransport> TPassThruTransport<I> {
+    /// Create a `TPassThruTransport` that wraps an `inner` TTransport.
+    pub fn new(inner: Rc<RefCell<Box<I>>>) -> TPassThruTransport<I> {
+        TPassThruTransport { inner: inner }
+    }
+}
+
+impl<I: TTransport> Read for TPassThruTransport<I> {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.inner.borrow_mut().read(buf)
+    }
+}
+
+impl<I: TTransport> Write for TPassThruTransport<I> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.borrow_mut().write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.inner.borrow_mut().flush()
+    }
+}
diff --git a/lib/rs/src/transport/socket.rs b/lib/rs/src/transport/socket.rs
new file mode 100644
index 0000000..9f2b8ba
--- /dev/null
+++ b/lib/rs/src/transport/socket.rs
@@ -0,0 +1,141 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::convert::From;
+use std::io;
+use std::io::{ErrorKind, Read, Write};
+use std::net::{Shutdown, TcpStream};
+use std::ops::Drop;
+
+use ::{TransportError, TransportErrorKind};
+
+/// Communicate with a Thrift service over a TCP socket.
+///
+/// # Examples
+///
+/// Create a `TTcpTransport`.
+///
+/// ```no_run
+/// use std::io::{Read, Write};
+/// use thrift::transport::TTcpTransport;
+///
+/// let mut t = TTcpTransport::new();
+/// t.open("localhost:9090").unwrap();
+///
+/// let mut buf = vec![0u8; 4];
+/// t.read(&mut buf).unwrap();
+/// t.write(&vec![0, 1, 2]).unwrap();
+/// ```
+///
+/// Create a `TTcpTransport` by wrapping an existing `TcpStream`.
+///
+/// ```no_run
+/// use std::io::{Read, Write};
+/// use std::net::TcpStream;
+/// use thrift::transport::TTcpTransport;
+///
+/// let stream = TcpStream::connect("127.0.0.1:9189").unwrap();
+/// let mut t = TTcpTransport::with_stream(stream);
+///
+/// // no need to call t.open() since we've already connected above
+///
+/// let mut buf = vec![0u8; 4];
+/// t.read(&mut buf).unwrap();
+/// t.write(&vec![0, 1, 2]).unwrap();
+/// ```
+#[derive(Default)]
+pub struct TTcpTransport {
+    stream: Option<TcpStream>,
+}
+
+impl TTcpTransport {
+    /// Create an uninitialized `TTcpTransport`.
+    ///
+    /// The returned instance must be opened using `TTcpTransport::open(...)`
+    /// before it can be used.
+    pub fn new() -> TTcpTransport {
+        TTcpTransport { stream: None }
+    }
+
+    /// Create a `TTcpTransport` that wraps an existing `TcpStream`.
+    ///
+    /// The passed-in stream is assumed to have been opened before being wrapped
+    /// by the created `TTcpTransport` instance.
+    pub fn with_stream(stream: TcpStream) -> TTcpTransport {
+        TTcpTransport { stream: Some(stream) }
+    }
+
+    /// Connect to `remote_address`, which should have the form `host:port`.
+    pub fn open(&mut self, remote_address: &str) -> ::Result<()> {
+        if self.stream.is_some() {
+            Err(::Error::Transport(TransportError::new(TransportErrorKind::AlreadyOpen,
+                                                       "transport previously opened")))
+        } else {
+            match TcpStream::connect(&remote_address) {
+                Ok(s) => {
+                    self.stream = Some(s);
+                    Ok(())
+                }
+                Err(e) => Err(From::from(e)),
+            }
+        }
+    }
+
+    /// Shutdown this transport.
+    ///
+    /// Both send and receive halves are closed, and this instance can no
+    /// longer be used to communicate with another endpoint.
+    pub fn close(&mut self) -> ::Result<()> {
+        self.if_set(|s| s.shutdown(Shutdown::Both)).map_err(From::from)
+    }
+
+    fn if_set<F, T>(&mut self, mut stream_operation: F) -> io::Result<T>
+        where F: FnMut(&mut TcpStream) -> io::Result<T>
+    {
+
+        if let Some(ref mut s) = self.stream {
+            stream_operation(s)
+        } else {
+            Err(io::Error::new(ErrorKind::NotConnected, "tcp endpoint not connected"))
+        }
+    }
+}
+
+impl Read for TTcpTransport {
+    fn read(&mut self, b: &mut [u8]) -> io::Result<usize> {
+        self.if_set(|s| s.read(b))
+    }
+}
+
+impl Write for TTcpTransport {
+    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
+        self.if_set(|s| s.write(b))
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.if_set(|s| s.flush())
+    }
+}
+
+// Do I have to implement the Drop trait? TcpStream closes the socket on drop.
+impl Drop for TTcpTransport {
+    fn drop(&mut self) {
+        if let Err(e) = self.close() {
+            warn!("error while closing socket transport: {:?}", e)
+        }
+    }
+}
