use humantime::parse_duration;
use serde::{Deserialize, Deserializer, Serializer};
use std::time::Duration;
pub fn serialize<S>(duration: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Some(d) = duration {
serializer.serialize_str(&format!("{}s", d.as_secs()))
} else {
serializer.serialize_none()
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_option(DurationOptionVisitor)
}
struct DurationOptionVisitor;
impl<'de> serde::de::Visitor<'de> for DurationOptionVisitor {
type Value = Option<Duration>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Invalid duration string, supported formats like 5s, 3m, 6h")
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
parse_duration(&s)
.map(Some)
.map_err(serde::de::Error::custom)
}
}