# Rust Thrift library
## Overview
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. The `generated` layer is code generated by the
Thrift compiler's Rust plugin. It uses the components defined in this crate to
serialize and deserialize types and implement RPC. Users interact with these
types and services by writing their own code on top.
```text
+-----------+
| generated | <-> errors/results
+-----------+
| protocol |
+-----------+
| transport |
+-----------+
```
## Using this crate
Add `thrift = "x.y.z"` to your `Cargo.toml`, where `x.y.z` is the version of the
Thrift compiler you're using.
## API Documentation
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.15.0
* **[THRIFT-5360]** - No longer define OR generate `description()` methods for `Error` types.
`Error.description()` was soft-deprecated in 1.27, and deprecated as of 1.41.
Library error types also do not implement `Error.description()`. Also, as a result of this change
the generated Rust representation of an Error no longer implements the `Error.description()` method.
Instead, it generates a `Display` impl with the same information.
For example:
```thrift
exception Xception {
1: i32 errorCode,
2: string message
}
```
used to generate:
```rust
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().format(f)
}
}
```
It *now* generates:
```rust
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 { }
// 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 {
write!(f, "remote service threw Xception")
}
}
```
* **[THRIFT-5314]** - Generate enums implementations that are forward compatible (i.e. don't error on unknown values)
As a result of this change the Rust representation of an enum changes from a standard
Rust enum into a newtype struct with associated constants.
For example:
```thrift
// THRIFT
enum Operation {
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE,
}
```
used to generate:
```rust
pub enum Operation {
Add,
Subtract,
Multiply,
Divide,
}
```
It *now* generates:
```rust
pub struct Operation(pub i32);
impl Operation {
pub const ADD: Operation = Operation(0);
pub const SUBTRACT: Operation = Operation(1);
pub const MULTIPLY: Operation = Operation(2);
pub const DIVIDE: Operation = Operation(3);
}
```
##### Thrift 0.14.0
* **[THRIFT-5158]** - Rust library and generator now support Rust 2018 only. Required rust 1.40.0 or higher
The Rust `thrift` library was updated to Rust 2018 via `cargo fix --edition`.
All test code in the repo was updated as well. The code generator was also updated
to support Rust 2018 only.
##### Thrift 0.13.0
* **[THRIFT-4536]** - Use TryFrom from std, required rust 1.34.0 or higher
Previously TryFrom was from try_from crate, it is now from the std library,
but this functionality is only available in rust 1.34.0. Additionally,
ordered-float is now re-exported under the thrift module to reduce
possible dependency mismatches.
##### 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
pub enum Operation {
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE,
}
```
It *now* generates:
```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
[Thrift website](https://thrift.apache.org/) for more details.
Thrift Rust support requires code in several directories:
* `compiler/cpp/src/thrift/generate/t_rs_generator.cc`: binding code generator
* `lib/rs`: runtime library
* `lib/rs/test`: supplemental tests
* `tutorial/rs`: tutorial client and server
* `test/rs`: cross-language test client and server
All library code, test code and auto-generated code compiles and passes clippy
without warnings. All new code must do the same! When making changes ensure that:
* `rustc` does does output any warnings
* `clippy` with default settings does not output any warnings (includes auto-generated code)
* `cargo test` is successful
* `make precross` and `make check` are successful
* `tutorial/bin/tutorial_client` and `tutorial/bin/tutorial_server` communicate