use serde::de::{self, Deserialize, Deserializer, Unexpected};
use serde::ser::{Serialize, Serializer};
use std::borrow::Borrow;
use std::error::Error;
use std::fmt;
use std::str::FromStr;
#[cfg(test)]
mod test;
#[rustfmt::skip]
static VALID_CHARS: [u8; 256] = [
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,
];
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BearerToken(String);
impl BearerToken {
#[inline]
pub fn new(s: &str) -> Result<BearerToken, ParseError> {
s.parse()
}
#[inline]
pub fn as_str(&self) -> &str {
&self.0
}
#[inline]
pub fn into_string(self) -> String {
self.0
}
}
impl AsRef<str> for BearerToken {
#[inline]
fn as_ref(&self) -> &str {
&self.0
}
}
impl Borrow<str> for BearerToken {
#[inline]
fn borrow(&self) -> &str {
&self.0
}
}
impl fmt::Debug for BearerToken {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("BearerToken").field(&"REDACTED").finish()
}
}
impl FromStr for BearerToken {
type Err = ParseError;
fn from_str(s: &str) -> Result<BearerToken, ParseError> {
if !is_valid(s) {
return Err(ParseError(()));
}
Ok(BearerToken(s.to_string()))
}
}
impl Serialize for BearerToken {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(s)
}
}
impl<'de> Deserialize<'de> for BearerToken {
fn deserialize<D>(d: D) -> Result<BearerToken, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(d)?;
if is_valid(&s) {
Ok(BearerToken(s))
} else {
Err(de::Error::invalid_value(
Unexpected::Str(&s),
&"a bearer token",
))
}
}
}
fn is_valid(s: &str) -> bool {
let stripped = s.trim_end_matches('=');
if stripped.is_empty() || !stripped.as_bytes().iter().cloned().all(valid_char) {
return false;
}
true
}
fn valid_char(b: u8) -> bool {
VALID_CHARS[b as usize] != 0
}
#[derive(Debug)]
pub struct ParseError(());
impl fmt::Display for ParseError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("invalid bearer token")
}
}
impl Error for ParseError {}