[Thiago Cafe] Programming is fun!

Another way to deserialise DateTime in Rust

Created by Thiago Guedes on 2024-06-02 20:53:59

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)
    }
}

Conclusion

If you need a conclusion, please read again the code before the conclusion.

Tell me your opinion!

Reach me on Twitter - @thiedri