Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DurationSeconds w/ chrono TimeDelta errors Deserialize not implemented #758

Closed
docwilco opened this issue Jun 25, 2024 · 3 comments
Closed

Comments

@docwilco
Copy link

docwilco commented Jun 25, 2024

When trying to use DurationSeconds with chrono I get:

error[E0277]: the trait bound `TimeDelta: Deserialize<'_>` is not satisfied
    --> src/main.rs:9:9
     |
9    |     d1: Duration,
     |         ^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `TimeDelta`
     |
     = help: the following other types implement trait `Deserialize<'de>`:
               &'a Path
               &'a [u8]
               &'a str
               ()
               (T,)
               (T0, T1)
               (T0, T1, T2)
               (T0, T1, T2, T3)
             and 150 others
note: required by a bound in `next_element`
    --> C:\Users\msnpa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.203\src\de\mod.rs:1726:12
     |
1724 |     fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
     |        ------------ required by a bound in this associated function
1725 |     where
1726 |         T: Deserialize<'de>,
     |            ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element`

error[E0277]: the trait bound `TimeDelta: Deserialize<'_>` is not satisfied
    --> src/main.rs:11:9
     |
11   |     d2: TimeDelta,
     |         ^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `TimeDelta`
     |
     = help: the following other types implement trait `Deserialize<'de>`:
               &'a Path
               &'a [u8]
               &'a str
               ()
               (T,)
               (T0, T1)
               (T0, T1, T2)
               (T0, T1, T2, T3)
             and 150 others
note: required by a bound in `next_element`
    --> C:\Users\msnpa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.203\src\de\mod.rs:1726:12
     |
1724 |     fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
     |        ------------ required by a bound in this associated function
1725 |     where
1726 |         T: Deserialize<'de>,
     |            ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element`

error[E0277]: the trait bound `TimeDelta: Deserialize<'_>` is not satisfied
    --> src/main.rs:9:9
     |
9    |     d1: Duration,
     |         ^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `TimeDelta`
     |
     = help: the following other types implement trait `Deserialize<'de>`:
               &'a Path
               &'a [u8]
               &'a str
               ()
               (T,)
               (T0, T1)
               (T0, T1, T2)
               (T0, T1, T2, T3)
             and 150 others
note: required by a bound in `next_value`
    --> C:\Users\msnpa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.203\src\de\mod.rs:1865:12
     |
1863 |     fn next_value<V>(&mut self) -> Result<V, Self::Error>
     |        ---------- required by a bound in this associated function
1864 |     where
1865 |         V: Deserialize<'de>,
     |            ^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value`

error[E0277]: the trait bound `TimeDelta: Deserialize<'_>` is not satisfied
    --> src/main.rs:11:9
     |
11   |     d2: TimeDelta,
     |         ^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `TimeDelta`
     |
     = help: the following other types implement trait `Deserialize<'de>`:
               &'a Path
               &'a [u8]
               &'a str
               ()
               (T,)
               (T0, T1)
               (T0, T1, T2)
               (T0, T1, T2, T3)
             and 150 others
note: required by a bound in `next_value`
    --> C:\Users\msnpa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.203\src\de\mod.rs:1865:12
     |
1863 |     fn next_value<V>(&mut self) -> Result<V, Self::Error>
     |        ---------- required by a bound in this associated function
1864 |     where
1865 |         V: Deserialize<'de>,
     |            ^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value`

error[E0277]: the trait bound `TimeDelta: Deserialize<'_>` is not satisfied
  --> src/main.rs:5:10
   |
5  | #[derive(Deserialize)]
   |          ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `TimeDelta`
   |
   = help: the following other types implement trait `Deserialize<'de>`:
             &'a Path
             &'a [u8]
             &'a str
             ()
             (T,)
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
           and 150 others
note: required by a bound in `_serde::__private::de::missing_field`
  --> C:\Users\msnpa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.203\src\private\de.rs:25:8
   |
23 | pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
   |        ------------- required by a bound in this function
24 | where
25 |     V: Deserialize<'de>,
   |        ^^^^^^^^^^^^^^^^ required by this bound in `missing_field`
   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

source for that:

use chrono::{Duration, TimeDelta};
use serde::Deserialize;
use serde_with::serde_as;

#[derive(Deserialize)]
#[serde_as]
struct Test {
    #[serde_as(as = "DurationSeconds<i64>")]
    d1: Duration,
    #[serde_as(as = "DurationSeconds<i64>")]
    d2: TimeDelta,
}

fn main() {}

And Cargo.toml:

[package]
name = "foo"
version = "0.1.0"
edition = "2021"

[dependencies]
chrono = { version = "0.4.38", features = ["serde"] }
serde = { version = "1.0.203", features = ["derive"] }
serde_with = { version = "3.8.1", features = ["chrono","chrono_0_4"] }
@jonasbb
Copy link
Owner

jonasbb commented Jun 25, 2024

You need to switch the order of the macro annotations around. serde_as must always come before the derive. The reason is that the macro order is significant in Rust, as the macros are expanded top down. You need to place serde_as first as it must run before the derive generates all its code, as otherwise the derive will not know about the changed behavior. That should fix everything.

#[serde_as]
#[derive(Deserialize)]

@docwilco
Copy link
Author

And that was indeed the thing. Any way of making the compiler point that out?

@jonasbb
Copy link
Owner

jonasbb commented Jun 25, 2024

As far as I know this is not possible. The proc-macro cannot tell that the serde derives are "missing" (or already executed). At least not reliably. A warning cannot be printed, since there is no stable API to perform that for a proc-macro, see rust-lang/rust#54140. The only option is a full compile_error!.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants