Tags: #rust
In a previous post, I wanted to deserialise a date from a Toml file and implemented the Deserialize trait for a type NaiveDate. When I was implementing metrics, I had to do it again, but implement serialise and deserialise for NaiveDate and I found another way, possibly simpler, to serialise and deserialise NaiveDate.
First: add derive support to your Cargo.toml
Inside dependencies, make sure that derive feature is enabled
[dependencies]
serde = { version = "1.0.198", features = ["derive"] }
Second: In the struct containing the NaiveDate you want to serialise and deserialise, add #[serde(with = "naive_date_format")]
. E.g.
use crate::metrics::naive_date_format;
// ...
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct PostCounter {
pub post_id: String,
pub total: u64,
pub origins: HashSet<String>,
#[serde(with = "naive_date_format")]
pub stats_date: NaiveDate,
}
Third: Create naive_date_format function
You may figured already that naive_date_format is a function. This is a suggested implementation
mod naive_date_format {
use chrono::NaiveDate;
use serde::{self, Deserialize, Deserializer, Serializer};
const FORMAT: &str = "%Y-%m-%d";
/// Transforms a NaiveDate into a String
pub fn serialize<S>(date: &NaiveDate, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = date.format(FORMAT).to_string();
serializer.serialize_str(&s)
}
/// Transforms a String into a NaiveDate
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDate, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
NaiveDate::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
}
}
If you need a conclusion, please read again the code before the conclusion.