Upgrading vendor folder dependencies.

This commit is contained in:
Renan DelValle 2018-12-27 09:58:53 -08:00
parent 4a0cbcd770
commit acbe9ad9e5
No known key found for this signature in database
GPG key ID: C240AD6D6F443EC9
229 changed files with 10735 additions and 4528 deletions

View file

@ -1,7 +1,7 @@
[package]
name = "thrift"
description = "Rust bindings for the Apache Thrift RPC system"
version = "1.0.0"
version = "0.12.0"
license = "Apache-2.0"
authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
homepage = "http://thrift.apache.org"

View file

@ -37,6 +37,57 @@ Thrift compiler you're using.
Full [Rustdoc](https://docs.rs/thrift/)
## Compatibility
The Rust library and auto-generated code targets Rust versions 1.28+.
It does not currently use any Rust 2018 features.
### Breaking Changes
Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.
##### Thrift 0.12.0
* **[THRIFT-4529]** - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
Previously, enum variants were uppercased in the auto-generated code.
For example, the following thrift enum:
```thrift
// THRIFT
enum Operation {
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE,
}
```
used to generate:
```rust
// OLD AUTO-GENERATED RUST
pub enum Operation {
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE,
}
```
It *now* generates:
```rust
// NEW AUTO-GENERATED RUST
pub enum Operation {
Add,
Subtract,
Multiply,
Divide,
}
```
You will have to change all enum variants in your code to use camel-cased names.
This should be a search and replace.
## Contributing
Bug reports and PRs are always welcome! Please see the

View file

@ -198,8 +198,9 @@ 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> {
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;
@ -224,9 +225,8 @@ impl Error {
}
2 => {
let remote_type_as_int = i.read_i32()?;
let remote_kind: ApplicationErrorKind =
TryFrom::try_from(remote_type_as_int)
.unwrap_or(ApplicationErrorKind::Unknown);
let remote_kind: ApplicationErrorKind = TryFrom::try_from(remote_type_as_int)
.unwrap_or(ApplicationErrorKind::Unknown);
i.read_field_end()?;
kind = remote_kind;
}
@ -238,12 +238,10 @@ impl Error {
i.read_struct_end()?;
Ok(
ApplicationError {
kind: kind,
message: message,
},
)
Ok(ApplicationError {
kind: kind,
message: message,
})
}
/// Convert an `ApplicationError` into its wire representation and write
@ -254,7 +252,9 @@ impl Error {
e: &ApplicationError,
o: &mut TOutputProtocol,
) -> ::Result<()> {
o.write_struct_begin(&TStructIdentifier { name: "TApplicationException".to_owned() },)?;
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);
@ -309,23 +309,19 @@ impl Display for Error {
impl From<String> for Error {
fn from(s: String) -> Self {
Error::Application(
ApplicationError {
kind: ApplicationErrorKind::Unknown,
message: s,
},
)
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),
},
)
Error::Application(ApplicationError {
kind: ApplicationErrorKind::Unknown,
message: String::from(s),
})
}
}
@ -427,16 +423,10 @@ impl TryFrom<i32> for TransportErrorKind {
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),
},
),
)
}
_ => Err(Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::Unknown,
message: format!("cannot convert {} to TransportErrorKind", from),
})),
}
}
}
@ -444,47 +434,29 @@ impl TryFrom<i32> for TransportErrorKind {
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(),
},
)
}
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
},
)
Error::Transport(TransportError {
kind: TransportErrorKind::Unknown,
message: err.description().to_owned(), // FIXME: use io error's debug string
})
}
}
}
@ -492,12 +464,10 @@ impl From<io::Error> for Error {
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
},
)
Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::InvalidData,
message: err.description().to_owned(), // FIXME: use fmt::Error's debug string
})
}
}
@ -583,16 +553,10 @@ impl TryFrom<i32> for ProtocolErrorKind {
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),
},
),
)
}
_ => Err(Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::Unknown,
message: format!("cannot convert {} to ProtocolErrorKind", from),
})),
}
}
}
@ -697,16 +661,10 @@ impl TryFrom<i32> for ApplicationErrorKind {
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),
},
),
)
}
_ => Err(Error::Application(ApplicationError {
kind: ApplicationErrorKind::Unknown,
message: format!("cannot convert {} to ApplicationErrorKind", from),
})),
}
}
}

View file

@ -63,13 +63,11 @@ extern crate log;
/// 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()
}
}
($e: expr) => {{
let res = $e;
assert!(res.is_ok());
res.unwrap()
}};
}
pub mod protocol;

View file

