-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port FlatBuffers to Rust #4898
Port FlatBuffers to Rust #4898
Conversation
c855cd4
to
e92a41e
Compare
Awesome work @rw - thank you! We're already using your patch in our project and it's working great. |
e92a41e
to
4722510
Compare
dff1ac4
to
de40027
Compare
5c1afc2
to
21fefe9
Compare
21fefe9
to
93f9162
Compare
Should the fie |
@phayes I included it in the PR for people who don't want to run the code but still want to see the output of tests passing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WOW! This is some amazing effort, the most comprehensive language port yet!
I'm missing Rust specific changes to Tutorial.md
, and a Rust sample in samples
. Here is a sample checklist to see if you've touched all typical language port files: 4898809
docs/source/RustUsage.md
Outdated
The generated accessor functions access fields over offsets, which is | ||
very quick. These offsets are not verified at run-time, so a malformed | ||
buffer could cause a program to crash by accessing random memory. (We try to | ||
prevent this in Rust by using safe slice accesses, instead of unsafe pointer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this phrase is a bit weird.. what exactly happens if an offset in the buffer that points outside of the buffer is turned into a slice, and then accessed? How is that different from a raw pointer?
docs/source/RustUsage.md
Outdated
data from the network that can potentially have been modified by an | ||
attacker, this is undesirable. | ||
|
||
The C++ port provides a buffer verifier, but, at this time, Rust does not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Rust may provide this in a future version" ?
rust/flatbuffers/src/builder.rs
Outdated
/// the default, then this is a no-op. | ||
#[inline] | ||
pub fn push_slot<X: Push + PartialEq>(&mut self, slotoff: VOffsetT, x: X, default: X) { | ||
self.assert_nested("push_slot must be called after start_table"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that users of the generated API likely aren't calling push_slot
themselves, this message may be confusing? In fact, it may be easier to just have one message for nesting violations.
rust/flatbuffers/src/builder.rs
Outdated
} | ||
|
||
#[inline] | ||
fn fill(&mut self, zero_pad_bytes: usize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function doesn't appear to do anything?
@@ -14,8 +14,8 @@ | |||
# See the License for the specific language governing permissions and | |||
# limitations under the License. | |||
|
|||
../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json | |||
../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs | |||
../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please change .bat
as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
impl<'a> flatbuffers::Follow<'a> for Monster<'a> { | ||
type Inner = Monster<'a>; | ||
#[inline] | ||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be _follow
if there is a possibility of a clash with generated fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eye! This is actually okay because it's a trait method, so unless users are importing Push
, they cannot access it. Furthermore, I added the trait methods we use to the reserved keywords list, so a field called follow
would be generated as follow_
.
@@ -0,0 +1,184 @@ | |||
running 170 tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems weird to include this in the repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it
let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20), | ||
my_game::example::Test::new(30, 40)]); | ||
let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8)); | ||
let args = my_game::example::MonsterArgs{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline in the create
call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment explaining why we can't do this (the Args
struct takes a reference to a Vec3
so we have to make sure it lives long enough).
None => { return Err("bad m.testarrayofstring"); } | ||
Some(x) => { x } | ||
}; | ||
if testarrayofstring.len() != 2 { return Err("bad monster.testarrayofstring len"); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should bad fieldname
be generated with a macro?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or just use assert_eq
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrote a macro for this.
@aardappel Thanks for the feedback, I incorporated it all. Also, I resolved an alignment issue that I didn't catch before, and made the |
Thanks! Amazing work! |
This is a port of FlatBuffers to Rust. It provides code generation and a runtime library derived from the C++ implementation. It utilizes the Rust type system to provide safe and fast traversal of FlatBuffers data. There are 188 tests, including many fuzz tests of roundtrips for various serialization scenarios. Initial benchmarks indicate that the canonical example payload can be written in ~700ns, and traversed in ~100ns. Rustaceans may be interested in the Follow,Push, and SafeSliceAccess traits. These traits lift traversals, reads, writes, and slice accesses into the type system, providing abstraction with no runtime penalty.
This is a port of FlatBuffers to Rust. It provides code generation and a runtime library derived from the C++ implementation. It utilizes the Rust type system to provide safe and fast traversal of FlatBuffers data. There are 188 tests, including many fuzz tests of roundtrips for various serialization scenarios. Initial benchmarks indicate that the canonical example payload can be written in ~700ns, and traversed in ~100ns. Rustaceans may be interested in the Follow, Push, and SafeSliceAccess traits. These traits lift traversals, reads, writes, and slice accesses into the type system, providing abstraction with no runtime penalty.
👏 👏 👏 |
This is a port of FlatBuffers to Rust. It provides code generation and a runtime library derived from the C++ implementation. It utilizes the Rust type system to provide safe and fast traversal of FlatBuffers data. There are 188 tests, including many fuzz tests of roundtrips for various serialization scenarios. Initial benchmarks indicate that the canonical example payload can be written in ~700ns, and traversed in ~100ns. Rustaceans may be interested in the Follow, Push, and SafeSliceAccess traits. These traits lift traversals, reads, writes, and slice accesses into the type system, providing abstraction with no runtime penalty.
This is a port of FlatBuffers to Rust. It provides code generation and a runtime library derived from the C++ implementation. It utilizes the Rust type system to provide safe and fast traversal of FlatBuffers data. There are 188 tests, including many fuzz tests of roundtrips for various serialization scenarios. Initial benchmarks indicate that the canonical example payload can be written in ~700ns, and traversed in ~100ns. Rustaceans may be interested in the Follow, Push, and SafeSliceAccess traits. These traits lift traversals, reads, writes, and slice accesses into the type system, providing abstraction with no runtime penalty.
This is a port of FlatBuffers to native Rust. It provides code generation and a runtime library derived from the C++ implementation. It utilizes the Rust type system to provide safe and fast traversal of FlatBuffers data.
There are 188 tests, including many fuzz tests of roundtrips for various serialization scenarios. Initial benchmarks indicate that the canonical example payload can be written in ~700ns, and traversed in ~100ns.
Rustaceans may be interested in the
Follow
,Push
, andSafeSliceAccess
traits. These traits lift traversals, reads, writes, and slice accesses into the type system, providing abstraction with no runtime penalty.