serde: Add deser functions for Duration from milliseconds
This commit is contained in:
parent
f3ba40a56f
commit
b27e54c7ed
@ -1,5 +1,6 @@
|
|||||||
//! De-/serialization functions for `std::time::Duration` objects
|
//! De-/serialization functions for `std::time::Duration` objects
|
||||||
|
|
||||||
|
pub mod ms;
|
||||||
pub mod opt_ms;
|
pub mod opt_ms;
|
||||||
pub mod opt_secs;
|
pub mod opt_secs;
|
||||||
pub mod secs;
|
pub mod secs;
|
||||||
|
67
crates/ruma-common/src/serde/duration/ms.rs
Normal file
67
crates/ruma-common/src/serde/duration/ms.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
//! De-/serialization functions for `Option<std::time::Duration>` objects represented as
|
||||||
|
//! milliseconds.
|
||||||
|
//!
|
||||||
|
//! Delegates to `js_int::UInt` to ensure integer size is within bounds.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use js_int::UInt;
|
||||||
|
use serde::{
|
||||||
|
de::{Deserialize, Deserializer},
|
||||||
|
ser::{Error, Serialize, Serializer},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Serializes a Duration to an integer representing seconds.
|
||||||
|
///
|
||||||
|
/// Will fail if integer is greater than the maximum integer that can be
|
||||||
|
/// unambiguously represented by an f64.
|
||||||
|
pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match UInt::try_from(duration.as_millis()) {
|
||||||
|
Ok(uint) => uint.serialize(serializer),
|
||||||
|
Err(err) => Err(S::Error::custom(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserializes an integer representing seconds into a Duration.
|
||||||
|
///
|
||||||
|
/// Will fail if integer is greater than the maximum integer that can be
|
||||||
|
/// unambiguously represented by an f64.
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
UInt::deserialize(deserializer).map(|ms| Duration::from_millis(ms.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": 3000 });
|
||||||
|
|
||||||
|
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": 7000 }));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user