5 ms·
I flipped through one of my Rust projects and the best use case I saw was for serializing messages for disk / network / IPC: // This derive macro expands t
by ReactiveJelly 3y ago
I flipped through one of my Rust projects and the best use case I saw was for serializing messages for disk / network / IPC:
// This derive macro expands to a visitor pattern during build
#[derive (serde::Serialize)]
enum Message {
QueryFoo (QueryFoo),
MutateBar (MutateBar),
}
struct QueryFoo {
foo_id: i64,
}
// If we receive a Message::MutateBar from outside our process,
// it's a compile error for us to accidentally access the field `QueryFoo::foo_id`.
struct MutateBar {
bar_id: String,
baz_value: u32,
}
fn send_msg_as_json (tx: &mut Sender, msg: &Message) -> anyhow::Result <()> {
// The JSON serialization / deserialization is generated, too
tx.send (serde_json::to_string (msg))?;
Ok (())
}
It's possible to represent this in C++, and you can integrate FlatBuffers or whatever to auto-generate the ser/de code, but then you're not writing C++, you're writing some weird DSL and you're fighting the build system and you're teaching juniors how to install it.
I haven't seen anything in C++ that's both as easy and as airtight as a Rust enum with serde's automatic serialization macro on the top.
- gpderetta 3y agoFWIW using std::variant (or whatever is your in-house variant) to store message types is very common. Also in well designed low level binary protocols message types have a discriminant header already so often common to wrap them in an ad hoc-variant which doesn't have a separate discriminant.