rama_http_headers/util/
seconds.rs1use std::fmt;
2use std::time::Duration;
3
4use rama_http_types::HeaderValue;
5
6use crate::Error;
7use crate::util::IterExt;
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Seconds(u64);
11
12impl Seconds {
13 #[must_use]
14 pub fn new(seconds: u64) -> Self {
15 Self(seconds)
16 }
17
18 #[must_use]
19 pub fn try_from_val(val: &HeaderValue) -> Option<Self> {
20 let secs = val.to_str().ok()?.parse().ok()?;
21
22 Some(Self::new(secs))
23 }
24
25 #[must_use]
26 pub fn try_from_duration(dur: Duration) -> Option<Self> {
27 if dur.subsec_nanos() != 0 {
28 return None;
29 }
30 Some(Self::new(dur.as_secs()))
31 }
32
33 #[must_use]
34 pub fn from_duration_rounded(dur: Duration) -> Self {
35 Self::new(dur.as_secs())
36 }
37
38 #[must_use]
39 pub fn as_duration(self) -> Duration {
40 Duration::from_secs(self.0)
41 }
42
43 #[must_use]
44 pub fn as_u64(self) -> u64 {
45 self.0
46 }
47}
48
49impl super::TryFromValues for Seconds {
50 fn try_from_values<'i, I>(values: &mut I) -> Result<Self, Error>
51 where
52 I: Iterator<Item = &'i HeaderValue>,
53 {
54 values
55 .just_one()
56 .and_then(Self::try_from_val)
57 .ok_or_else(Error::invalid)
58 }
59}
60
61impl<'a> From<&'a Seconds> for HeaderValue {
62 fn from(secs: &'a Seconds) -> Self {
63 secs.as_u64().into()
64 }
65}
66
67impl From<Seconds> for Duration {
68 fn from(secs: Seconds) -> Self {
69 secs.as_duration()
70 }
71}
72
73impl From<Seconds> for u64 {
74 fn from(secs: Seconds) -> Self {
75 secs.as_u64()
76 }
77}
78
79impl fmt::Debug for Seconds {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 write!(f, "{}s", self.as_u64())
82 }
83}
84
85impl fmt::Display for Seconds {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 fmt::Display::fmt(&self.as_u64(), f)
88 }
89}