Как сериализовать и десериализовать chrono::Duration?

#rust #chrono #serde

#Ржавчина #chrono #серде

Вопрос:

В моем текущем проекте я пытаюсь сохранить a chrono::Duration в структуре конфигурации, которая будет периодически сериализовываться и десериализовываться serde_json .

К сожалению, похоже, что Serialize и Deserialize не реализованы для chrono::Duration . Тем chrono не менее, говорится, что у него есть поддержка с serde помощью одной из его дополнительных функций. Я пытался использовать этот метод, но теперь компилятор жалуется на методы возврата:

 error[E0308]: mismatched types
 --> src/config.rs:6:10
  |
6 | #[derive(Serialize, Deserialize, Debug, Clone)]
  |          ^^^^^^^^^ expected struct `DateTime`, found struct `chrono::Duration`
  |
  = note: expected reference `amp;DateTime<Utc>`
         found reference `amp;'__a chrono::Duration`
  = note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src/config.rs:6:21
  |
6 | #[derive(Serialize, Deserialize, Debug, Clone)]
  |                     ^^^^^^^^^^^ expected struct `chrono::Duration`, found struct `DateTime`
  |
  = note: expected struct `chrono::Duration`
             found struct `DateTime<Utc>`
  = note: this error originates in the macro `try` (in Nightly builds, run with -Z macro-backtrace for more info)
 

Почему это происходит? Что я могу сделать, чтобы это исправить?

Вот код, о котором идет речь:

 use serde::{Serialize, Deserialize};
use chrono::{DateTime, Duration, Utc};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Config {
    pub dest_ip: String,
    #[serde(borrow)]
    pub include_paths: Vec<amp;'static std::path::Path>,
    pub exclude_paths: Vec<amp;'static std::path::Path>,
    #[serde(with = "chrono::serde::ts_seconds")]
    pub time_between_checks: Duration,
}
 

Кроме того, вот соответствующие фрагменты груза.toml:

 serde_json = "1.0.72"
serde = { version = "1.0.130", features = ["derive"] }
chrono = { version = "0.4.19", features = ["serde"]}
 

Комментарии:

1. Смотрите Этот выпуск от 2017 года github.com/chronotope/chrono/issues/117

2. ts_seconds только для DateTime экземпляров.

Ответ №1:

Вы можете использовать serde_with::DurationSeconds для сериализации. Он работает идентично ts_seconds , но поддерживает больше типов и форм сериализации.

 #[serde_with::serde_as]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Config {
    // ...
    #[serde_as(as = "serde_with::DurationSeconds<i64>")]
    pub time_between_checks: Duration,
}