@ -19,11 +19,13 @@ use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use std::convert::From;
use try_from::TryFrom;
use {ProtocolError, ProtocolErrorKind};
use transport::{TReadTransport, TWriteTransport};
use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
TMapIdentifier, TMessageIdentifier, TMessageType};
use super::{
TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
TMessageIdentifier, TMessageType,
};
use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
use transport::{TReadTransport, TWriteTransport};
use {ProtocolError, ProtocolErrorKind};
const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
@ -90,14 +92,10 @@ where
// 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]),
},
),
)
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()?;
@ -110,20 +108,16 @@ where
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]),
},
),
)
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);
let mut name_buf: Vec<u8> = vec![0; name_size];
self.transport.read_exact(&mut name_buf)?;
let name = String::from_utf8(name_buf)?;
@ -154,7 +148,9 @@ where
TType::Stop => Ok(0),
_ => self.read_i16(),
}?;
Ok(TFieldIdentifier::new::<Option<String>, String, i16>(None, field_type, id),)
Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
None, field_type, id,
))
}
fn read_field_end(&mut self) -> ::Result<()> {
@ -183,27 +179,19 @@ where
}
fn read_i16(&mut self) -> ::Result<i16> {
self.transport
.read_i16::<BigEndian>()
.map_err(From::from)
self.transport.read_i16::<BigEndian>().map_err(From::from)
}
fn read_i32(&mut self) -> ::Result<i32> {
self.transport
.read_i32::<BigEndian>()
.map_err(From::from)
self.transport.read_i32::<BigEndian>().map_err(From::from)
}
fn read_i64(&mut self) -> ::Result<i64> {
self.transport
.read_i64::<BigEndian>()
.map_err(From::from)
self.transport.read_i64::<BigEndian>().map_err(From::from)
}
fn read_double(&mut self) -> ::Result<f64> {
self.transport
.read_f64::<BigEndian>()
.map_err(From::from)
self.transport.read_f64::<BigEndian>().map_err(From::from)
}
fn read_string(&mut self) -> ::Result<String> {
@ -346,17 +334,13 @@ where
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
),
},
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))?;
@ -393,27 +377,19 @@ where
}
fn write_i16(&mut self, i: i16) -> ::Result<()> {
self.transport
.write_i16::<BigEndian>(i)
.map_err(From::from)
self.transport.write_i16::<BigEndian>(i).map_err(From::from)
}
fn write_i32(&mut self, i: i32) -> ::Result<()> {
self.transport
.write_i32::<BigEndian>(i)
.map_err(From::from)
self.transport.write_i32::<BigEndian>(i).map_err(From::from)
}
fn write_i64(&mut self, i: i64) -> ::Result<()> {
self.transport
.write_i64::<BigEndian>(i)
.map_err(From::from)
self.transport.write_i64::<BigEndian>(i).map_err(From::from)
}
fn write_double(&mut self, d: f64) -> ::Result<()> {
self.transport
.write_f64::<BigEndian>(d)
.map_err(From::from)
self.transport.write_f64::<BigEndian>(d).map_err(From::from)
}
fn write_string(&mut self, s: &str) -> ::Result<()> {
@ -520,36 +496,32 @@ fn field_type_from_u8(b: u8) -> ::Result<TType> {
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),
},
),
)
}
unkn => Err(::Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::InvalidData,
message: format!("cannot convert {} to TType", unkn),
})),
}
}
#[cfg(test)]
mod tests {
use protocol::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier,
TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier,
TStructIdentifier, TType};
use protocol::{
TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
};
use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
use super::*;
#[test]
fn must_write_message_call_begin() {
let (_, mut o_prot) = test_objects();
fn must_write_strict_message_call_begin() {
let (_, mut o_prot) = test_objects(true);
let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
assert!(o_prot.write_message_begin(&ident).is_ok());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 16] = [
0x80,
0x01,
@ -573,12 +545,40 @@ mod tests {
}
#[test]
fn must_write_message_reply_begin() {
let (_, mut o_prot) = test_objects();
fn must_write_non_strict_message_call_begin() {
let (_, mut o_prot) = test_objects(false);
let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
assert!(o_prot.write_message_begin(&ident).is_ok());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 13] = [
0x00,
0x00,
0x00,
0x04,
0x74,
0x65,
0x73,
0x74,
0x01,
0x00,
0x00,
0x00,
0x01,
];
assert_eq_written_bytes!(o_prot, expected);
}
#[test]
fn must_write_strict_message_reply_begin() {
let (_, mut o_prot) = test_objects(true);
let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
assert!(o_prot.write_message_begin(&ident).is_ok());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 16] = [
0x80,
0x01,
@ -601,9 +601,49 @@ mod tests {
assert_eq_written_bytes!(o_prot, expected);
}
#[test]
fn must_write_non_strict_message_reply_begin() {
let (_, mut o_prot) = test_objects(false);
let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
assert!(o_prot.write_message_begin(&ident).is_ok());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 13] = [
0x00,
0x00,
0x00,
0x04,
0x74,
0x65,
0x73,
0x74,
0x02,
0x00,
0x00,
0x00,
0x0A,
];
assert_eq_written_bytes!(o_prot, expected);
}
#[test]
fn must_round_trip_strict_message_begin() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
assert!(o_prot.write_message_begin(&sent_ident).is_ok());
copy_write_buffer_to_read_buffer!(o_prot);
let received_ident = assert_success!(i_prot.read_message_begin());
assert_eq!(&received_ident, &sent_ident);
}
#[test]
fn must_round_trip_non_strict_message_begin() {
let (mut i_prot, mut o_prot) = test_objects(false);
let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
assert!(o_prot.write_message_begin(&sent_ident).is_ok());
@ -616,28 +656,29 @@ mod tests {
#[test]
fn must_write_message_end() {
assert_no_write(|o| o.write_message_end());
assert_no_write(|o| o.write_message_end(), true);
}
#[test]
fn must_write_struct_begin() {
assert_no_write(|o| o.write_struct_begin(&TStructIdentifier::new("foo")));
assert_no_write(
|o| o.write_struct_begin(&TStructIdentifier::new("foo")),
true,
);
}
#[test]
fn must_write_struct_end() {
assert_no_write(|o| o.write_struct_end());
assert_no_write(|o| o.write_struct_end(), true);
}
#[test]
fn must_write_field_begin() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(
o_prot
.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
.is_ok()
);
assert!(o_prot
.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
.is_ok());
let expected: [u8; 3] = [0x0B, 0x00, 0x16];
assert_eq_written_bytes!(o_prot, expected);
@ -645,7 +686,7 @@ mod tests {
#[test]
fn must_round_trip_field_begin() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
@ -663,7 +704,7 @@ mod tests {
#[test]
fn must_write_stop_field() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(o_prot.write_field_stop().is_ok());
@ -673,7 +714,7 @@ mod tests {
#[test]
fn must_round_trip_field_stop() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
assert!(o_prot.write_field_stop().is_ok());
@ -691,18 +732,16 @@ mod tests {
#[test]
fn must_write_field_end() {
assert_no_write(|o| o.write_field_end());
assert_no_write(|o| o.write_field_end(), true);
}
#[test]
fn must_write_list_begin() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(
o_prot
.write_list_begin(&TListIdentifier::new(TType::Bool, 5))
.is_ok()
);
assert!(o_prot
.write_list_begin(&TListIdentifier::new(TType::Bool, 5))
.is_ok());
let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
assert_eq_written_bytes!(o_prot, expected);
@ -710,7 +749,7 @@ mod tests {
#[test]
fn must_round_trip_list_begin() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
let ident = TListIdentifier::new(TType::List, 900);
assert!(o_prot.write_list_begin(&ident).is_ok());
@ -723,18 +762,16 @@ mod tests {
#[test]
fn must_write_list_end() {
assert_no_write(|o| o.write_list_end());
assert_no_write(|o| o.write_list_end(), true);
}
#[test]
fn must_write_set_begin() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(
o_prot
.write_set_begin(&TSetIdentifier::new(TType::I16, 7))
.is_ok()
);
assert!(o_prot
.write_set_begin(&TSetIdentifier::new(TType::I16, 7))
.is_ok());
let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
assert_eq_written_bytes!(o_prot, expected);
@ -742,7 +779,7 @@ mod tests {
#[test]
fn must_round_trip_set_begin() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
let ident = TSetIdentifier::new(TType::I64, 2000);
assert!(o_prot.write_set_begin(&ident).is_ok());
@ -756,18 +793,16 @@ mod tests {
#[test]
fn must_write_set_end() {
assert_no_write(|o| o.write_set_end());
assert_no_write(|o| o.write_set_end(), true);
}
#[test]
fn must_write_map_begin() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(
o_prot
.write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
.is_ok()
);
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];
assert_eq_written_bytes!(o_prot, expected);
@ -775,7 +810,7 @@ mod tests {
#[test]
fn must_round_trip_map_begin() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
assert!(o_prot.write_map_begin(&ident).is_ok());
@ -788,12 +823,12 @@ mod tests {
#[test]
fn must_write_map_end() {
assert_no_write(|o| o.write_map_end());
assert_no_write(|o| o.write_map_end(), true);
}
#[test]
fn must_write_bool_true() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(o_prot.write_bool(true).is_ok());
@ -803,7 +838,7 @@ mod tests {
#[test]
fn must_write_bool_false() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
assert!(o_prot.write_bool(false).is_ok());
@ -813,7 +848,7 @@ mod tests {
#[test]
fn must_read_bool_true() {
let (mut i_prot, _) = test_objects();
let (mut i_prot, _) = test_objects(true);
set_readable_bytes!(i_prot, &[0x01]);
@ -823,7 +858,7 @@ mod tests {
#[test]
fn must_read_bool_false() {
let (mut i_prot, _) = test_objects();
let (mut i_prot, _) = test_objects(true);
set_readable_bytes!(i_prot, &[0x00]);
@ -833,7 +868,7 @@ mod tests {
#[test]
fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
let (mut i_prot, _) = test_objects();
let (mut i_prot, _) = test_objects(true);
set_readable_bytes!(i_prot, &[0xAC]);
@ -843,7 +878,7 @@ mod tests {
#[test]
fn must_write_bytes() {
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(true);
let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
@ -856,8 +891,9 @@ mod tests {
#[test]
fn must_round_trip_bytes() {
let (mut i_prot, mut o_prot) = test_objects();
let (mut i_prot, mut o_prot) = test_objects(true);
#[cfg_attr(rustfmt, rustfmt::skip)]
let bytes: [u8; 25] = [
0x20,
0xFD,
@ -894,25 +930,27 @@ mod tests {
assert_eq!(&received_bytes, &bytes);
}
fn test_objects()
-> (TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
TBinaryOutputProtocol<WriteHalf<TBufferChannel>>)
{
fn test_objects(
strict: bool,
) -> (
TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
) {
let mem = TBufferChannel::with_capacity(40, 40);
let (r_mem, w_mem) = mem.split().unwrap();
let i_prot = TBinaryInputProtocol::new(r_mem, true);
let o_prot = TBinaryOutputProtocol::new(w_mem, true);
let i_prot = TBinaryInputProtocol::new(r_mem, strict);
let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
(i_prot, o_prot)
}
fn assert_no_write<F>(mut write_fn: F)
fn assert_no_write<F>(mut write_fn: F, strict: bool)
where
F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
{
let (_, mut o_prot) = test_objects();
let (_, mut o_prot) = test_objects(strict);
assert!(write_fn(&mut o_prot).is_ok());
assert_eq!(o_prot.transport.write_bytes().len(), 0);
}

View file

@ -18,13 +18,15 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use integer_encoding::{VarIntReader, VarIntWriter};
use std::convert::From;
use try_from::TryFrom;
use std::io;
use try_from::TryFrom;
use transport::{TReadTransport, TWriteTransport};
use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
TMapIdentifier, TMessageIdentifier, TMessageType};
use super::{
TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
TMessageIdentifier, TMessageType,
};
use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
use transport::{TReadTransport, TWriteTransport};
const COMPACT_PROTOCOL_ID: u8 = 0x82;
const COMPACT_VERSION: u8 = 0x01;
@ -103,14 +105,10 @@ where
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),
},
),
)
Err(::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::BadVersion,
message: format!("invalid compact protocol header {:?}", compact_id),
}))
} else {
Ok(())
}?;
@ -118,17 +116,13 @@ where
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
),
},
Err(::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::BadVersion,
message: format!(
"cannot process compact protocol version {:?}",
received_version
),
)
}))
} else {
Ok(())
}?;
@ -140,7 +134,11 @@ where
self.last_read_field_id = 0;
Ok(TMessageIdentifier::new(service_call_name, message_type, sequence_number),)
Ok(TMessageIdentifier::new(
service_call_name,
message_type,
sequence_number,
))
}
fn read_message_end(&mut self) -> ::Result<()> {
@ -154,7 +152,8 @@ where
}
fn read_struct_end(&mut self) -> ::Result<()> {
self.last_read_field_id = self.read_field_id_stack
self.last_read_field_id = self
.read_field_id_stack
.pop()
.expect("should have previous field ids");
Ok(())
@ -179,15 +178,13 @@ where
}?;
match field_type {
TType::Stop => {
Ok(
TFieldIdentifier::new::<Option<String>, String, Option<i16>>(
None,
TType::Stop,
None,
),
)
}
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;
@ -195,13 +192,11 @@ where
self.last_read_field_id = self.read_i16()?;
};
Ok(
TFieldIdentifier {
name: None,
field_type: field_type,
id: Some(self.last_read_field_id),
},
)
Ok(TFieldIdentifier {
name: None,
field_type: field_type,
id: Some(self.last_read_field_id),
})
}
}
}
@ -218,16 +213,10 @@ where
match b {
0x01 => Ok(true),
0x02 => Ok(false),
unkn => {
Err(
::Error::Protocol(
::ProtocolError {
kind: ::ProtocolErrorKind::InvalidData,
message: format!("cannot convert {} into bool", unkn),
},
),
)
}
unkn => Err(::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::InvalidData,
message: format!("cannot convert {} into bool", unkn),
})),
}
}
}
@ -259,9 +248,7 @@ where
}
fn read_double(&mut self) -> ::Result<f64> {
self.transport
.read_f64::<BigEndian>()
.map_err(From::from)
self.transport.read_f64::<BigEndian>().map_err(From::from)
}
fn read_string(&mut self) -> ::Result<String> {
@ -315,7 +302,6 @@ where
}
}
impl<T> io::Seek for TCompactInputProtocol<T>
where
T: io::Seek + TReadTransport,
@ -450,7 +436,8 @@ where
fn write_struct_end(&mut self) -> ::Result<()> {
self.assert_no_pending_bool_write();
self.last_write_field_id = self.write_field_id_stack
self.last_write_field_id = self
.write_field_id_stack
.pop()
.expect("should have previous field ids");
Ok(())
@ -462,7 +449,7 @@ where
if self.pending_write_bool_field_identifier.is_some() {
panic!(
"should not have a pending bool while writing another bool with id: \
{:?}",
{:?}",
identifier
)
}
@ -471,9 +458,7 @@ where
}
_ => {
let field_type = type_to_u8(identifier.field_type);
let field_id = identifier
.id
.expect("non-stop field should have field id");
let field_id = identifier.id.expect("non-stop field should have field id");
self.write_field_header(field_type, field_id)
}
}
@ -537,9 +522,7 @@ where
}
fn write_double(&mut self, d: f64) -> ::Result<()> {
self.transport
.write_f64::<BigEndian>(d)
.map_err(From::from)
self.transport.write_f64::<BigEndian>(d).map_err(From::from)
}
fn write_string(&mut self, s: &str) -> ::Result<()> {
@ -595,10 +578,7 @@ where
//
fn write_byte(&mut self, b: u8) -> ::Result<()> {
self.transport
.write(&[b])
.map_err(From::from)
.map(|_| ())
self.transport.write(&[b]).map_err(From::from).map(|_| ())
}
}
@ -639,7 +619,10 @@ fn type_to_u8(field_type: TType) -> u8 {
TType::Set => 0x0A,
TType::Map => 0x0B,
TType::Struct => 0x0C,
_ => panic!(format!("should not have attempted to convert {} to u8", field_type)),
_ => panic!(format!(
"should not have attempted to convert {} to u8",
field_type
)),
}
}
@ -663,25 +646,20 @@ fn u8_to_type(b: u8) -> ::Result<TType> {
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),
},
),
)
}
unkn => Err(::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::InvalidData,
message: format!("cannot convert {} into TType", unkn),
})),
}
}
#[cfg(test)]
mod tests {
use protocol::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier,
TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier,
TStructIdentifier, TType};
use protocol::{
TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
};
use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
use super::*;
@ -690,8 +668,13 @@ mod tests {
fn must_write_message_begin_0() {
let (_, mut o_prot) = test_objects();
assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("foo", TMessageType::Call, 431)));
assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
"foo",
TMessageType::Call,
431
)));
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 8] = [
0x82, /* protocol ID */
0x21, /* message type | protocol version */
@ -710,10 +693,13 @@ mod tests {
fn must_write_message_begin_1() {
let (_, mut o_prot) = test_objects();
assert_success!(
o_prot.write_message_begin(&TMessageIdentifier::new("bar", TMessageType::Reply, 991828))
);
assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
"bar",
TMessageType::Reply,
991828
)));
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 9] = [
0x82, /* protocol ID */
0x41, /* message type | protocol version */
@ -777,6 +763,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 5] = [
0x03, /* field type */
0x00, /* first field id */
@ -891,6 +878,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 4] = [
0x15, /* field delta (1) | field type */
0x1A, /* field delta (1) | field type */
@ -1003,6 +991,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 8] = [
0x05, /* field type */
0x00, /* first field id */
@ -1126,6 +1115,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 10] = [
0x16, /* field delta (1) | field type */
0x85, /* field delta (8) | field type */
@ -1290,6 +1280,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 7] = [
0x16, /* field delta (1) | field type */
0x85, /* field delta (8) | field type */
@ -1462,6 +1453,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 7] = [
0x16, /* field delta (1) | field type */
0x85, /* field delta (8) | field type */
@ -1634,6 +1626,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 7] = [
0x16, /* field delta (1) | field type */
0x08, /* field type */
@ -1803,6 +1796,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 8] = [
0x16, /* field delta (1) | field type */
0x08, /* field type */
@ -1968,6 +1962,7 @@ mod tests {
assert_success!(o_prot.write_field_stop());
assert_success!(o_prot.write_struct_end());
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 7] = [
0x11, /* field delta (1) | true */
0x82, /* field delta (8) | false */
@ -2158,8 +2153,7 @@ mod tests {
let expected: [u8; 3] = [
0xF9, /* 0xF0 | elem_type */
0x8F,
0x4E /* size as varint */,
0x8F, 0x4E, /* size as varint */
];
assert_eq_written_bytes!(o_prot, expected);
@ -2217,9 +2211,7 @@ mod tests {
let expected: [u8; 4] = [
0xF7, /* 0xF0 | elem_type */
0xD3,
0xBA,
0x01 /* size as varint */,
0xD3, 0xBA, 0x01, /* size as varint */
];
assert_eq_written_bytes!(o_prot, expected);
@ -2267,10 +2259,10 @@ mod tests {
assert_eq!(
&res,
&TMapIdentifier {
key_type: None,
value_type: None,
size: 0,
}
key_type: None,
value_type: None,
size: 0,
}
);
}
@ -2278,12 +2270,15 @@ mod tests {
fn must_write_map_begin() {
let (_, mut o_prot) = test_objects();
assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::String, 238)));
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 */,
0xEE, 0x01, /* size as varint */
0x78, /* key type | val type */
];
assert_eq_written_bytes!(o_prot, expected);
@ -2321,7 +2316,7 @@ mod tests {
0x01, /* size as varint */
0x11, /* key type | val type */
0x01, /* key: true */
0x02 /* val: false */,
0x02, /* val: false */
];
assert_eq_written_bytes!(o_prot, expected);
@ -2366,10 +2361,10 @@ mod tests {
assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
}
fn test_objects()
-> (TCompactInputProtocol<ReadHalf<TBufferChannel>>,
TCompactOutputProtocol<WriteHalf<TBufferChannel>>)
{
fn test_objects() -> (
TCompactInputProtocol<ReadHalf<TBufferChannel>>,
TCompactOutputProtocol<WriteHalf<TBufferChannel>>,
) {
let mem = TBufferChannel::with_capacity(80, 80);
let (r_mem, w_mem) = mem.split().unwrap();

View file

@ -57,38 +57,34 @@
//! protocol.write_field_end().unwrap();
//! ```
use std::convert::From;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::convert::From;
use try_from::TryFrom;
use {ProtocolError, ProtocolErrorKind};
use transport::{TReadTransport, TWriteTransport};
use {ProtocolError, ProtocolErrorKind};
#[cfg(test)]
macro_rules! assert_eq_written_bytes {
($o_prot:ident, $expected_bytes:ident) => {
{
assert_eq!($o_prot.transport.write_bytes(), &$expected_bytes);
}
};
($o_prot:ident, $expected_bytes:ident) => {{
assert_eq!($o_prot.transport.write_bytes(), &$expected_bytes);
}};
}
// FIXME: should take both read and write
#[cfg(test)]
macro_rules! copy_write_buffer_to_read_buffer {
($o_prot:ident) => {
{
$o_prot.transport.copy_write_buffer_to_read_buffer();
}
};
($o_prot:ident) => {{
$o_prot.transport.copy_write_buffer_to_read_buffer();
}};
}
#[cfg(test)]
macro_rules! set_readable_bytes {
($i_prot:ident, $bytes:expr) => {
$i_prot.transport.set_readable_bytes($bytes);
}
};
}
mod binary;
@ -96,10 +92,14 @@ 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::binary::{
TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol,
TBinaryOutputProtocolFactory,
};
pub use self::compact::{
TCompactInputProtocol, TCompactInputProtocolFactory, TCompactOutputProtocol,
TCompactOutputProtocolFactory,
};
pub use self::multiplexed::TMultiplexedOutputProtocol;
pub use self::stored::TStoredInputProtocol;
@ -186,14 +186,10 @@ pub trait TInputProtocol {
/// 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),
},
),
);
return Err(::Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::DepthLimit,
message: format!("cannot parse past {:?}", field_type),
}));
}
match field_type {
@ -243,16 +239,10 @@ pub trait TInputProtocol {
}
self.read_map_end()
}
u => {
Err(
::Error::Protocol(
ProtocolError {
kind: ProtocolErrorKind::Unknown,
message: format!("cannot skip field type {:?}", &u),
},
),
)
}
u => Err(::Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::Unknown,
message: format!("cannot skip field type {:?}", &u),
})),
}
}
@ -787,16 +777,10 @@ impl TryFrom<u8> for TMessageType {
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),
},
),
)
}
unkn => Err(::Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::InvalidData,
message: format!("cannot convert {} to TMessageType", unkn),
})),
}
}
}
@ -869,14 +853,10 @@ 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),
},
),
)
Err(::Error::Application(::ApplicationError {
kind: ::ApplicationErrorKind::BadSequenceId,
message: format!("expected {} got {}", expected, actual),
}))
}
}
@ -888,14 +868,10 @@ 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),
},
),
)
Err(::Error::Application(::ApplicationError {
kind: ::ApplicationErrorKind::WrongMethodName,
message: format!("expected {} got {}", expected, actual),
}))
}
}
@ -907,14 +883,10 @@ pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType
if expected == actual {
Ok(())
} else {
Err(
::Error::Application(
::ApplicationError {
kind: ::ApplicationErrorKind::InvalidMessageType,
message: format!("expected {} got {}", expected, actual),
},
),
)
Err(::Error::Application(::ApplicationError {
kind: ::ApplicationErrorKind::InvalidMessageType,
message: format!("expected {} got {}", expected, actual),
}))
}
}
@ -924,16 +896,10 @@ pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType
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),
},
),
)
}
None => Err(::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::Unknown,
message: format!("missing required field {}", field_name),
})),
}
}
@ -943,18 +909,12 @@ pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> :
///
/// 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),
},
)
},
)
field_ident.id.ok_or_else(|| {
::Error::Protocol(::ProtocolError {
kind: ::ProtocolErrorKind::Unknown,
message: format!("missing field in in {:?}", field_ident),
})
})
}
#[cfg(test)]

