prover-utils 1.0.0

prover-utils offers utility functions and structs, used in prover-engine.
Documentation
use std::time::Duration;

use serde_with::serde_conv;

serde_conv!(pub HumanDuration, Duration, HumanDurationImpl::new, HumanDurationImpl::get);

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)]
#[serde(untagged)]
enum HumanDurationImpl {
    Secs(u64),
    Human(#[serde(with = "humantime_serde")] Duration),
}

impl HumanDurationImpl {
    fn new(value: &Duration) -> Self {
        Self::Human(*value)
    }

    pub fn get(self) -> Result<Duration, std::convert::Infallible> {
        match self {
            Self::Secs(secs) => Ok(Duration::from_secs(secs)),
            Self::Human(duration) => Ok(duration),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::time::Duration;

    use toml::toml;

    #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
    struct TestConfig {
        #[serde(with = "super::HumanDuration")]
        time: Duration,
    }

    impl TestConfig {
        fn from_secs(secs: u64) -> Self {
            let time = Duration::from_secs(secs);
            Self { time }
        }

        fn from_toml(value: toml::Value) -> Result<Self, toml::de::Error> {
            value.try_into()
        }

        fn to_toml(&self) -> toml::Value {
            toml::Value::try_from(self).unwrap()
        }
    }

    #[test]
    fn serialize() {
        assert_eq!(
            (TestConfig::from_secs(10)).to_toml(),
            toml!(time = "10s").into(),
        );
        assert_eq!(
            (TestConfig::from_secs(60)).to_toml(),
            toml!(time = "1m").into(),
        );
        assert_eq!(
            (TestConfig::from_secs(600)).to_toml(),
            toml!(time = "10m").into(),
        );
        assert_eq!(
            (TestConfig::from_secs(601)).to_toml(),
            toml!(time = "10m 1s").into(),
        );
        assert_eq!(
            (TestConfig::from_secs(3600)).to_toml(),
            toml!(time = "1h").into(),
        );
    }

    #[test]
    fn deserialize() {
        assert_eq!(
            TestConfig::from_secs(10),
            TestConfig::from_toml(toml!(time = 10).into()).unwrap(),
        );
        assert_eq!(
            TestConfig::from_secs(10),
            TestConfig::from_toml(toml!(time = "10s").into()).unwrap(),
        );
        assert_eq!(
            TestConfig::from_toml(toml!(time = 70).into()).unwrap(),
            TestConfig::from_toml(toml!(time = "1min 10s").into()).unwrap(),
        );
        assert!(TestConfig::from_toml("10s".into()).is_err());
        assert!(TestConfig::from_toml(10.into()).is_err());
    }
}