http_types/other/
expect.rs1use crate::ensure_eq_status;
2use crate::headers::{HeaderName, HeaderValue, Headers, ToHeaderValues, EXPECT};
3
4use std::fmt::Debug;
5use std::option;
6
7#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
34pub struct Expect {
35 _priv: (),
36}
37
38impl Expect {
39 pub fn new() -> Self {
41 Self { _priv: () }
42 }
43
44 pub fn from_headers(headers: impl AsRef<Headers>) -> crate::Result<Option<Self>> {
46 let headers = match headers.as_ref().get(EXPECT) {
47 Some(headers) => headers,
48 None => return Ok(None),
49 };
50
51 let header = headers.iter().last().unwrap();
54 ensure_eq_status!(header, "100-continue", 400, "malformed `Expect` header");
55
56 Ok(Some(Self { _priv: () }))
57 }
58
59 pub fn apply(&self, mut headers: impl AsMut<Headers>) {
61 headers.as_mut().insert(EXPECT, self.value());
62 }
63
64 pub fn name(&self) -> HeaderName {
66 EXPECT
67 }
68
69 pub fn value(&self) -> HeaderValue {
71 let value = "100-continue";
72 unsafe { HeaderValue::from_bytes_unchecked(value.into()) }
74 }
75}
76
77impl ToHeaderValues for Expect {
78 type Iter = option::IntoIter<HeaderValue>;
79 fn to_header_values(&self) -> crate::Result<Self::Iter> {
80 Ok(self.value().to_header_values().unwrap())
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use crate::headers::Headers;
89
90 #[test]
91 fn smoke() -> crate::Result<()> {
92 let expect = Expect::new();
93
94 let mut headers = Headers::new();
95 expect.apply(&mut headers);
96
97 let expect = Expect::from_headers(headers)?.unwrap();
98 assert_eq!(expect, Expect::new());
99 Ok(())
100 }
101
102 #[test]
103 fn bad_request_on_parse_error() {
104 let mut headers = Headers::new();
105 headers.insert(EXPECT, "<nori ate the tag. yum.>");
106 let err = Expect::from_headers(headers).unwrap_err();
107 assert_eq!(err.status(), 400);
108 }
109}