1*890232f2SAndroid Build Coastguard WorkerUse in Rust {#flatbuffers_guide_use_rust} 2*890232f2SAndroid Build Coastguard Worker========== 3*890232f2SAndroid Build Coastguard Worker 4*890232f2SAndroid Build Coastguard Worker## Before you get started 5*890232f2SAndroid Build Coastguard Worker 6*890232f2SAndroid Build Coastguard WorkerBefore diving into the FlatBuffers usage in Rust, it should be noted that 7*890232f2SAndroid Build Coastguard Workerthe [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide 8*890232f2SAndroid Build Coastguard Workerto general FlatBuffers usage in all of the supported languages (including Rust). 9*890232f2SAndroid Build Coastguard WorkerThis page is designed to cover the nuances of FlatBuffers usage, specific to 10*890232f2SAndroid Build Coastguard WorkerRust. 11*890232f2SAndroid Build Coastguard Worker 12*890232f2SAndroid Build Coastguard Worker#### Prerequisites 13*890232f2SAndroid Build Coastguard Worker 14*890232f2SAndroid Build Coastguard WorkerThis page assumes you have written a FlatBuffers schema and compiled it 15*890232f2SAndroid Build Coastguard Workerwith the Schema Compiler. If you have not, please see 16*890232f2SAndroid Build Coastguard Worker[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) 17*890232f2SAndroid Build Coastguard Workerand [Writing a schema](@ref flatbuffers_guide_writing_schema). 18*890232f2SAndroid Build Coastguard Worker 19*890232f2SAndroid Build Coastguard WorkerAssuming you wrote a schema, say `mygame.fbs` (though the extension doesn't 20*890232f2SAndroid Build Coastguard Workermatter), you've generated a Rust file called `mygame_generated.rs` using the 21*890232f2SAndroid Build Coastguard Workercompiler (e.g. `flatc --rust mygame.fbs` or via helpers listed in "Useful 22*890232f2SAndroid Build Coastguard Workertools created by others" section bellow), you can now start using this in 23*890232f2SAndroid Build Coastguard Workeryour program by including the file. As noted, this header relies on the crate 24*890232f2SAndroid Build Coastguard Worker`flatbuffers`, which should be in your include `Cargo.toml`. 25*890232f2SAndroid Build Coastguard Worker 26*890232f2SAndroid Build Coastguard Worker## FlatBuffers Rust library code location 27*890232f2SAndroid Build Coastguard Worker 28*890232f2SAndroid Build Coastguard WorkerThe code for the FlatBuffers Rust library can be found at 29*890232f2SAndroid Build Coastguard Worker`flatbuffers/rust`. You can browse the library code on the 30*890232f2SAndroid Build Coastguard Worker[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/rust). 31*890232f2SAndroid Build Coastguard Worker 32*890232f2SAndroid Build Coastguard Worker## Testing the FlatBuffers Rust library 33*890232f2SAndroid Build Coastguard Worker 34*890232f2SAndroid Build Coastguard WorkerThe code to test the Rust library can be found at `flatbuffers/tests/rust_usage_test`. 35*890232f2SAndroid Build Coastguard WorkerThe test code itself is located in 36*890232f2SAndroid Build Coastguard Worker[integration_test.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/tests/integration_test.rs) 37*890232f2SAndroid Build Coastguard Worker 38*890232f2SAndroid Build Coastguard WorkerThis test file requires `flatc` to be present. To review how to build the project, 39*890232f2SAndroid Build Coastguard Workerplease read the [Building](@ref flatbuffers_guide_building) documentation. 40*890232f2SAndroid Build Coastguard Worker 41*890232f2SAndroid Build Coastguard WorkerTo run the tests, execute `RustTest.sh` from the `flatbuffers/tests` directory. 42*890232f2SAndroid Build Coastguard WorkerFor example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply 43*890232f2SAndroid Build Coastguard Workerrun: `cd tests && ./RustTest.sh`. 44*890232f2SAndroid Build Coastguard Worker 45*890232f2SAndroid Build Coastguard Worker*Note: The shell script requires [Rust](https://www.rust-lang.org) to 46*890232f2SAndroid Build Coastguard Workerbe installed.* 47*890232f2SAndroid Build Coastguard Worker 48*890232f2SAndroid Build Coastguard Worker## Using the FlatBuffers Rust library 49*890232f2SAndroid Build Coastguard Worker 50*890232f2SAndroid Build Coastguard Worker*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth 51*890232f2SAndroid Build Coastguard Workerexample of how to use FlatBuffers in Rust.* 52*890232f2SAndroid Build Coastguard Worker 53*890232f2SAndroid Build Coastguard WorkerFlatBuffers supports both reading and writing FlatBuffers in Rust. 54*890232f2SAndroid Build Coastguard Worker 55*890232f2SAndroid Build Coastguard WorkerTo use FlatBuffers in your code, first generate the Rust modules from your 56*890232f2SAndroid Build Coastguard Workerschema with the `--rust` option to `flatc`. Then you can import both FlatBuffers 57*890232f2SAndroid Build Coastguard Workerand the generated code to read or write FlatBuffers. 58*890232f2SAndroid Build Coastguard Worker 59*890232f2SAndroid Build Coastguard WorkerFor example, here is how you would read a FlatBuffer binary file in Rust: 60*890232f2SAndroid Build Coastguard WorkerFirst, include the library and generated code. Then read the file into 61*890232f2SAndroid Build Coastguard Workera `u8` vector, which you pass, as a byte slice, to `root_as_monster()`. 62*890232f2SAndroid Build Coastguard Worker 63*890232f2SAndroid Build Coastguard WorkerThis full example program is available in the Rust test suite: 64*890232f2SAndroid Build Coastguard Worker[monster_example.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/bin/monster_example.rs) 65*890232f2SAndroid Build Coastguard Worker 66*890232f2SAndroid Build Coastguard WorkerIt can be run by `cd`ing to the `rust_usage_test` directory and executing: `cargo run monster_example`. 67*890232f2SAndroid Build Coastguard Worker 68*890232f2SAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs} 69*890232f2SAndroid Build Coastguard Worker extern crate flatbuffers; 70*890232f2SAndroid Build Coastguard Worker 71*890232f2SAndroid Build Coastguard Worker #[allow(dead_code, unused_imports)] 72*890232f2SAndroid Build Coastguard Worker #[path = "../../monster_test_generated.rs"] 73*890232f2SAndroid Build Coastguard Worker mod monster_test_generated; 74*890232f2SAndroid Build Coastguard Worker pub use monster_test_generated::my_game; 75*890232f2SAndroid Build Coastguard Worker 76*890232f2SAndroid Build Coastguard Worker use std::io::Read; 77*890232f2SAndroid Build Coastguard Worker 78*890232f2SAndroid Build Coastguard Worker fn main() { 79*890232f2SAndroid Build Coastguard Worker let mut f = std::fs::File::open("../monsterdata_test.mon").unwrap(); 80*890232f2SAndroid Build Coastguard Worker let mut buf = Vec::new(); 81*890232f2SAndroid Build Coastguard Worker f.read_to_end(&mut buf).expect("file reading failed"); 82*890232f2SAndroid Build Coastguard Worker 83*890232f2SAndroid Build Coastguard Worker let monster = my_game::example::root_as_monster(&buf[..]); 84*890232f2SAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 85*890232f2SAndroid Build Coastguard Worker 86*890232f2SAndroid Build Coastguard Worker`monster` is of type `Monster`, and points to somewhere *inside* your 87*890232f2SAndroid Build Coastguard Workerbuffer (root object pointers are not the same as `buffer_pointer` !). 88*890232f2SAndroid Build Coastguard WorkerIf you look in your generated header, you'll see it has 89*890232f2SAndroid Build Coastguard Workerconvenient accessors for all fields, e.g. `hp()`, `mana()`, etc: 90*890232f2SAndroid Build Coastguard Worker 91*890232f2SAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs} 92*890232f2SAndroid Build Coastguard Worker println!("{}", monster.hp()); // `80` 93*890232f2SAndroid Build Coastguard Worker println!("{}", monster.mana()); // default value of `150` 94*890232f2SAndroid Build Coastguard Worker println!("{:?}", monster.name()); // Some("MyMonster") 95*890232f2SAndroid Build Coastguard Worker } 96*890232f2SAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 97*890232f2SAndroid Build Coastguard Worker 98*890232f2SAndroid Build Coastguard Worker*Note: That we never stored a `mana` value, so it will return the default.* 99*890232f2SAndroid Build Coastguard Worker 100*890232f2SAndroid Build Coastguard Worker## Direct memory access 101*890232f2SAndroid Build Coastguard Worker 102*890232f2SAndroid Build Coastguard WorkerAs you can see from the above examples, all elements in a buffer are 103*890232f2SAndroid Build Coastguard Workeraccessed through generated accessors. This is because everything is 104*890232f2SAndroid Build Coastguard Workerstored in little endian format on all platforms (the accessor 105*890232f2SAndroid Build Coastguard Workerperforms a swap operation on big endian machines), and also because 106*890232f2SAndroid Build Coastguard Workerthe layout of things is generally not known to the user. 107*890232f2SAndroid Build Coastguard Worker 108*890232f2SAndroid Build Coastguard WorkerFor structs, layout is deterministic and guaranteed to be the same 109*890232f2SAndroid Build Coastguard Workeracross platforms (scalars are aligned to their 110*890232f2SAndroid Build Coastguard Workerown size, and structs themselves to their largest member), and you 111*890232f2SAndroid Build Coastguard Workerare allowed to access this memory directly by using `safe_slice` 112*890232f2SAndroid Build Coastguard Workeron the reference to a struct, or even an array of structs. 113*890232f2SAndroid Build Coastguard Worker 114*890232f2SAndroid Build Coastguard WorkerTo compute offsets to sub-elements of a struct, make sure they 115*890232f2SAndroid Build Coastguard Workerare structs themselves, as then you can use the pointers to 116*890232f2SAndroid Build Coastguard Workerfigure out the offset without having to hardcode it. This is 117*890232f2SAndroid Build Coastguard Workerhandy for use of arrays of structs with calls like `glVertexAttribPointer` 118*890232f2SAndroid Build Coastguard Workerin OpenGL or similar APIs. 119*890232f2SAndroid Build Coastguard Worker 120*890232f2SAndroid Build Coastguard WorkerIt is important to note is that structs are still little endian on all 121*890232f2SAndroid Build Coastguard Workermachines, so the functions to enable tricks like this are only exposed on little 122*890232f2SAndroid Build Coastguard Workerendian machines. If you also ship on big endian machines, using an 123*890232f2SAndroid Build Coastguard Worker`#[cfg(target_endian = "little")]` attribute would be wise or your code will not 124*890232f2SAndroid Build Coastguard Workercompile. 125*890232f2SAndroid Build Coastguard Worker 126*890232f2SAndroid Build Coastguard WorkerThe special function `safe_slice` is implemented on Vector objects that are 127*890232f2SAndroid Build Coastguard Workerrepresented in memory the same way as they are represented on the wire. This 128*890232f2SAndroid Build Coastguard Workerfunction is always available on vectors of struct, bool, u8, and i8. It is 129*890232f2SAndroid Build Coastguard Workerconditionally-compiled on little-endian systems for all the remaining scalar 130*890232f2SAndroid Build Coastguard Workertypes. 131*890232f2SAndroid Build Coastguard Worker 132*890232f2SAndroid Build Coastguard WorkerThe FlatBufferBuilder function `create_vector_direct` is implemented for all 133*890232f2SAndroid Build Coastguard Workertypes that are endian-safe to write with a `memcpy`. It is the write-equivalent 134*890232f2SAndroid Build Coastguard Workerof `safe_slice`. 135*890232f2SAndroid Build Coastguard Worker 136*890232f2SAndroid Build Coastguard Worker## Access of untrusted buffers 137*890232f2SAndroid Build Coastguard Worker 138*890232f2SAndroid Build Coastguard WorkerThe safe Rust functions to interpret a slice as a table (`root`, 139*890232f2SAndroid Build Coastguard Worker`size_prefixed_root`, `root_with_opts`, and `size_prefixed_root_with_opts`) 140*890232f2SAndroid Build Coastguard Workerverify the data first. This has some performance cost, but is intended to be 141*890232f2SAndroid Build Coastguard Workersafe for use on flatbuffers from untrusted sources. There are corresponding 142*890232f2SAndroid Build Coastguard Worker`unsafe` versions with names ending in `_unchecked` which skip this 143*890232f2SAndroid Build Coastguard Workerverification, and may access arbitrary memory. 144*890232f2SAndroid Build Coastguard Worker 145*890232f2SAndroid Build Coastguard WorkerThe generated accessor functions access fields over offsets, which is 146*890232f2SAndroid Build Coastguard Workervery quick. The current implementation uses these to access memory without any 147*890232f2SAndroid Build Coastguard Workerfurther bounds checking. All of the safe Rust APIs ensure the verifier is run 148*890232f2SAndroid Build Coastguard Workerover these flatbuffers before accessing them. 149*890232f2SAndroid Build Coastguard Worker 150*890232f2SAndroid Build Coastguard WorkerWhen you're processing large amounts of data from a source you know (e.g. 151*890232f2SAndroid Build Coastguard Workeryour own generated data on disk), the `_unchecked` versions are acceptable, but 152*890232f2SAndroid Build Coastguard Workerwhen reading data from the network that can potentially have been modified by an 153*890232f2SAndroid Build Coastguard Workerattacker, it is desirable to use the safe versions which use the verifier. 154*890232f2SAndroid Build Coastguard Worker 155*890232f2SAndroid Build Coastguard Worker## Threading 156*890232f2SAndroid Build Coastguard Worker 157*890232f2SAndroid Build Coastguard WorkerReading a FlatBuffer does not touch any memory outside the original buffer, 158*890232f2SAndroid Build Coastguard Workerand is entirely read-only (all immutable), so is safe to access from multiple 159*890232f2SAndroid Build Coastguard Workerthreads even without synchronisation primitives. 160*890232f2SAndroid Build Coastguard Worker 161*890232f2SAndroid Build Coastguard WorkerCreating a FlatBuffer is not thread safe. All state related to building 162*890232f2SAndroid Build Coastguard Workera FlatBuffer is contained in a FlatBufferBuilder instance, and no memory 163*890232f2SAndroid Build Coastguard Workeroutside of it is touched. To make this thread safe, either do not 164*890232f2SAndroid Build Coastguard Workershare instances of FlatBufferBuilder between threads (recommended), or 165*890232f2SAndroid Build Coastguard Workermanually wrap it in synchronisation primitives. There's no automatic way to 166*890232f2SAndroid Build Coastguard Workeraccomplish this, by design, as we feel multithreaded construction 167*890232f2SAndroid Build Coastguard Workerof a single buffer will be rare, and synchronisation overhead would be costly. 168*890232f2SAndroid Build Coastguard Worker 169*890232f2SAndroid Build Coastguard WorkerUnlike most other languages, in Rust these properties are exposed to and 170*890232f2SAndroid Build Coastguard Workerenforced by the type system. `flatbuffers::Table` and the generated table types 171*890232f2SAndroid Build Coastguard Workerare `Send + Sync`, indicating they may be freely shared across threads and data 172*890232f2SAndroid Build Coastguard Workermay be accessed from any thread which receives a const (aka shared) reference. 173*890232f2SAndroid Build Coastguard WorkerThere are no functions which require a mutable (aka exclusive) reference, which 174*890232f2SAndroid Build Coastguard Workermeans all the available functions may be called like this. 175*890232f2SAndroid Build Coastguard Worker`flatbuffers::FlatBufferBuilder` is also `Send + Sync`, but all of the mutating 176*890232f2SAndroid Build Coastguard Workerfunctions require a mutable (aka exclusive) reference which can only be created 177*890232f2SAndroid Build Coastguard Workerwhen no other references to the `FlatBufferBuilder` exist, and may not be copied 178*890232f2SAndroid Build Coastguard Workerwithin the same thread, let alone to a second thread. 179*890232f2SAndroid Build Coastguard Worker 180*890232f2SAndroid Build Coastguard Worker## Useful tools created by others 181*890232f2SAndroid Build Coastguard Worker 182*890232f2SAndroid Build Coastguard Worker* [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler 183*890232f2SAndroid Build Coastguard Worker(flatc) as API for transparent `.fbs` to `.rs` code-generation via Cargo 184*890232f2SAndroid Build Coastguard Workerbuild scripts integration. 185*890232f2SAndroid Build Coastguard Worker 186*890232f2SAndroid Build Coastguard Worker<br> 187