use std::{
fmt::{self, Formatter},
time::Duration,
};
use serde::{
de::{self},
Deserializer, Serialize, Serializer,
};
use super::forward_visitor;
pub(crate) fn serialize<S>(duration: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
duration
.map(crate::duration::to_string)
.serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(Visitor)
}
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Option<Duration>;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("integer representing microseconds or a duration string")
}
forward_visitor! {
visit_u64,
visit_i64: i64,
visit_i128: i128,
visit_u128: u128,
}
fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
Ok(Some(Duration::from_micros(v)))
}
fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
deserializer.deserialize_any(self)
}
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
crate::duration::parse(v).map(Some).map_err(E::custom)
}
}