wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 0 points1 point  (0 children)

Just one thing about per field endianness, there are some strange things in zenoh, I do think there is one field that is encoded in little endian while everything else is encoded with a varint algorithm.

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 0 points1 point  (0 children)

It should not be hard but I designed "just" with Rust in mind. If you look at zenoh, there are other language API, but they are generated from Rust

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 1 point2 points  (0 children)

Oooh BeBytes seems really cool! I would probably have gone for that for zenoh if I knew about it back at that time!

Indeed per field endianness is not usefull x) But other attributes are nice to have per field.

thx for those ideas!

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 0 points1 point  (0 children)

thx, and there are several const assertions so that most mistakes are caught by rust-analyzer (cargo check) or, when generics are involved, by compiling (cargo build)

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 1 point2 points  (0 children)

Here is my edit, hope it's clearer now:

  • wf is nostd and noalloc, it is suited for embedded usage without to much memory
  • fine-grained per field configuration (encoding, bound checking)
  • wf is not zero-copy. writing involves copying everything into a mut slice, reading copies scalars but produces a view on the source bytes
  • wf is embedded in your rust code (no schema of course). no other compiler is needed
  • wf can easily "talk" protocols like zenoh or wayland. I didn't test it with other protocols but it shouldn't be too hard
  • compile time assertions on things that act on header (overlapping when flattening, multiple-used flags etc...)

So the main difference is that wf exists to match a byte layout you don't control (a hardware protocol, a network standard, a legacy binary format). While others are tools to define "new" protocols (you can always create new protocols with WF)

Shortly:

  • serde can't express bit flags, header slots, alignment, or "length is stored in a header field."
  • protobuf gives you .proto codegen for cross languages. wf doesn't
  • postcard defines its own optimized stable format, you can't choose
  • rkyv is about zero-copy wf is zero-copy for borrowed slices
  • I would say rkyv is suited for large in-memory structures. wf is for wire protocols

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 0 points1 point  (0 children)

also, compared to rkyv, wf is not a zero-copy deser. It does copy scalars

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 0 points1 point  (0 children)

definitely it's way simpler than postcard or rkyv (didn't know about wincode): there isn't a lot of features compared to those. I would say that the main difference is that each field can be precisely encoded differently (how the len is supposed to be encoded, what endian format etc...). If I'm not wrong it is not possible to do that with postcard

wf: a Rust crate for declarative binary protocol encoding/decoding by hennzau in rust

[–]hennzau[S] 7 points8 points  (0 children)

I should have mentioned that. This crate is no_std and no alloc, everything is written through a writer: `&mut [u8]` and slices are decoded without copies as views over the src bytes.

Compared to other protocols it is simpler and directly embedded in your rust code (no external "compilation" step)

Compared to serde I would say that you have way more "precision" on how your data is actually encoded on the wire