rama-http-headers 0.3.0-rc1

typed http headers for rama
Documentation
use std::fmt;
use std::time::Duration;

use rama_http_types::HeaderValue;

use crate::Error;
use crate::util::IterExt;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Seconds(u64);

impl Seconds {
    #[must_use]
    pub fn new(seconds: u64) -> Self {
        Self(seconds)
    }

    #[must_use]
    pub fn try_from_val(val: &HeaderValue) -> Option<Self> {
        let secs = val.to_str().ok()?.parse().ok()?;

        Some(Self::new(secs))
    }

    #[must_use]
    pub fn try_from_duration(dur: Duration) -> Option<Self> {
        if dur.subsec_nanos() != 0 {
            return None;
        }
        Some(Self::new(dur.as_secs()))
    }

    #[must_use]
    pub fn from_duration_rounded(dur: Duration) -> Self {
        Self::new(dur.as_secs())
    }

    #[must_use]
    pub fn as_duration(self) -> Duration {
        Duration::from_secs(self.0)
    }

    #[must_use]
    pub fn as_u64(self) -> u64 {
        self.0
    }
}

impl super::TryFromValues for Seconds {
    fn try_from_values<'i, I>(values: &mut I) -> Result<Self, Error>
    where
        I: Iterator<Item = &'i HeaderValue>,
    {
        values
            .just_one()
            .and_then(Self::try_from_val)
            .ok_or_else(Error::invalid)
    }
}

impl<'a> From<&'a Seconds> for HeaderValue {
    fn from(secs: &'a Seconds) -> Self {
        secs.as_u64().into()
    }
}

impl From<Seconds> for Duration {
    fn from(secs: Seconds) -> Self {
        secs.as_duration()
    }
}

impl From<Seconds> for u64 {
    fn from(secs: Seconds) -> Self {
        secs.as_u64()
    }
}

impl fmt::Debug for Seconds {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}s", self.as_u64())
    }
}

impl fmt::Display for Seconds {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.as_u64(), f)
    }
}