View file

@ -15,8 +15,10 @@
// specific language governing permissions and limitations
// under the License.
use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
TOutputProtocol, TSetIdentifier, TStructIdentifier};
use super::{
TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
TOutputProtocol, TSetIdentifier, TStructIdentifier,
};
/// `TOutputProtocol` that prefixes the service name to all outgoing Thrift
/// messages.
@ -81,7 +83,8 @@ where
P: TOutputProtocol,
{
fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
match identifier.message_type { // FIXME: is there a better way to override identifier here?
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),
@ -200,6 +203,7 @@ mod tests {
let ident = TMessageIdentifier::new("bar", TMessageType::Call, 2);
assert_success!(o_prot.write_message_begin(&ident));
#[cfg_attr(rustfmt, rustfmt::skip)]
let expected: [u8; 19] = [
0x80,
0x01, /* protocol identifier */
@ -225,9 +229,7 @@ mod tests {
assert_eq!(o_prot.inner.transport.write_bytes(), expected);
}
fn test_objects
()
-> TMultiplexedOutputProtocol<TBinaryOutputProtocol<WriteHalf<TBufferChannel>>>
fn test_objects() -> TMultiplexedOutputProtocol<TBinaryOutputProtocol<WriteHalf<TBufferChannel>>>
{
let c = TBufferChannel::with_capacity(40, 40);
let (_, w_chan) = c.split().unwrap();

View file

@ -17,9 +17,11 @@
use std::convert::Into;
use super::{
TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
TSetIdentifier, TStructIdentifier,
};
use ProtocolErrorKind;
use super::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
TSetIdentifier, TStructIdentifier};
/// `TInputProtocol` required to use a `TMultiplexedProcessor`.
///
@ -101,16 +103,12 @@ impl<'a> TStoredInputProtocol<'a> {
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",
)
},
self.message_ident.take().ok_or_else(|| {
::errors::new_protocol_error(
ProtocolErrorKind::Unknown,
"message identifier already read",
)
})
}
fn read_message_end(&mut self) -> ::Result<()> {

View file

@ -17,8 +17,8 @@
//! Types used to implement a Thrift server.
use {ApplicationError, ApplicationErrorKind};
use protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
use {ApplicationError, ApplicationErrorKind};
mod multiplexed;
mod threaded;

View file

@ -16,16 +16,17 @@
// under the License.
use std::collections::HashMap;
use std::convert::Into;
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::convert::Into;
use std::sync::{Arc, Mutex};
use protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol};
use super::{TProcessor, handle_process_result};
use super::{handle_process_result, TProcessor};
const MISSING_SEPARATOR_AND_NO_DEFAULT: &'static str = "missing service separator and no default processor set";
const MISSING_SEPARATOR_AND_NO_DEFAULT: &'static str =
"missing service separator and no default processor set";
type ThreadSafeProcessor = Box<TProcessor + Send + Sync>;
/// A `TProcessor` that can demux service calls to multiple underlying
@ -54,12 +55,10 @@ impl TMultiplexedProcessor {
/// processors.
pub fn new() -> TMultiplexedProcessor {
TMultiplexedProcessor {
stored: Mutex::new(
StoredProcessors {
processors: HashMap::new(),
default_processor: None,
},
),
stored: Mutex::new(StoredProcessors {
processors: HashMap::new(),
default_processor: None,
}),
}
}
@ -97,7 +96,7 @@ impl TMultiplexedProcessor {
Ok(())
}
} else {
Err(format!("cannot overwrite existing processor for service {}", name).into(),)
Err(format!("cannot overwrite existing processor for service {}", name).into())
}
}
@ -160,13 +159,11 @@ impl Debug for TMultiplexedProcessor {
fn split_ident_name(ident_name: &str) -> (Option<&str>, &str) {
ident_name
.find(':')
.map(
|pos| {
let (svc_name, svc_call) = ident_name.split_at(pos);
let (_, svc_call) = svc_call.split_at(1); // remove colon from service call name
(Some(svc_name), svc_call)
},
)
.map(|pos| {
let (svc_name, svc_call) = ident_name.split_at(pos);
let (_, svc_call) = svc_call.split_at(1); // remove colon from service call name
(Some(svc_name), svc_call)
})
.or_else(|| Some((None, ident_name)))
.unwrap()
}
@ -181,12 +178,12 @@ fn missing_processor_message(svc_name: Option<&str>) -> String {
#[cfg(test)]
mod tests {
use std::convert::Into;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use {ApplicationError, ApplicationErrorKind};
use protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType};
use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
use {ApplicationError, ApplicationErrorKind};
use super::*;
@ -219,8 +216,7 @@ mod tests {
let p = TMultiplexedProcessor::new();
p.process(&mut i, &mut o).unwrap(); // at this point an error should be written out
i.transport
.set_readable_bytes(&o.transport.write_bytes());
i.transport.set_readable_bytes(&o.transport.write_bytes());
let rcvd_ident = i.read_message_begin().unwrap();
let expected_ident = TMessageIdentifier::new("foo", TMessageType::Exception, 10);
assert_eq!(rcvd_ident, expected_ident);
@ -245,8 +241,7 @@ mod tests {
let p = TMultiplexedProcessor::new();
p.process(&mut i, &mut o).unwrap(); // at this point an error should be written out
i.transport
.set_readable_bytes(&o.transport.write_bytes());
i.transport.set_readable_bytes(&o.transport.write_bytes());
let rcvd_ident = i.read_message_begin().unwrap();
let expected_ident = TMessageIdentifier::new("missing:call", TMessageType::Exception, 10);
assert_eq!(rcvd_ident, expected_ident);
@ -265,7 +260,8 @@ mod tests {
impl TProcessor for Service {
fn process(&self, _: &mut TInputProtocol, _: &mut TOutputProtocol) -> ::Result<()> {
let res = self.invoked
let res = self
.invoked
.compare_and_swap(false, true, Ordering::Relaxed);
if res {
Ok(())
@ -280,9 +276,13 @@ mod tests {
let (mut i, mut o) = build_objects();
// build the services
let svc_1 = Service { invoked: Arc::new(AtomicBool::new(false)) };
let svc_1 = Service {
invoked: Arc::new(AtomicBool::new(false)),
};
let atm_1 = svc_1.invoked.clone();
let svc_2 = Service { invoked: Arc::new(AtomicBool::new(false)) };
let svc_2 = Service {
invoked: Arc::new(AtomicBool::new(false)),
};
let atm_2 = svc_2.invoked.clone();
// register them
@ -309,9 +309,13 @@ mod tests {
let (mut i, mut o) = build_objects();
// build the services
let svc_1 = Service { invoked: Arc::new(AtomicBool::new(false)) };
let svc_1 = Service {
invoked: Arc::new(AtomicBool::new(false)),
};
let atm_1 = svc_1.invoked.clone();
let svc_2 = Service { invoked: Arc::new(AtomicBool::new(false)) };
let svc_2 = Service {
invoked: Arc::new(AtomicBool::new(false)),
};
let atm_2 = svc_2.invoked.clone();
// register them
@ -333,12 +337,15 @@ mod tests {
assert_eq!(atm_2.load(Ordering::Relaxed), true);
}
fn build_objects()
-> (TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
TBinaryOutputProtocol<WriteHalf<TBufferChannel>>)
{
fn build_objects() -> (
TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
) {
let c = TBufferChannel::with_capacity(128, 128);
let (r_c, w_c) = c.split().unwrap();
(TBinaryInputProtocol::new(r_c, true), TBinaryOutputProtocol::new(w_c, true))
(
TBinaryInputProtocol::new(r_c, true),
TBinaryOutputProtocol::new(w_c, true),
)
}
}

View file

@ -19,9 +19,9 @@ use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use threadpool::ThreadPool;
use {ApplicationError, ApplicationErrorKind};
use protocol::{TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory};
use transport::{TIoChannel, TReadTransportFactory, TTcpChannel, TWriteTransportFactory};
use {ApplicationError, ApplicationErrorKind};
use super::TProcessor;
@ -129,11 +129,13 @@ where
}
impl<PRC, RTF, IPF, WTF, OPF> TServer<PRC, RTF, IPF, WTF, OPF>
where PRC: TProcessor + Send + Sync + 'static,
RTF: TReadTransportFactory + 'static,
IPF: TInputProtocolFactory + 'static,
WTF: TWriteTransportFactory + 'static,
OPF: TOutputProtocolFactory + 'static {
where
PRC: TProcessor + Send + Sync + 'static,
RTF: TReadTransportFactory + 'static,
IPF: TInputProtocolFactory + 'static,
WTF: TWriteTransportFactory + 'static,
OPF: TOutputProtocolFactory + 'static,
{
/// Create a `TServer`.
///
/// Each accepted connection has an input and output half, each of which
@ -155,10 +157,7 @@ impl<PRC, RTF, IPF, WTF, OPF> TServer<PRC, RTF, IPF, WTF, OPF>
w_trans_factory: write_transport_factory,
o_proto_factory: output_protocol_factory,
processor: Arc::new(processor),
worker_pool: ThreadPool::with_name(
"Thrift service processor".to_owned(),
num_workers,
),
worker_pool: ThreadPool::with_name("Thrift service processor".to_owned(), num_workers),
}
}
@ -179,7 +178,7 @@ impl<PRC, RTF, IPF, WTF, OPF> TServer<PRC, RTF, IPF, WTF, OPF>
let (i_prot, o_prot) = self.new_protocols_for_connection(s)?;
let processor = self.processor.clone();
self.worker_pool
.execute(move || handle_incoming_connection(processor, i_prot, o_prot),);
.execute(move || handle_incoming_connection(processor, i_prot, o_prot));
}
Err(e) => {
warn!("failed to accept remote connection with error {:?}", e);
@ -187,17 +186,12 @@ impl<PRC, RTF, IPF, WTF, OPF> TServer<PRC, RTF, IPF, WTF, OPF>
}
}
Err(
::Error::Application(
ApplicationError {
kind: ApplicationErrorKind::Unknown,
message: "aborted listen loop".into(),
},
),
)
Err(::Error::Application(ApplicationError {
kind: ApplicationErrorKind::Unknown,
message: "aborted listen loop".into(),
}))
}
fn new_protocols_for_connection(
&mut self,
stream: TcpStream,

View file

@ -192,7 +192,10 @@ where
/// `read_capacity` and an internal write buffer of size
/// `write_capacity` that wraps the given `TIoChannel`.
pub fn with_capacity(write_capacity: usize, channel: C) -> TBufferedWriteTransport<C> {
assert!(write_capacity > 0, "write buffer size must be a positive integer");
assert!(
write_capacity > 0,
"write buffer size must be a positive integer"
);
TBufferedWriteTransport {
buf: Vec::with_capacity(write_capacity),

View file

@ -201,8 +201,7 @@ where
if let 0 = message_size {
return Ok(());
} else {
self.channel
.write_i32::<BigEndian>(message_size as i32)?;
self.channel.write_i32::<BigEndian>(message_size as i32)?;
}
// will spin if the underlying channel can't be written to
@ -240,7 +239,7 @@ impl TWriteTransportFactory for TFramedWriteTransportFactory {
#[cfg(test)]
mod tests {
use super::*;
use ::transport::mem::TBufferChannel;
use transport::mem::TBufferChannel;
// FIXME: test a forced reserve
@ -249,12 +248,10 @@ mod tests {
let c = TBufferChannel::with_capacity(10, 10);
let mut t = TFramedReadTransport::with_capacity(8, c);
t.chan.set_readable_bytes(
&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03 /* message body */
]
);
t.chan.set_readable_bytes(&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03, /* message body */
]);
let mut buf = vec![0; 8];
@ -268,12 +265,10 @@ mod tests {
let c = TBufferChannel::with_capacity(10, 10);
let mut t = TFramedReadTransport::with_capacity(2, c);
t.chan.set_readable_bytes(
&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03 /* message body */
]
);
t.chan.set_readable_bytes(&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03, /* message body */
]);
let mut buf = vec![0; 8];
@ -291,12 +286,10 @@ mod tests {
// 1st message
//
t.chan.set_readable_bytes(
&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03 /* message body */
]
);
t.chan.set_readable_bytes(&[
0x00, 0x00, 0x00, 0x04, /* message size */
0x00, 0x01, 0x02, 0x03, /* message body */
]);
let mut buf = vec![0; 8];
@ -308,12 +301,10 @@ mod tests {
// 2nd message
//
t.chan.set_readable_bytes(
&[
0x00, 0x00, 0x00, 0x01, /* message size */
0x04 /* message body */
]
);
t.chan.set_readable_bytes(&[
0x00, 0x00, 0x00, 0x01, /* message size */
0x04, /* message body */
]);
let mut buf = vec![0; 8];
@ -356,8 +347,8 @@ mod tests {
assert!(t.flush().is_ok());
let expected_bytes = [
0x00, 0x00, 0x00, 0x05, /* message size */
0x00, 0x01, 0x02, 0x03, 0x04 /* message body */
0x00, 0x00, 0x00, 0x05, /* message size */
0x00, 0x01, 0x02, 0x03, 0x04, /* message body */
];
assert_eq_transport_written_bytes!(t, expected_bytes);
@ -382,8 +373,8 @@ mod tests {
assert!(t.flush().is_ok());
let expected_bytes = [
0x00, 0x00, 0x00, 0x03, /* message size */
0x00, 0x01, 0x02 /* message body */
0x00, 0x00, 0x00, 0x03, /* message size */
0x00, 0x01, 0x02, /* message body */
];
assert_eq_transport_written_bytes!(t, expected_bytes);
@ -408,8 +399,8 @@ mod tests {
assert!(t.flush().is_ok());
let expected_bytes = [
0x00, 0x00, 0x00, 0x03, /* message size */
0x00, 0x01, 0x02 /* message body */
0x00, 0x00, 0x00, 0x03, /* message size */
0x00, 0x01, 0x02, /* message body */
];
assert_eq_transport_written_bytes!(t, expected_bytes);

View file

@ -57,25 +57,17 @@ impl TBufferChannel {
/// read buffer capacity and write buffer capacity.
pub fn with_capacity(read_capacity: usize, write_capacity: usize) -> TBufferChannel {
TBufferChannel {
read: Arc::new(
Mutex::new(
ReadData {
buf: vec![0; read_capacity].into_boxed_slice(),
idx: 0,
pos: 0,
cap: read_capacity,
},
),
),
write: Arc::new(
Mutex::new(
WriteData {
buf: vec![0; write_capacity].into_boxed_slice(),
pos: 0,
cap: write_capacity,
},
),
),
read: Arc::new(Mutex::new(ReadData {
buf: vec![0; read_capacity].into_boxed_slice(),
idx: 0,
pos: 0,
cap: read_capacity,
})),
write: Arc::new(Mutex::new(WriteData {
buf: vec![0; write_capacity].into_boxed_slice(),
pos: 0,
cap: write_capacity,
})),
}
}
@ -151,20 +143,20 @@ impl TIoChannel for TBufferChannel {
where
Self: Sized,
{
Ok(
(ReadHalf {
handle: TBufferChannel {
read: self.read.clone(),
write: self.write.clone(),
},
},
WriteHalf {
handle: TBufferChannel {
read: self.read.clone(),
write: self.write.clone(),
},
}),
)
Ok((
ReadHalf {
handle: TBufferChannel {
read: self.read.clone(),
write: self.write.clone(),
},
},
WriteHalf {
handle: TBufferChannel {
read: self.read.clone(),
write: self.write.clone(),
},
},
))
}
}

View file

@ -29,32 +29,31 @@ use std::ops::{Deref, DerefMut};
#[cfg(test)]
macro_rules! assert_eq_transport_num_written_bytes {
($transport:ident, $num_written_bytes:expr) => {
{
assert_eq!($transport.channel.write_bytes().len(), $num_written_bytes);
}
};
($transport:ident, $num_written_bytes:expr) => {{
assert_eq!($transport.channel.write_bytes().len(), $num_written_bytes);
}};
}
#[cfg(test)]
macro_rules! assert_eq_transport_written_bytes {
($transport:ident, $expected_bytes:ident) => {
{
assert_eq!($transport.channel.write_bytes(), &$expected_bytes);
}
};
($transport:ident, $expected_bytes:ident) => {{
assert_eq!($transport.channel.write_bytes(), &$expected_bytes);
}};
}
mod buffered;
mod framed;
mod socket;
mod mem;
mod socket;
pub use self::buffered::{TBufferedReadTransport, TBufferedReadTransportFactory,
TBufferedWriteTransport, TBufferedWriteTransportFactory};
pub use self::framed::{TFramedReadTransport, TFramedReadTransportFactory, TFramedWriteTransport,
TFramedWriteTransportFactory};
pub use self::buffered::{
TBufferedReadTransport, TBufferedReadTransportFactory, TBufferedWriteTransport,
TBufferedWriteTransportFactory,
};
pub use self::framed::{
TFramedReadTransport, TFramedReadTransportFactory, TFramedWriteTransport,
TFramedWriteTransportFactory,
};
pub use self::mem::TBufferChannel;
pub use self::socket::TTcpChannel;
@ -78,17 +77,9 @@ pub trait TWriteTransportFactory {
fn create(&self, channel: Box<Write + Send>) -> Box<TWriteTransport + Send>;
}
impl<T> TReadTransport for T
where
T: Read,
{
}
impl<T> TReadTransport for T where T: Read {}
impl<T> TWriteTransport for T
where
T: Write,
{
}
impl<T> TWriteTransport for T where T: Write {}
// FIXME: implement the Debug trait for boxed transports
@ -143,6 +134,26 @@ where
handle: C,
}
impl<C> ReadHalf<C>
where
C: Read,
{
/// Create a `ReadHalf` associated with readable `handle`
pub fn new(handle: C) -> ReadHalf<C> {
ReadHalf { handle }
}
}
impl<C> WriteHalf<C>
where
C: Write,
{
/// Create a `WriteHalf` associated with writable `handle`
pub fn new(handle: C) -> WriteHalf<C> {
WriteHalf { handle }
}
}
impl<C> Read for ReadHalf<C>
where
C: Read,

View file

@ -20,8 +20,8 @@ use std::io;
use std::io::{ErrorKind, Read, Write};
use std::net::{Shutdown, TcpStream};
use {TransportErrorKind, new_transport_error};
use super::{ReadHalf, TIoChannel, WriteHalf};
use {new_transport_error, TransportErrorKind};
/// Bidirectional TCP/IP channel.
///
@ -76,18 +76,18 @@ impl TTcpChannel {
/// The passed-in stream is assumed to have been opened before being wrapped
/// by the created `TTcpChannel` instance.
pub fn with_stream(stream: TcpStream) -> TTcpChannel {
TTcpChannel { stream: Some(stream) }
TTcpChannel {
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(
new_transport_error(
TransportErrorKind::AlreadyOpen,
"tcp connection previously opened",
),
)
Err(new_transport_error(
TransportErrorKind::AlreadyOpen,
"tcp connection previously opened",
))
} else {
match TcpStream::connect(&remote_address) {
Ok(s) => {
@ -112,11 +112,13 @@ impl TTcpChannel {
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"),)
Err(io::Error::new(
ErrorKind::NotConnected,
"tcp endpoint not connected",
))
}
}
}
@ -131,20 +133,21 @@ impl TIoChannel for TTcpChannel {
s.stream
.as_mut()
.and_then(|s| s.try_clone().ok())
.map(
|cloned| {
(ReadHalf { handle: TTcpChannel { stream: s.stream.take() } },
WriteHalf { handle: TTcpChannel { stream: Some(cloned) } })
},
)
.ok_or_else(
|| {
new_transport_error(
TransportErrorKind::Unknown,
"cannot clone underlying tcp stream",
)
},
)
.map(|cloned| {
let read_half = ReadHalf::new(TTcpChannel {
stream: s.stream.take(),
});
let write_half = WriteHalf::new(TTcpChannel {
stream: Some(cloned),
});
(read_half, write_half)
})
.ok_or_else(|| {
new_transport_error(
TransportErrorKind::Unknown,
"cannot clone underlying tcp stream",
)
})
}
}

View file

@ -28,10 +28,13 @@ use kitchen_sink::midlayer::{MealServiceSyncClient, TMealServiceSyncClient};
use kitchen_sink::recursive;
use kitchen_sink::recursive::{CoRec, CoRec2, RecList, RecTree, TTestServiceSyncClient};
use kitchen_sink::ultimate::{FullMealServiceSyncClient, TFullMealServiceSyncClient};
use thrift::transport::{ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel,
TTcpChannel, WriteHalf};
use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol,
TCompactOutputProtocol, TInputProtocol, TOutputProtocol};
use thrift::protocol::{
TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol, TCompactOutputProtocol,
TInputProtocol, TOutputProtocol,
};
use thrift::transport::{
ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel, WriteHalf,
};
fn main() {
match run() {
@ -61,17 +64,20 @@ fn run() -> thrift::Result<()> {
let service = matches.value_of("service").unwrap_or("part");
let (i_chan, o_chan) = tcp_channel(host, port)?;
let (i_tran, o_tran) = (TFramedReadTransport::new(i_chan), TFramedWriteTransport::new(o_chan));
let (i_tran, o_tran) = (
TFramedReadTransport::new(i_chan),
TFramedWriteTransport::new(o_chan),
);
let (i_prot, o_prot): (Box<TInputProtocol>, Box<TOutputProtocol>) = match protocol {
"binary" => {
(Box::new(TBinaryInputProtocol::new(i_tran, true)),
Box::new(TBinaryOutputProtocol::new(o_tran, true)))
}
"compact" => {
(Box::new(TCompactInputProtocol::new(i_tran)),
Box::new(TCompactOutputProtocol::new(o_tran)))
}
"binary" => (
Box::new(TBinaryInputProtocol::new(i_tran, true)),
Box::new(TBinaryOutputProtocol::new(o_tran, true)),
),
"compact" => (
Box::new(TCompactInputProtocol::new(i_tran)),
Box::new(TCompactOutputProtocol::new(o_tran)),
),
unmatched => return Err(format!("unsupported protocol {}", unmatched).into()),
};
@ -87,7 +93,10 @@ fn run_client(
"full" => exec_full_meal_client(i_prot, o_prot),
"part" => exec_meal_client(i_prot, o_prot),
"recursive" => exec_recursive_client(i_prot, o_prot),
_ => Err(thrift::Error::from(format!("unknown service type {}", service)),),
_ => Err(thrift::Error::from(format!(
"unknown service type {}",
service
))),
}
}
@ -110,12 +119,9 @@ fn exec_meal_client(
// this is because the MealService struct does not contain the appropriate service marker
// only the following three calls work
execute_call("part", "ramen", || client.ramen(50))
.map(|_| ())?;
execute_call("part", "meal", || client.meal())
.map(|_| ())?;
execute_call("part", "napkin", || client.napkin())
.map(|_| ())?;
execute_call("part", "ramen", || client.ramen(50)).map(|_| ())?;
execute_call("part", "meal", || client.meal()).map(|_| ())?;
execute_call("part", "napkin", || client.napkin()).map(|_| ())?;
Ok(())
}
@ -126,14 +132,10 @@ fn exec_full_meal_client(
) -> thrift::Result<()> {
let mut client = FullMealServiceSyncClient::new(i_prot, o_prot);
execute_call("full", "ramen", || client.ramen(100))
.map(|_| ())?;
execute_call("full", "meal", || client.meal())
.map(|_| ())?;
execute_call("full", "napkin", || client.napkin())
.map(|_| ())?;
execute_call("full", "full meal", || client.full_meal())
.map(|_| ())?;
execute_call("full", "ramen", || client.ramen(100)).map(|_| ())?;
execute_call("full", "meal", || client.meal()).map(|_| ())?;
execute_call("full", "napkin", || client.napkin()).map(|_| ())?;
execute_call("full", "full meal", || client.full_meal()).map(|_| ())?;
Ok(())
}
@ -145,114 +147,75 @@ fn exec_recursive_client(
let mut client = recursive::TestServiceSyncClient::new(i_prot, o_prot);
let tree = RecTree {
children: Some(
vec![
Box::new(
RecTree {
children: Some(
vec![
Box::new(
RecTree {
children: None,
item: Some(3),
},
),
Box::new(
RecTree {
children: None,
item: Some(4),
},
),
],
),
item: Some(2),
},
),
],
),
children: Some(vec![Box::new(RecTree {
children: Some(vec![
Box::new(RecTree {
children: None,
item: Some(3),
}),
Box::new(RecTree {
children: None,
item: Some(4),
}),
]),
item: Some(2),
})]),
item: Some(1),
};
let expected_tree = RecTree {
children: Some(
vec![
Box::new(
RecTree {
children: Some(
vec![
Box::new(
RecTree {
children: Some(Vec::new()), // remote returns an empty list
item: Some(3),
},
),
Box::new(
RecTree {
children: Some(Vec::new()), // remote returns an empty list
item: Some(4),
},
),
],
),
item: Some(2),
},
),
],
),
children: Some(vec![Box::new(RecTree {
children: Some(vec![
Box::new(RecTree {
children: Some(Vec::new()), // remote returns an empty list
item: Some(3),
}),
Box::new(RecTree {
children: Some(Vec::new()), // remote returns an empty list
item: Some(4),
}),
]),
item: Some(2),
})]),
item: Some(1),
};
let returned_tree = execute_call("recursive", "echo_tree", || client.echo_tree(tree.clone()))?;
if returned_tree != expected_tree {
return Err(
format!(
"mismatched recursive tree {:?} {:?}",
expected_tree,
returned_tree
)
.into(),
);
return Err(format!(
"mismatched recursive tree {:?} {:?}",
expected_tree, returned_tree
)
.into());
}
let list = RecList {
nextitem: Some(
Box::new(
RecList {
nextitem: Some(
Box::new(
RecList {
nextitem: None,
item: Some(3),
},
),
),
item: Some(2),
},
),
),
nextitem: Some(Box::new(RecList {
nextitem: Some(Box::new(RecList {
nextitem: None,
item: Some(3),
})),
item: Some(2),
})),
item: Some(1),
};
let returned_list = execute_call("recursive", "echo_list", || client.echo_list(list.clone()))?;
if returned_list != list {
return Err(format!("mismatched recursive list {:?} {:?}", list, returned_list).into(),);
return Err(format!("mismatched recursive list {:?} {:?}", list, returned_list).into());
}
let co_rec = CoRec {
other: Some(
Box::new(
CoRec2 {
other: Some(CoRec { other: Some(Box::new(CoRec2 { other: None })) }),
},
),
),
other: Some(Box::new(CoRec2 {
other: Some(CoRec {
other: Some(Box::new(CoRec2 { other: None })),
}),
})),
};
let returned_co_rec = execute_call(
"recursive",
"echo_co_rec",
|| client.echo_co_rec(co_rec.clone()),
)?;
let returned_co_rec = execute_call("recursive", "echo_co_rec", || {
client.echo_co_rec(co_rec.clone())
})?;
if returned_co_rec != co_rec {
return Err(format!("mismatched co_rec {:?} {:?}", co_rec, returned_co_rec).into(),);
return Err(format!("mismatched co_rec {:?} {:?}", co_rec, returned_co_rec).into());
}
Ok(())
@ -266,14 +229,10 @@ where
match res {
Ok(_) => println!("{}: completed {} call", service_type, call_name),
Err(ref e) => {
println!(
"{}: failed {} call with error {:?}",
service_type,
call_name,
e
)
}
Err(ref e) => println!(
"{}: failed {} call with error {:?}",
service_type, call_name, e
),
}
res

View file

@ -17,23 +17,32 @@
#[macro_use]
extern crate clap;
extern crate kitchen_sink;
extern crate thrift;
use kitchen_sink::base_one::Noodle;
use kitchen_sink::base_two::{Napkin, NapkinServiceSyncHandler, Ramen, RamenServiceSyncHandler};
use kitchen_sink::midlayer::{Dessert, Meal, MealServiceSyncHandler, MealServiceSyncProcessor};
use kitchen_sink::recursive;
use kitchen_sink::ultimate::{Drink, FullMeal, FullMealAndDrinks,
FullMealAndDrinksServiceSyncProcessor, FullMealServiceSyncHandler};
use kitchen_sink::ultimate::FullMealAndDrinksServiceSyncHandler;
use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
TInputProtocolFactory, TOutputProtocolFactory};
use thrift::transport::{TFramedReadTransportFactory, TFramedWriteTransportFactory,
TReadTransportFactory, TWriteTransportFactory};
use thrift::protocol::{
TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory,
TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory,
};
use thrift::server::TServer;
use thrift::transport::{
TFramedReadTransportFactory, TFramedWriteTransportFactory, TReadTransportFactory,
TWriteTransportFactory,
};
use kitchen_sink::base_one::Noodle;
use kitchen_sink::base_two::{
BrothType, Napkin, NapkinServiceSyncHandler, Ramen, RamenServiceSyncHandler,
};
use kitchen_sink::midlayer::{
Dessert, Meal, MealServiceSyncHandler, MealServiceSyncProcessor, Pie,
};
use kitchen_sink::recursive;
use kitchen_sink::ultimate::FullMealAndDrinksServiceSyncHandler;
use kitchen_sink::ultimate::{
Drink, FullMeal, FullMealAndDrinks, FullMealAndDrinksServiceSyncProcessor,
FullMealServiceSyncHandler,
};
fn main() {
match run() {
@ -46,7 +55,6 @@ fn main() {
}
fn run() -> thrift::Result<()> {
let matches = clap_app!(rust_kitchen_sink_server =>
(version: "0.1.0")
(author: "Apache Thrift Developers <dev@thrift.apache.org>")
@ -67,21 +75,22 @@ fn run() -> thrift::Result<()> {
let r_transport_factory = TFramedReadTransportFactory::new();
let w_transport_factory = TFramedWriteTransportFactory::new();
let (i_protocol_factory, o_protocol_factory): (Box<TInputProtocolFactory>,
Box<TOutputProtocolFactory>) =
match &*protocol {
"binary" => {
(Box::new(TBinaryInputProtocolFactory::new()),
Box::new(TBinaryOutputProtocolFactory::new()))
}
"compact" => {
(Box::new(TCompactInputProtocolFactory::new()),
Box::new(TCompactOutputProtocolFactory::new()))
}
unknown => {
return Err(format!("unsupported transport type {}", unknown).into());
}
};
let (i_protocol_factory, o_protocol_factory): (
Box<TInputProtocolFactory>,
Box<TOutputProtocolFactory>,
) = match &*protocol {
"binary" => (
Box::new(TBinaryInputProtocolFactory::new()),
Box::new(TBinaryOutputProtocolFactory::new()),
),
"compact" => (
Box::new(TCompactInputProtocolFactory::new()),
Box::new(TCompactOutputProtocolFactory::new()),
),
unknown => {
return Err(format!("unsupported transport type {}", unknown).into());
}
};
// FIXME: should processor be boxed as well?
//
@ -94,33 +103,27 @@ fn run() -> thrift::Result<()> {
//
// Since what I'm doing is uncommon I'm just going to duplicate the code
match &*service {
"part" => {
run_meal_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
)
}
"full" => {
run_full_meal_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
)
}
"recursive" => {
run_recursive_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
)
}
"part" => run_meal_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
),
"full" => run_full_meal_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
),
"recursive" => run_recursive_server(
&listen_address,
r_transport_factory,
i_protocol_factory,
w_transport_factory,
o_protocol_factory,
),
unknown => Err(format!("unsupported service type {}", unknown).into()),
}
}
@ -207,7 +210,13 @@ struct FullHandler;
impl FullMealAndDrinksServiceSyncHandler for FullHandler {
fn handle_full_meal_and_drinks(&self) -> thrift::Result<FullMealAndDrinks> {
Ok(FullMealAndDrinks::new(full_meal(), Drink::WHISKEY))
println!("full_meal_and_drinks: handling full meal and drinks call");
Ok(FullMealAndDrinks::new(full_meal(), Drink::CanadianWhisky))
}
fn handle_best_pie(&self) -> thrift::Result<Pie> {
println!("full_meal_and_drinks: handling pie call");
Ok(Pie::MississippiMud) // I prefer Pie::Pumpkin, but I have to check that casing works
}
}
@ -252,7 +261,7 @@ fn noodle() -> Noodle {
}
fn ramen() -> Ramen {
Ramen::new("Mr Ramen".to_owned(), 72)
Ramen::new("Mr Ramen".to_owned(), 72, BrothType::Miso)
}
fn napkin() -> Napkin {

View file

@ -37,6 +37,9 @@ const list<double> CommonTemperatures = [300.0, 450.0]
const double MealsPerDay = 2.5;
const string DefaultRecipeName = "Soup-rise of the Day"
const binary DefaultRecipeBinary = "Soup-rise of the 01010101"
struct Noodle {
1: string flourType
2: Temperature cookTemp

View file

@ -23,9 +23,15 @@
const i32 WaterWeight = 200
enum brothType {
Miso,
shouyu,
}
struct Ramen {
1: optional string ramenType
2: required i32 noodleCount
3: brothType broth
}
struct Napkin {

View file

@ -46,6 +46,15 @@ const set<set<i32>> MyConstNestedSet = [
[6, 7, 8]
]
enum Pie {
PUMPKIN,
apple, // intentionally poorly cased
STRAWBERRY_RHUBARB,
Key_Lime, // intentionally poorly cased
coconut_Cream, // intentionally poorly cased
mississippi_mud, // intentionally poorly cased
}
struct Meal {
1: Base_One.Noodle noodle
2: Base_Two.Ramen ramen

View file

@ -27,6 +27,21 @@ enum Drink {
WATER,
WHISKEY,
WINE,
scotch, // intentionally poorly cased
LATE_HARVEST_WINE,
India_Pale_Ale, // intentionally poorly cased
apple_cider, // intentially poorly cased
belgian_Ale, // intentionally poorly cased
Canadian_whisky, // intentionally poorly cased
}
const map<i8, Midlayer.Pie> RankedPies = {
1: Midlayer.Pie.PUMPKIN,
2: Midlayer.Pie.STRAWBERRY_RHUBARB,
3: Midlayer.Pie.apple,
4: Midlayer.Pie.mississippi_mud,
5: Midlayer.Pie.coconut_Cream,
6: Midlayer.Pie.Key_Lime,
}
struct FullMeal {
@ -45,5 +60,7 @@ service FullMealService extends Midlayer.MealService {
service FullMealAndDrinksService extends FullMealService {
FullMealAndDrinks fullMealAndDrinks()
Midlayer.Pie bestPie()
}