use std::{borrow::Cow, str};
use crate::{
traits::{AuthValue, Scheme},
Error,
};
use async_trait::async_trait;
pub struct Bearer {
bearer: Option<Cow<'static, str>>,
}
unsafe impl Send for Bearer {}
unsafe impl Sync for Bearer {}
impl Default for Bearer {
fn default() -> Self {
Bearer { bearer: None }
}
}
impl Bearer {
pub fn new<T: Into<String>>(bearer: T) -> Self {
let bearer: String = bearer.into();
Bearer {
bearer: Some(bearer.into()),
}
}
}
#[async_trait]
impl Scheme for Bearer {
fn header_name() -> http_types::headers::HeaderName {
http_types::headers::AUTHORIZATION
}
async fn parse(
&self,
header_value: &http_types::headers::HeaderValue,
) -> crate::Result<crate::traits::AuthValue> {
let bearer = if let Some(ref bearer) = self.bearer {
bearer.to_string()
} else {
"Bearer".to_string()
};
if header_value.as_str().len() < bearer.len() + 2 {
return Err(Error::Invalid);
}
let mut parts = header_value.as_str().splitn(2, ' ');
match parts.next() {
Some(scheme) if scheme == bearer => {}
_ => return Err(Error::MissingScheme),
}
let value = parts.next().ok_or(Error::Invalid)?;
Ok(AuthValue::Bearer(value.to_string()))
}
}