I needed to deserialise a “bare” json array of arrays so I wrote the code below. It works as intended and is based on these stackoverflow questions Deserializing a DateTime from a string millisecond timestamp with serde and Rust: Deserialize a JSON array into a very simple custom table. However, I don’t know why #[serde(transparent)]
is required and what this attribute is doing.
I read the official documentation but I didn’t understand it. Can someone explain it in simpler terms?
from Serde’s Container attributes
#[serde(transparent)]
Serialize and deserialize a newtype struct or a braced struct with one field exactly the same as if its one field were serialized and deserialized by itself. Analogous to #[repr(transparent)].
from The Rustonomicon Alternative representations
#[repr(transparent)] can only be used on a struct or single-variant enum that has a single non-zero-sized field (there may be additional zero-sized fields). The effect is that the layout and ABI of the whole struct/enum is guaranteed to be the same as that one field.#[repr(transparent)] can only be used on a struct or single-variant enum that has a single non-zero-sized field (there may be additional zero-sized fields). The effect is that the layout and ABI of the whole struct/enum is guaranteed to be the same as that one field.
use chrono::{DateTime, Utc};
use serde::Deserialize;
use serde_json::{self, Result};
use serde_with::formats::Flexible;
use serde_with::TimestampSeconds;
const EMONCMS_FEED_DATA: &str = r#"
[
[
1716705669,
272430
],
[
1716705729,
272436
]
]"#;
#[serde_with::serde_as]
#[derive(Deserialize, Debug)]
pub struct Msg {
#[serde_as(as = "TimestampSeconds<String, Flexible>")]
pub date_time: DateTime<Utc>,
pub msg: i32,
}
#[derive(Deserialize, Debug)]
#[serde(transparent)]
pub struct EmoncmsMsg {
pub rows: Vec<Msg>,
}
impl EmoncmsMsg {
pub fn new(data: &str) -> Result<EmoncmsMsg> {
serde_json::from_str(data)
}
}
fn main() {
let table: EmoncmsMsg = EmoncmsMsg::new(EMONCMS_FEED_DATA).unwrap();
assert_eq!(table.rows.len(), 2);
println!("{:?}", table);
}
Output:
EmoncmsMsg { rows: [Msg { date_time: 2024-05-26T06:41:09Z, msg: 272430 }, Msg { date_time: 2024-05-26T06:42:09Z, msg: 272436 }] }