• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use bitflags::bitflags;
2 use http::Method;
3 use std::{
4     fmt,
5     fmt::{Debug, Formatter},
6 };
7 
8 bitflags! {
9     /// A filter that matches one or more HTTP methods.
10     pub struct MethodFilter: u16 {
11         /// Match `DELETE` requests.
12         const DELETE =  0b000000010;
13         /// Match `GET` requests.
14         const GET =     0b000000100;
15         /// Match `HEAD` requests.
16         const HEAD =    0b000001000;
17         /// Match `OPTIONS` requests.
18         const OPTIONS = 0b000010000;
19         /// Match `PATCH` requests.
20         const PATCH =   0b000100000;
21         /// Match `POST` requests.
22         const POST =    0b001000000;
23         /// Match `PUT` requests.
24         const PUT =     0b010000000;
25         /// Match `TRACE` requests.
26         const TRACE =   0b100000000;
27     }
28 }
29 
30 /// Error type used when converting a [`Method`] to a [`MethodFilter`] fails.
31 #[derive(Debug)]
32 pub struct NoMatchingMethodFilter {
33     method: Method,
34 }
35 
36 impl NoMatchingMethodFilter {
37     /// Get the [`Method`] that couldn't be converted to a [`MethodFilter`].
method(&self) -> &Method38     pub fn method(&self) -> &Method {
39         &self.method
40     }
41 }
42 
43 impl fmt::Display for NoMatchingMethodFilter {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result44     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
45         write!(f, "no `MethodFilter` for `{}`", self.method.as_str())
46     }
47 }
48 
49 impl std::error::Error for NoMatchingMethodFilter {}
50 
51 impl TryFrom<Method> for MethodFilter {
52     type Error = NoMatchingMethodFilter;
53 
try_from(m: Method) -> Result<Self, NoMatchingMethodFilter>54     fn try_from(m: Method) -> Result<Self, NoMatchingMethodFilter> {
55         match m {
56             Method::DELETE => Ok(MethodFilter::DELETE),
57             Method::GET => Ok(MethodFilter::GET),
58             Method::HEAD => Ok(MethodFilter::HEAD),
59             Method::OPTIONS => Ok(MethodFilter::OPTIONS),
60             Method::PATCH => Ok(MethodFilter::PATCH),
61             Method::POST => Ok(MethodFilter::POST),
62             Method::PUT => Ok(MethodFilter::PUT),
63             Method::TRACE => Ok(MethodFilter::TRACE),
64             other => Err(NoMatchingMethodFilter { method: other }),
65         }
66     }
67 }
68 
69 #[cfg(test)]
70 mod tests {
71     use super::*;
72 
73     #[test]
from_http_method()74     fn from_http_method() {
75         assert_eq!(
76             MethodFilter::try_from(Method::DELETE).unwrap(),
77             MethodFilter::DELETE
78         );
79 
80         assert_eq!(
81             MethodFilter::try_from(Method::GET).unwrap(),
82             MethodFilter::GET
83         );
84 
85         assert_eq!(
86             MethodFilter::try_from(Method::HEAD).unwrap(),
87             MethodFilter::HEAD
88         );
89 
90         assert_eq!(
91             MethodFilter::try_from(Method::OPTIONS).unwrap(),
92             MethodFilter::OPTIONS
93         );
94 
95         assert_eq!(
96             MethodFilter::try_from(Method::PATCH).unwrap(),
97             MethodFilter::PATCH
98         );
99 
100         assert_eq!(
101             MethodFilter::try_from(Method::POST).unwrap(),
102             MethodFilter::POST
103         );
104 
105         assert_eq!(
106             MethodFilter::try_from(Method::PUT).unwrap(),
107             MethodFilter::PUT
108         );
109 
110         assert_eq!(
111             MethodFilter::try_from(Method::TRACE).unwrap(),
112             MethodFilter::TRACE
113         );
114 
115         assert!(MethodFilter::try_from(http::Method::CONNECT)
116             .unwrap_err()
117             .to_string()
118             .contains("CONNECT"));
119     }
120 }
121