DEV Community

Thiago Massari Guedes
Thiago Massari Guedes

Posted on

4

How to deserialise DateTime from toml configuration

When implementing a new configuration parameter for Texted, I needed something to represent the date the blog started.

When looking into the TOML website, I was fortunate to discover that it has a data type for dates, so I could create the new parameter

blog_start_date = 2016-06-25
Enter fullscreen mode Exit fullscreen mode

However, my fortune was gone as I found that the Toml crate does not support deserialising.

First, I tried to find if any other crate implemented this, but I found nothing that worked and most of them were over complicated for my use case.

Then I thought, I am pretty sure I am not the only one with this need and with some searching, I found in Arnau Siches website a nice solution for what I needed and I am sharing here a slightly modified version of their solution

use std::str::FromStr;  

use chrono::{NaiveDate, ParseError};  
use serde::Deserialize;  

// Code adapted from https://www.seachess.net/notes/toml-dates/  
#[derive(Copy, Clone, PartialEq, Debug)]  
pub struct TomlDate(pub NaiveDate);  

impl<'de> Deserialize<'de> for TomlDate {  
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>  
        where  
            D: serde::Deserializer<'de>,  
    {  
        use serde::de::Error;  
        let value = toml::value::Datetime::deserialize(deserializer)?;  
        let date = TomlDate::from_str(&value.to_string()).map_err(Error::custom)?;  
        Ok(date)  
    }  
}  

impl FromStr for TomlDate {  
    type Err = ParseError;  

    fn from_str(s: &str) -> Result<Self, Self::Err> {  
        let naive = NaiveDate::from_str(s)?;  
        Ok(Self(naive))  
    }  
}
Enter fullscreen mode Exit fullscreen mode

Of course, one small unit test to make sure it works.

#[cfg(test)]  
mod tests {  
    use serde::Deserialize;  

    use super::*;  

    #[derive(Deserialize)]  
    pub struct Personal {  
        pub activity_start_year: i32,  
        pub blog_start_date: TomlDate,  
    }  

    #[derive(Deserialize)]  
    pub struct Config {  
        pub personal: Personal,  
    }  

    #[test]  
    fn test_date_time() {  
        let toml_str = r##"  
[personal]  
activity_start_year = 2000  
blog_start_date = 2024-04-22  
"##;  
        let cfg: Config = toml::from_str::<Config>(toml_str).unwrap();  
        assert_eq!(cfg.personal.blog_start_date, TomlDate(NaiveDate::from_ymd_opt(2024, 04, 22).unwrap()));  
    }  
}
Enter fullscreen mode Exit fullscreen mode

To conclude, please note that this code was adapted from a CC BY-NC 4.0 license

Link to author's blog: thiagocafe/How to deserialise DateTime from toml configuration

Please leave your appreciation by commenting on this post!

I can do that

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

đź‘‹ Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay