1use serde::de::{self, Deserialize, Deserializer, Unexpected};
17use serde::ser::{Serialize, Serializer};
18use std::borrow::Borrow;
19use std::error::Error;
20use std::fmt;
21use std::str::FromStr;
22
23#[cfg(test)]
24mod test;
25
26#[rustfmt::skip]
30static VALID_CHARS: [u8; 256] = [
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b'+', 0, b'-', b'.', b'/', b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', 0, 0, 0, 0, 0, 0, 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', 0, 0, 0, 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', 0, 0, 0, b'~', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
59
60#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
64pub struct BearerToken(String);
65
66impl BearerToken {
67 #[inline]
71 pub fn new(s: &str) -> Result<BearerToken, ParseError> {
72 s.parse()
73 }
74
75 #[inline]
77 pub fn as_str(&self) -> &str {
78 &self.0
79 }
80
81 #[inline]
83 pub fn into_string(self) -> String {
84 self.0
85 }
86}
87
88impl AsRef<str> for BearerToken {
89 #[inline]
90 fn as_ref(&self) -> &str {
91 &self.0
92 }
93}
94
95impl Borrow<str> for BearerToken {
96 #[inline]
97 fn borrow(&self) -> &str {
98 &self.0
99 }
100}
101
102impl fmt::Debug for BearerToken {
103 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
104 fmt.debug_tuple("BearerToken").field(&"REDACTED").finish()
105 }
106}
107
108impl FromStr for BearerToken {
109 type Err = ParseError;
110
111 fn from_str(s: &str) -> Result<BearerToken, ParseError> {
112 if !is_valid(s) {
113 return Err(ParseError(()));
114 }
115
116 Ok(BearerToken(s.to_string()))
117 }
118}
119
120impl Serialize for BearerToken {
121 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
122 where
123 S: Serializer,
124 {
125 self.0.serialize(s)
126 }
127}
128
129impl<'de> Deserialize<'de> for BearerToken {
130 fn deserialize<D>(d: D) -> Result<BearerToken, D::Error>
131 where
132 D: Deserializer<'de>,
133 {
134 let s = String::deserialize(d)?;
135
136 if is_valid(&s) {
137 Ok(BearerToken(s))
138 } else {
139 Err(de::Error::invalid_value(
140 Unexpected::Str(&s),
141 &"a bearer token",
142 ))
143 }
144 }
145}
146
147fn is_valid(s: &str) -> bool {
148 let stripped = s.trim_end_matches('=');
149
150 if stripped.is_empty() || !stripped.as_bytes().iter().cloned().all(valid_char) {
151 return false;
152 }
153
154 true
155}
156
157fn valid_char(b: u8) -> bool {
159 VALID_CHARS[b as usize] != 0
160}
161
162#[derive(Debug)]
164pub struct ParseError(());
165
166impl fmt::Display for ParseError {
167 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
168 fmt.write_str("invalid bearer token")
169 }
170}
171
172impl Error for ParseError {}