Flattening and capturing extras in Rust
flatten merges a nested struct into the parent, or sweeps up unknown keys.
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize)]
struct Common {
id: u32,
created: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct Record {
#[serde(flatten)]
common: Common,
name: String,
#[serde(flatten)]
extra: HashMap<String, serde_json::Value>,
}
fn main() -> Result<(), serde_json::Error> {
let raw = r#"{"id":7,"created":"2026-07-29","name":"ada",
"streak":12}"#;
let record: Record = serde_json::from_str(raw)?;
println!("{} {}", record.common.id, record.name);
println!("{:?}", record.extra.get("streak"));
Ok(())
}
How it works
flattenon a struct field inlines its keys.flattenon a map collects everything not otherwise named.- This is how you model an envelope plus a payload.
Keywords and builtins used here
CommonHashMapOkRecordResultStringfnletmainstructu32use
The run, in numbers
- Lines
- 26
- Characters to type
- 596
- Tokens
- 139
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 79 seconds.
Step 3 of 3 in Field attributes, step 6 of 11 in Serde & JSON.