bugeats / flatbuffers-owned

A Rust crate that provides a wrapper struct for FlatBuffers that allows them to be used as owned types.

Home Page:https://crates.io/crates/flatbuffers-owned

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

flatbuffers-owned   Build Status License Latest Version

This small Rust crate provides a wrapper struct for generated Rust FlatBuffers that allows them to be used as owned types.

A owned FlatBuffer does not reference its source data and can therefore be easily moved into another thread.

Documentation

Usage

Add this to your Cargo.toml:

[dependencies]
flatbuffers-owned = "0.1"

Quickstart

Use the flatbuffers_owned! convenience macro on your FlatBuffers to implement the required trait and introduce a type alias for each owned FlatBuffer.

Generate the OwnedMessage type alias for the Message FlatBuffer:

use flatbuffers_owned::*;

flatbuffers_owned!(Message);

Receive a byte slice, create a boxed slice, and initialize the owned flatbuffer:

let message_bytes: &[u8] = receive_message_bytes();
let message_bytes: Box<[u8]> = Box::from(message_bytes);

let owned_message = OwnedMessage::new(message_bytes).unwrap();

Access the actual FlatBuffer:

let message: Message = owned_message.as_actual();

assert_eq!(message.get_text().unwrap(), "Hello, world!");

Error-Handling

The new() constructor always verifies the raw FlatBuffer bytes using the FlatBuffer's built-in run_verifier() method.
Since there can always be a faulty byte-slice passed, you need to check the returned Result of the constructor:

for id in message_ids {
    let message_bytes = Box::from(receive_message_bytes());
    
    let owned_message = OwnedMessage::new(message_bytes);

    match owned_message {
        Ok(message) => {
            // ... process message
        },
        Err(e) => {
            println!("Failed to parse Message: {}", e);
            // ... handling logic
        },
    }
} 

Approach

The wrapper struct

The wrapper struct is a newtype for a Box<[u8]> that accepts a FlatBuffer as the generic type.
With the flatbuffers_owned! convenience macro we get a type alias that just masks this wrapper struct.

pub type OwnedMessage = OwnedFlatBuffer<Message<'static>>;

So instead of OwnedMessage, we can just as well use OwnedFlatBuffer<Message<'static>>.

let owned_message = OwnedFlatBuffer::<Message<'static>>::new(message_bytes).unwrap();

As you may have noticed, the 'static lifetime is then always present when working with the OwnedFlatBuffer.
However, this can be misleading, because the OwnedFlatBuffer does not actually reference anything in the 'static lifetime.
The lifetime is only required by the FlatBuffer struct.
So to make the code more readable, we have the type alias.

Deref to &[u8]

The OwnedFlatBuffer struct de-references itself to its underlying bytes slice.
A Deref to the actual FlatBuffer struct is sadly not possible, since the associated type of the Deref trait can not carry a lifetime.

Open to Feedback

If you have any ideas for improvements or would like to contribute to this project, please feel free to open an issue or pull request.

I will also be happy for any general tips or suggestions given that this is my first (published) library ever. :)

License

This project is released under the MIT License, which allows for commercial use, modification, distribution, and private use. See the LICENSE file for the full text of the license.

About

A Rust crate that provides a wrapper struct for FlatBuffers that allows them to be used as owned types.

https://crates.io/crates/flatbuffers-owned

License:MIT License


Languages

Language:Rust 100.0%