1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::time::{Duration, SystemTime};
use util::{HttpDate, Seconds};
use ::HeaderValue;
#[derive(Debug, Clone, PartialEq, Eq, Header)]
pub struct RetryAfter(After);
#[derive(Debug, Clone, PartialEq, Eq)]
enum After {
DateTime(HttpDate),
Delay(Seconds),
}
impl RetryAfter {
pub fn date(time: SystemTime) -> RetryAfter {
RetryAfter(After::DateTime(time.into()))
}
pub fn delay(dur: Duration) -> RetryAfter {
RetryAfter(After::Delay(dur.into()))
}
}
impl ::headers_core::decode::TryFromValues for After {
fn try_from_values(values: &mut ::Values) -> Option<Self> {
let val = values.next()?;
if let Some(delay) = Seconds::from_val(val) {
return Some(After::Delay(delay));
}
let date = HttpDate::from_val(val)?;
Some(After::DateTime(date))
}
}
impl<'a> From<&'a After> for HeaderValue {
fn from(after: &'a After) -> HeaderValue {
match *after {
After::Delay(ref delay) => delay.into(),
After::DateTime(ref date) => date.into(),
}
}
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use util::HttpDate;
use super::RetryAfter;
use super::super::{test_decode};
#[test]
fn delay_decode() {
let r: RetryAfter = test_decode(&["1234"]).unwrap();
assert_eq!(
r,
RetryAfter::delay(Duration::from_secs(1234)),
);
}
macro_rules! test_retry_after_datetime {
($name:ident, $s:expr) => {
#[test]
fn $name() {
let r: RetryAfter = test_decode(&[$s]).unwrap();
let dt = "Sun, 06 Nov 1994 08:49:37 GMT".parse::<HttpDate>().unwrap();
assert_eq!(r, RetryAfter(super::After::DateTime(dt)));
}
}
}
test_retry_after_datetime!(date_decode_rfc1123, "Sun, 06 Nov 1994 08:49:37 GMT");
test_retry_after_datetime!(date_decode_rfc850, "Sunday, 06-Nov-94 08:49:37 GMT");
test_retry_after_datetime!(date_decode_asctime, "Sun Nov 6 08:49:37 1994");
}