Explicit Deserialization of TOML Datetimes between structs and `Value` fail
I tried this code: Rust Playground Link
I expected this to happen: both the first "full" deserialization and the second "partial" deserialization behave the same.
Instead this happened: error invalid type: string \"[...]", expected a TOML datetime
Possibly related to #333 very intdirectly? At least it seems related to the weird way that Datetime objects in TOML are handled.
If I'm reading this correctly, this is a bug in deserializing a toml::Value into a struct as opposed to deserializing a &str into a struct.
If I'm reading this correctly, this is a bug in deserializing a
toml::Valueinto a struct as opposed to deserializing a&strinto a struct.
Correct.
Same with serialisation. A call of toml::Value::try_from(toml_datetime) produces a table with the magic field, rather then toml::Value::Datetime.
use serde::{Serialize, Serializer};
fn main() {
let datetime = toml::value::Datetime {
date: Some(toml::value::Date {
year: 2025,
month: 4,
day: 20,
}),
time: Some(toml::value::Time {
hour: 17,
minute: 14,
second: 69,
nanosecond: 42,
}),
offset: None,
};
let value = toml::Value::try_from(datetime).unwrap();
dbg!(&value);
assert!(value.is_table());
}
Bumped into similar problem - my idea was to have toml::Table with "intermediate" representation (similar to serde_json::Value) to parse toml in a generic place and later deserialize parts into concrete structs.
The simplest repro is:
let date_time: toml::Time = toml::Value::Datetime(toml::Datetime {
date: None,
time: Some(toml::Time {
hour: 0,
minute: 0,
second: 0,
nanosecond: 0,
}),
offset: None,
})
.try_into()?;
The culprit is that TOML's datetime doesn't round-trip via serde because it doesn't have direct representation in serde's data model and round-trip via string is not implemented.
Deserialization (aka conversion) from toml::Value into custom struct is done via Deserializer trait of Value which converts DateTime to string: https://github.com/toml-rs/toml/blob/main/crates/toml/src/value.rs#L530. However, the corresponding Visitor for DateTime accepts only struct and falls back to default rejection when called for a string: https://github.com/toml-rs/toml/blob/main/crates/toml_datetime/src/datetime.rs#L809
I guess the only option is to implement parsing from string, but I wish there was a way to preserve type in such cases...