1use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, AGE};
2use crate::Status;
3
4use std::fmt::Debug;
5use std::option;
6use std::time::Duration;
7
8#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
33pub struct Age {
34 dur: Duration,
35}
36
37impl Age {
38 pub fn new(dur: Duration) -> Self {
40 Self { dur }
41 }
42
43 pub fn from_secs(secs: u64) -> Self {
45 let dur = Duration::from_secs(secs);
46 Self { dur }
47 }
48
49 pub fn duration(&self) -> Duration {
51 self.dur
52 }
53
54 pub fn from_headers(headers: impl AsRef<Headers>) -> crate::Result<Option<Self>> {
56 let headers = match headers.as_ref().get(AGE) {
57 Some(headers) => headers,
58 None => return Ok(None),
59 };
60
61 let header = headers.iter().last().unwrap();
64
65 let num: u64 = header.as_str().parse().status(400)?;
66 let dur = Duration::from_secs_f64(num as f64);
67
68 Ok(Some(Self { dur }))
69 }
70
71 pub fn apply(&self, mut headers: impl AsMut<Headers>) {
73 headers.as_mut().insert(AGE, self.value());
74 }
75
76 pub fn name(&self) -> HeaderName {
78 AGE
79 }
80
81 pub fn value(&self) -> HeaderValue {
83 let output = self.dur.as_secs().to_string();
84
85 unsafe { HeaderValue::from_bytes_unchecked(output.into()) }
87 }
88}
89
90impl ToHeaderValues for Age {
91 type Iter = option::IntoIter<HeaderValue>;
92 fn to_header_values(&self) -> crate::Result<Self::Iter> {
93 Ok(self.value().to_header_values().unwrap())
95 }
96}
97
98#[cfg(test)]
99mod test {
100 use super::*;
101 use crate::headers::Headers;
102
103 #[test]
104 fn smoke() -> crate::Result<()> {
105 let age = Age::new(Duration::from_secs(12));
106
107 let mut headers = Headers::new();
108 age.apply(&mut headers);
109
110 let age = Age::from_headers(headers)?.unwrap();
111 assert_eq!(age, Age::new(Duration::from_secs(12)));
112 Ok(())
113 }
114
115 #[test]
116 fn bad_request_on_parse_error() {
117 let mut headers = Headers::new();
118 headers.insert(AGE, "<nori ate the tag. yum.>");
119 let err = Age::from_headers(headers).unwrap_err();
120 assert_eq!(err.status(), 400);
121 }
122}