| # 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 |
| +-----------+ |
| | app dev | |
| +-----------+ |
| | 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 2021 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 |
| // OLD AUTO-GENERATED RUST |
| pub enum Operation { |
| Add, |
| Subtract, |
| Multiply, |
| Divide, |
| } |
| ``` |
| |
| It *now* generates: |
| |
| ```rust |
| // NEW AUTO-GENERATED 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 2021 only. Required rust 1.65.0 or higher |
| |
| The Rust `thrift` library was updated to Rust 2021 via `cargo fix --edition`. |
| All test code in the repo was updated as well. The code generator was also updated |
| to support Rust 2021 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 |
| // 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 |
| [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 |