# Rust Language Bindings for Thrift

## Getting Started

1. Get the [Thrift compiler](https://thrift.apache.org).

2. Add the thrift crate to your `Cargo.toml`.

```toml
thrift = "x.y.z" # x.y.z is the version of the thrift compiler
```

3. Generate Rust sources for your IDL (for example, `Tutorial.thrift`).

```shell
thrift -out my_rust_program/src --gen rs -r Tutorial.thrift
```

4. Use the generated source in your code.

```rust
// generated Rust module from Thrift IDL
mod tutorial;

use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol};
use thrift::protocol::{TInputProtocol, TOutputProtocol};
use thrift::transport::{TFramedReadTransport, TFramedWriteTransport};
use thrift::transport::{TIoChannel, TTcpChannel};

use tutorial::{CalculatorSyncClient, TCalculatorSyncClient};
use tutorial::{Operation, Work};

fn main() {
    match run() {
        Ok(()) => println!("client ran successfully"),
        Err(e) => {
            println!("client failed with {:?}", e);
            std::process::exit(1);
        }
    }
}

fn run() -> thrift::Result<()> {
    //
    // build client
    //

    println!("connect to server on 127.0.0.1:9090");
    let mut c = TTcpChannel::new();
    c.open("127.0.0.1:9090")?;

    let (i_chan, o_chan) = c.split()?;
    
    let i_prot = TCompactInputProtocol::new(
        TFramedReadTransport::new(i_chan)
    );
    let o_prot = TCompactOutputProtocol::new(
        TFramedWriteTransport::new(o_chan)
    );

    let mut client = CalculatorSyncClient::new(i_prot, o_prot);

    //
    // alright! - let's make some calls
    //

    // two-way, void return
    client.ping()?;

    // two-way with some return
    let res = client.calculate(
        72,
        Work::new(7, 8, Operation::Multiply, None)
    )?;
    println!("multiplied 7 and 8, got {}", res);

    // two-way and returns a Thrift-defined exception
    let res = client.calculate(
        77,
        Work::new(2, 0, Operation::Divide, None)
    );
    match res {
        Ok(v) => panic!("shouldn't have succeeded with result {}", v),
        Err(e) => println!("divide by zero failed with {:?}", e),
    }

    // one-way
    client.zip()?;

    // done!
    Ok(())
}
```

## Code Generation

### Thrift Files and Generated Modules

The Thrift code generator takes each Thrift file and generates a Rust module
with the same name snake-cased. For example, running the compiler on
`ThriftTest.thrift` creates `thrift_test.rs`. To use these generated files add
`mod ...` and `use ...` declarations to your `lib.rs` or `main.rs` - one for
each generated file.

### Results and Errors

The Thrift runtime library defines a `thrift::Result` and a `thrift::Error` type,
both of which are used throughout the runtime library and in all generated code.
Conversions are defined from `std::io::Error`, `str` and `String` into
`thrift::Error`.

### Thrift Type and their Rust Equivalents

Thrift defines a number of types, each of which is translated into its Rust
equivalent by the code generator.

* Primitives (bool, i8, i16, i32, i64, double, string, binary)
* Typedefs
* Enums
* Containers
* Structs
* Unions
* Exceptions
* Services
* Constants (primitives, containers, structs)

In addition, unless otherwise noted, thrift includes are translated into
`use ...` statements in the generated code, and all declarations, parameters,
traits and types in the generated code are namespaced appropriately.

The following subsections cover each type and their generated Rust equivalent.

### Primitives

Thrift primitives have straightforward Rust equivalents.

* bool: `bool`
* i8: `i8`
* i16: `i16`
* i32: `i32`
* i64: `i64`
* double: `OrderedFloat<f64>`
* string: `String`
* binary: `Vec<u8>`

### Typedefs

A typedef is translated to a `pub type` declaration.

```thrift
typedef i64 UserId

typedef map<string, UserId> MapType
```
```rust
pub type UserId = i64;

pub type MapType = BTreeMap<String, Bonk>;
```

### Enums

A Thrift enum is represented as a Rust enum, and each variant is transcribed 1:1.

```thrift
enum Numberz
{
    ONE = 1,
    TWO,
    THREE,
    FIVE = 5,
    SIX,
    EIGHT = 8
}
```

```rust
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Numberz {
    ONE = 1,
    TWO = 2,
    THREE = 3,
    FIVE = 5,
    SIX = 6,
    EIGHT = 8,
}

impl TryFrom<i32> for Numberz {
    // ...
}

```

### Containers

Thrift has three container types: list, set and map. They are translated into
Rust `Vec`, `BTreeSet` and `BTreeMap` respectively. Any Thrift type (this
includes structs, enums and typedefs) can be a list/set element or a map
key/value.

#### List

```thrift
list <i32> numbers
```

```rust
numbers: Vec<i32>
```

#### Set

```thrift
set <i32> numbers
```

```rust
numbers: BTreeSet<i32>
```

#### Map

```thrift
map <string, i32> numbers
```

```rust
numbers: BTreeMap<String, i32>
```

### Structs

A Thrift struct is represented as a Rust struct, and each field transcribed 1:1.

```thrift
struct CrazyNesting {
    1: string string_field,
    2: optional set<Insanity> set_field,
    3: required list<
         map<set<i32>, map<i32,set<list<map<Insanity,string>>>>>
       >
    4: binary binary_field
}
```
```rust
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct CrazyNesting {
    pub string_field: Option<String>,
    pub set_field: Option<BTreeSet<Insanity>>,
    pub list_field: Vec<
        BTreeMap<
            BTreeSet<i32>,
            BTreeMap<i32, BTreeSet<Vec<BTreeMap<Insanity, String>>>>
        >
    >,
    pub binary_field: Option<Vec<u8>>,
}

impl CrazyNesting {
    pub fn read_from_in_protocol(i_prot: &mut TInputProtocol)
    ->
    thrift::Result<CrazyNesting> {
        // ...
    }
    pub fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol)
    ->
    thrift::Result<()> {
        // ...
    }
}

```
##### Optionality

Thrift has 3 "optionality" types:

1. Required
2. Optional
3. Default

The Rust code generator encodes *Required* fields as the bare type itself, while
*Optional* and *Default* fields are encoded as `Option<TypeName>`.

```thrift
struct Foo {
    1: required string bar  // 1. required
    2: optional string baz  // 2. optional
    3: string qux           // 3. default
}
```

```rust
pub struct Foo {
    bar: String,            // 1. required
    baz: Option<String>,    // 2. optional
    qux: Option<String>,    // 3. default
}
```

## Known Issues

* Struct constants are not supported
* Map, list and set constants require a const holder struct
