Rust Pattern: serde tags
March 15, 2026
(I’m going to try and post more “Rust learning moments” on here, feedback welcome on mastodon 😀)
Some protocols – including the Fowl frontend protocol – encode things as JSON, and include a "type" (or in my case "kind") attribute to tell you what sort of message this is.
For example:
{
"kind": "set-code",
"code": "999-foo-bar"
}
For a naive implementation in Rust, it’s nice to use an enum for this:
enum FowlCommand {
SetCode(String),
}
Looking ahead just a little bit, maybe we want slightly more structure so that the names match up:
enum FowlCommand {
AllocateCode {},
SetCode { code: String },
}
As pointed out to me on ##rust on Libera, serde has a built-in way to deal with this, called an internally tagged enum. This means that we can add a few things to the above and get a fully working “JSON to Rust datastructure” working:
#[derive(Debug, Serialize)]
#[serde(tag = "kind")]
enum FowlCommand {
#[serde(rename = "allocate-code")]
AllocateCode {},
#[serde(rename = "set-code")]
SetCode { code: String },
}
This will then emit JSON like {"kind": "set-code", "code": "999-foo-bar"} to match the fowld front-end control protocol.
Neat!
txtorcon
carml
cuv’ner