use std::time::Duration;
use js_int::UInt;
use serde::{
de::{Deserialize, Deserializer},
ser::{Error, Serialize, Serializer},
};
pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match UInt::try_from(duration.as_secs()) {
Ok(uint) => uint.serialize(serializer),
Err(err) => Err(S::Error::custom(err)),
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
{
UInt::deserialize(deserializer).map(|secs| Duration::from_secs(secs.into()))
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
struct DurationTest {
#[serde(with = "super")]
timeout: Duration,
}
#[test]
fn deserialize() {
let json = json!({ "timeout": 3 });
assert_eq!(
serde_json::from_value::<DurationTest>(json).unwrap(),
DurationTest { timeout: Duration::from_secs(3) },
);
}
#[test]
fn serialize() {
let test = DurationTest { timeout: Duration::from_millis(7000) };
assert_eq!(serde_json::to_value(test).unwrap(), json!({ "timeout": 7 }));
}
}