#![forbid(unsafe_code)]
use std::fmt;
use std::time::Duration;
use humantime;
use serde::{Deserializer, Serializer, de};
pub fn deserialize<'a, D>(d: D) -> Result<Duration, D::Error>
where
D: Deserializer<'a>,
{
struct V;
impl de::Visitor<'_> for V {
type Value = Duration;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("a duration")
}
fn visit_str<E>(self, v: &str) -> Result<Duration, E>
where
E: de::Error,
{
humantime::parse_duration(v)
.map_err(|_| E::invalid_value(de::Unexpected::Str(v), &self))
}
}
d.deserialize_str(V)
}
pub fn serialize<S>(d: &Duration, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.collect_str(&humantime::format_duration(*d))
}
pub mod option {
use std::time::Duration;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S>(d: &Option<Duration>, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match d {
Some(d) => super::serialize(d, s),
None => s.serialize_none(),
}
}
pub fn deserialize<'a, D>(d: D) -> Result<Option<Duration>, D::Error>
where
D: Deserializer<'a>,
{
struct Wrapper(Duration);
impl<'de> Deserialize<'de> for Wrapper {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
super::deserialize(d).map(Wrapper)
}
}
let v: Option<Wrapper> = Option::deserialize(d)?;
Ok(v.map(|Wrapper(d)| d))
}
}
#[cfg(test)]
#[path = "humantime_serde_tests.rs"]
mod humantime_serde_tests;