Skip to main content

prover_utils/with/
human_duration.rs

1use std::time::Duration;
2
3use serde_with::serde_conv;
4
5serde_conv!(pub HumanDuration, Duration, HumanDurationImpl::new, HumanDurationImpl::get);
6
7#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)]
8#[serde(untagged)]
9enum HumanDurationImpl {
10    Secs(u64),
11    Human(#[serde(with = "humantime_serde")] Duration),
12}
13
14impl HumanDurationImpl {
15    fn new(value: &Duration) -> Self {
16        Self::Human(*value)
17    }
18
19    pub fn get(self) -> Result<Duration, std::convert::Infallible> {
20        match self {
21            Self::Secs(secs) => Ok(Duration::from_secs(secs)),
22            Self::Human(duration) => Ok(duration),
23        }
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use std::time::Duration;
30
31    use toml::toml;
32
33    #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
34    struct TestConfig {
35        #[serde(with = "super::HumanDuration")]
36        time: Duration,
37    }
38
39    impl TestConfig {
40        fn from_secs(secs: u64) -> Self {
41            let time = Duration::from_secs(secs);
42            Self { time }
43        }
44
45        fn from_toml(value: toml::Value) -> Result<Self, toml::de::Error> {
46            value.try_into()
47        }
48
49        fn to_toml(&self) -> toml::Value {
50            toml::Value::try_from(self).unwrap()
51        }
52    }
53
54    #[test]
55    fn serialize() {
56        assert_eq!(
57            (TestConfig::from_secs(10)).to_toml(),
58            toml!(time = "10s").into(),
59        );
60        assert_eq!(
61            (TestConfig::from_secs(60)).to_toml(),
62            toml!(time = "1m").into(),
63        );
64        assert_eq!(
65            (TestConfig::from_secs(600)).to_toml(),
66            toml!(time = "10m").into(),
67        );
68        assert_eq!(
69            (TestConfig::from_secs(601)).to_toml(),
70            toml!(time = "10m 1s").into(),
71        );
72        assert_eq!(
73            (TestConfig::from_secs(3600)).to_toml(),
74            toml!(time = "1h").into(),
75        );
76    }
77
78    #[test]
79    fn deserialize() {
80        assert_eq!(
81            TestConfig::from_secs(10),
82            TestConfig::from_toml(toml!(time = 10).into()).unwrap(),
83        );
84        assert_eq!(
85            TestConfig::from_secs(10),
86            TestConfig::from_toml(toml!(time = "10s").into()).unwrap(),
87        );
88        assert_eq!(
89            TestConfig::from_toml(toml!(time = 70).into()).unwrap(),
90            TestConfig::from_toml(toml!(time = "1min 10s").into()).unwrap(),
91        );
92        assert!(TestConfig::from_toml("10s".into()).is_err());
93        assert!(TestConfig::from_toml(10.into()).is_err());
94    }
95}