//! Custom serialization/deserialization implementations. /// Use the well-known ISO 8601 format when serializing and deserializing an /// [`PrimitiveDateTime`][PrimitiveDateTime]. /// /// [PrimitiveDateTime]: ::time::PrimitiveDateTime pub mod iso8601 { use std::num::NonZeroU8; use serde::{ser::Error as _, Deserializer, Serialize, Serializer}; use time::{ format_description::well_known::{ iso8601::{Config, EncodedConfig, TimePrecision}, Iso8601, }, serde::iso8601, PrimitiveDateTime, UtcOffset, }; const FORMAT_CONFIG: EncodedConfig = Config::DEFAULT .set_time_precision(TimePrecision::Second { decimal_digits: NonZeroU8::new(3), }) .encode(); /// Serialize a [`PrimitiveDateTime`] using the well-known ISO 8601 format. pub fn serialize(date_time: &PrimitiveDateTime, serializer: S) -> Result where S: Serializer, { date_time .assume_utc() .format(&Iso8601::) .map_err(S::Error::custom)? .serialize(serializer) } /// Deserialize an [`PrimitiveDateTime`] from its ISO 8601 representation. pub fn deserialize<'a, D>(deserializer: D) -> Result where D: Deserializer<'a>, { iso8601::deserialize(deserializer).map(|offset_date_time| { let utc_date_time = offset_date_time.to_offset(UtcOffset::UTC); PrimitiveDateTime::new(utc_date_time.date(), utc_date_time.time()) }) } /// Use the well-known ISO 8601 format when serializing and deserializing an /// [`Option`][PrimitiveDateTime]. /// /// [PrimitiveDateTime]: ::time::PrimitiveDateTime pub mod option { use serde::Serialize; use time::format_description::well_known::Iso8601; use super::*; /// Serialize an [`Option`] using the well-known ISO 8601 format. pub fn serialize( date_time: &Option, serializer: S, ) -> Result where S: Serializer, { date_time .map(|date_time| date_time.assume_utc().format(&Iso8601::)) .transpose() .map_err(S::Error::custom)? .serialize(serializer) } /// Deserialize an [`Option`] from its ISO 8601 representation. pub fn deserialize<'a, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'a>, { iso8601::option::deserialize(deserializer).map(|option_offset_date_time| { option_offset_date_time.map(|offset_date_time| { let utc_date_time = offset_date_time.to_offset(UtcOffset::UTC); PrimitiveDateTime::new(utc_date_time.date(), utc_date_time.time()) }) }) } } } /// https://github.com/serde-rs/serde/issues/994#issuecomment-316895860 pub mod json_string { use serde::de::{self, Deserialize, DeserializeOwned, Deserializer}; use serde_json; /// Deserialize a string which is in json format pub fn deserialize<'de, T, D>(deserializer: D) -> Result where T: DeserializeOwned, D: Deserializer<'de>, { let j = String::deserialize(deserializer)?; serde_json::from_str(&j).map_err(de::Error::custom) } }