diff --git a/src/time_delta.rs b/src/time_delta.rs index 88aa31c6e..d03068969 100644 --- a/src/time_delta.rs +++ b/src/time_delta.rs @@ -638,6 +638,47 @@ impl arbitrary::Arbitrary<'_> for TimeDelta { } } +#[cfg(feature = "serde")] +mod serde { + use super::TimeDelta; + use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; + + impl Serialize for TimeDelta { + fn serialize(&self, serializer: S) -> Result { + <(i64, i32) as Serialize>::serialize(&(self.secs, self.nanos), serializer) + } + } + + impl<'de> Deserialize<'de> for TimeDelta { + fn deserialize>(deserializer: D) -> Result { + let (secs, nanos) = <(i64, i32) as Deserialize>::deserialize(deserializer)?; + TimeDelta::new(secs, nanos as u32).ok_or(Error::custom("TimeDelta out of bounds")) + } + } + + #[cfg(test)] + mod tests { + use super::{super::MAX, TimeDelta}; + + #[test] + fn test_serde() { + let duration = TimeDelta::new(123, 456).unwrap(); + assert_eq!( + serde_json::from_value::(serde_json::to_value(duration).unwrap()) + .unwrap(), + duration + ); + } + + #[test] + #[should_panic(expected = "TimeDelta out of bounds")] + fn test_serde_oob_panic() { + let _ = + serde_json::from_value::(serde_json::json!([MAX.secs + 1, 0])).unwrap(); + } + } +} + #[cfg(test)] mod tests { use super::OutOfRangeError;