1use Inner::*;
2use std::fmt;
3
4#[derive(Clone, PartialEq, Eq, Hash)]
6pub struct Method(Inner);
7
8impl Method {
9 pub const GET: Method = Method(Get);
11
12 pub const POST: Method = Method(Post);
14
15 pub const PUT: Method = Method(Put);
17
18 pub const DELETE: Method = Method(Delete);
20
21 pub const HEAD: Method = Method(Head);
23
24 pub const OPTIONS: Method = Method(Options);
26
27 pub const CONNECT: Method = Method(Connect);
29
30 pub const PATCH: Method = Method(Patch);
32
33 pub const TRACE: Method = Method(Trace);
35
36 pub fn from_bytes(src: &[u8]) -> Result<Method, InvalidMethod> {
37 match src {
38 b"" => Err(InvalidMethod {}),
39 b"GET" => Ok(Method::GET),
40 b"PUT" => Ok(Method::PUT),
41 b"POST" => Ok(Method::POST),
42 b"HEAD" => Ok(Method::HEAD),
43 b"PATCH" => Ok(Method::PATCH),
44 b"TRACE" => Ok(Method::TRACE),
45 b"DELETE" => Ok(Method::DELETE),
46 b"OPTIONS" => Ok(Method::OPTIONS),
47 b"CONNECT" => Ok(Method::CONNECT),
48 _ if src.iter().all(|b| METHOD_CHARS.contains(b)) => {
49 let string = unsafe { str::from_utf8_unchecked(src) };
51 Ok(Method(Inner::Other(string.to_owned())))
52 }
53 _ => Err(InvalidMethod {}),
54 }
55 }
56
57 #[inline]
59 pub fn as_str(&self) -> &str {
60 match self.0 {
61 Options => "OPTIONS",
62 Get => "GET",
63 Post => "POST",
64 Put => "PUT",
65 Delete => "DELETE",
66 Head => "HEAD",
67 Trace => "TRACE",
68 Connect => "CONNECT",
69 Patch => "PATCH",
70 Other(ref inline) => inline.as_str(),
71 }
72 }
73}
74
75impl Default for Method {
76 fn default() -> Method {
77 Method::GET
78 }
79}
80
81impl fmt::Debug for Method {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 f.write_str(self.as_str())
84 }
85}
86
87impl fmt::Display for Method {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 f.write_str(self.as_str())
90 }
91}
92
93#[derive(Debug)]
94#[non_exhaustive]
95pub struct InvalidMethod {}
96
97#[derive(Clone, PartialEq, Eq, Hash)]
98enum Inner {
99 Options,
100 Get,
101 Post,
102 Put,
103 Delete,
104 Head,
105 Trace,
106 Connect,
107 Patch,
108 Other(String),
109}
110
111#[rustfmt::skip]
127const METHOD_CHARS: [u8; 256] = [
128 b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'!', b'\0', b'#', b'$', b'%', b'&', b'\'', b'\0', b'\0', b'*', b'+', b'\0', b'-', b'.', b'\0', b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'\0', b'\0', b'\0', b'^', b'_', b'`', b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', b'z', b'\0', b'|', b'\0', b'~', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0' ];