apollo_configuration/types/
duration.rs1use std::borrow::Cow;
4use std::fmt;
5use std::str::FromStr;
6
7use derive_more::{Deref, From};
8use humantime_serde::re::humantime;
9use schemars::JsonSchema;
10use serde::de::Deserializer;
11use serde::{Deserialize, Serialize};
12
13use crate::Validate;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deref, From)]
19pub struct Duration(std::time::Duration);
20
21impl FromStr for Duration {
22 type Err = humantime::DurationError;
23
24 fn from_str(s: &str) -> Result<Self, Self::Err> {
25 humantime::parse_duration(s).map(Self)
26 }
27}
28
29impl fmt::Display for Duration {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "{}", humantime::format_duration(self.0))
32 }
33}
34
35impl<'de> Deserialize<'de> for Duration {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: Deserializer<'de>,
39 {
40 let s = String::deserialize(deserializer)?;
41 humantime::parse_duration(&s)
42 .map(Self)
43 .map_err(serde::de::Error::custom)
44 }
45}
46
47impl Serialize for Duration {
48 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: serde::Serializer,
51 {
52 humantime_serde::serialize(&self.0, serializer)
53 }
54}
55
56impl JsonSchema for Duration {
57 fn schema_name() -> Cow<'static, str> {
58 Cow::Borrowed("Duration")
59 }
60
61 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
62 String::json_schema(generator)
63 }
64}
65
66impl Validate for Duration {}
67
68#[cfg(test)]
69mod tests {
70 use super::Duration;
71 use std::str::FromStr as _;
72
73 #[test]
74 fn parse_from_str() {
75 assert_eq!(
76 Duration::from_str("5m 20s")
77 .expect("should parse")
78 .as_secs(),
79 320
80 );
81 let _err = Duration::from_str("5q").expect_err("should not parse");
82 }
83}