flagsmith_flag_engine/utils/
datetime.rs1use chrono::{DateTime, Utc};
4use serde::{self, Deserialize, Deserializer, Serializer};
5
6pub fn serialize<S>(date: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>
7where
8 S: Serializer,
9{
10 serializer.serialize_str(&date.to_rfc3339())
11}
12
13pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
14where
15 D: Deserializer<'de>,
16{
17 let s = String::deserialize(deserializer)?;
18 let datetime = match DateTime::parse_from_rfc3339(&s) {
19 Ok(datetime) => datetime,
20 Err(error) => match error.to_string().as_str() {
23 "premature end of input" => {
24 let datetime_str = s + "Z";
25 DateTime::parse_from_rfc3339(&datetime_str).map_err(serde::de::Error::custom)?
26 }
27 _ => panic!("Invalid datetime"),
28 },
29 };
30 let datatime_utc = datetime.with_timezone(&Utc);
31 return Ok(datatime_utc);
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use crate::utils;
38 use chrono::Utc;
39 use rstest::*;
40 use serde::Serialize;
41
42 #[rstest]
43 #[case(serde_json::json!({"datetime":"2021-11-29T17:15:51.694223Z"}))]
44 #[case(serde_json::json!({"datetime":"2021-11-29T17:15:51.694223"}))]
45 #[case(serde_json::json!({"datetime":"2021-11-29T17:15:51.694223+00:00"}))]
46 fn serialize_deserialize_datetime(#[case] given_datetime: serde_json::Value) {
47 #[derive(Serialize, Deserialize)]
49 struct AStruct {
50 #[serde(with = "utils::datetime")]
51 datetime: DateTime<Utc>,
52 }
53
54 let deserialized_struct: AStruct = serde_json::from_value(given_datetime.clone()).unwrap();
56
57 assert_eq!(deserialized_struct.datetime.timezone(), Utc);
59
60 let serialized_struct = serde_json::to_value(deserialized_struct).unwrap();
62 assert_eq!(
63 serialized_struct,
64 serde_json::json!({"datetime":"2021-11-29T17:15:51.694223+00:00"})
65 );
66 }
67}