1mod constants;
2mod invalid;
3mod kind;
4
5use self::kind::MethodKind;
6use shared_bytes::SharedStr;
7use std::{fmt, sync::Arc};
8
9pub use self::invalid::InvalidMethod;
10
11#[derive(Debug, Clone, PartialEq, Hash)]
12pub struct Method(MethodKind);
13
14impl Method {
15 fn internal_try_from(string: SharedStr) -> Result<Self, InvalidMethod> {
16 match MethodKind::standard(string.as_str()) {
17 Some(kind) => Ok(Self(kind)),
18 None => Self::internal_try_from_extension(string),
19 }
20 }
21
22 fn internal_try_from_extension(string: SharedStr) -> Result<Self, InvalidMethod> {
23 match validate(string.as_bytes()) {
24 Ok(()) => Ok(Self(MethodKind::Extension(string))),
25 Err(e) => Err(e),
26 }
27 }
28
29 fn try_from_string(value: String) -> Result<Self, InvalidMethod> {
30 match MethodKind::standard(&value) {
31 Some(kind) => Ok(Self(kind)),
32 None => Self::internal_try_from_extension(value.into()),
33 }
34 }
35
36 #[inline]
37 pub fn as_str(&self) -> &str {
38 self.0.as_str()
39 }
40}
41
42impl AsRef<str> for Method {
43 #[inline]
44 fn as_ref(&self) -> &str {
45 self.as_str()
46 }
47}
48
49impl Eq for Method {}
50
51impl PartialEq<str> for Method {
52 fn eq(&self, other: &str) -> bool {
53 self.as_str() == other
54 }
55}
56
57impl PartialEq<String> for Method {
58 fn eq(&self, other: &String) -> bool {
59 self.as_str() == other
60 }
61}
62
63impl<T> PartialEq<&'_ T> for Method
64where
65 Self: PartialEq<T>,
66 T: ?Sized,
67{
68 fn eq(&self, other: &&T) -> bool {
69 self.eq(*other)
70 }
71}
72
73impl TryFrom<&'static str> for Method {
74 type Error = InvalidMethod;
75
76 fn try_from(x: &'static str) -> Result<Self, Self::Error> {
77 Self::internal_try_from(SharedStr::from_static(x))
78 }
79}
80
81impl TryFrom<String> for Method {
82 type Error = InvalidMethod;
83
84 fn try_from(value: String) -> Result<Self, Self::Error> {
85 Self::try_from_string(value)
86 }
87}
88
89impl TryFrom<Arc<String>> for Method {
90 type Error = InvalidMethod;
91
92 fn try_from(value: Arc<String>) -> Result<Self, Self::Error> {
93 Self::internal_try_from(value.into())
94 }
95}
96
97impl TryFrom<SharedStr> for Method {
98 type Error = InvalidMethod;
99
100 fn try_from(value: SharedStr) -> Result<Self, Self::Error> {
101 Self::internal_try_from(value)
102 }
103}
104
105impl Default for Method {
106 fn default() -> Self {
107 Method::GET
108 }
109}
110
111impl fmt::Display for Method {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 self.as_str().fmt(f)
114 }
115}
116
117fn validate(bytes: &[u8]) -> Result<(), InvalidMethod> {
118 match crate::rfc::token::validate(bytes) {
119 Ok(()) => Ok(()),
120 Err(e) => Err(InvalidMethod { byte: e.byte }),
121 }
122}