Unexpected behavior of `time::serde::rfc3339::option::deserialize()`
OrangeTux opened this issue · 3 comments
When deserializing some data into a struct, serde
doesn't care if an field with type Option<T>
is available in the source bytes or not.
For example, the following code works fine. It parses an empty json string {}
as a Passes
instance.
// Relies on serde and serde-json.
// Code runs fine.
use serde::Deserialize;
use serde_json::json;
#[derive(Deserialize, Debug)]
struct Passes {
attribute: Option<i32>,
}
fn main() {
let source = json!({});
let concrete_type: Passes = serde_json::from_value(source).unwrap();
dbg!(concrete_type);
I would expect the same behavior for something of type Option<time::OffsetDateTime>
. But that type behaves different when using the time::serde::rfc3339::option::deserialize
. Consider the following code. When you run it, it'll panic. The code tries to deserialize an empty {}
as a struct Fails
. And that fails. serde
claims that fields datetime
is missing. Although the attribute being Option
al,
/// relies on serde, serde-json and time.
use time::OffsetDateTime;
use serde::Deserialize;
use serde_json::json;
#[derive(Deserialize, Debug)]
struct Fails {
#[serde(with = "time::serde::rfc3339::option")]
datetime: Option<OffsetDateTime>,
}
fn main() {
let source = json!({});
/// Code panics here.
let concrete_type: Fails = serde_json::from_value(source).unwrap();
}
The failure is:
thread 'main' panicked at src/main.rs:27:63:
called `Result::unwrap()` on an `Err` value: Error("missing field `datetime`", line: 0, column: 0)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Is this is bug? Shouldn't datetime
be set to None
when the field is not present input that's passed to serde_jsoin:from_value()
?
If so, I'm happy to provide a PR to fix the behavior.
Note, I'm aware that I can work around the issue by changing the field attribute of Fails.datetime
from 'm aware that I can work around #[serde(with = "time::serde::rfc3339::option")]
to #[serde(with = "time::serde::rfc3339::option", default)]
This has been brought up before, and I'm not aware of how to fix it. My recommendation has always been to use #[serde(default)]
. If there is a better way, I'm more than happy to review a PR.
Thanks for the response. I'll have try to find a fix. Bit since you're aware of the issue and don't know a solution, I'm doubt that I'll fine a solution.