1use std::{borrow::Cow, str};
2
3use crate::{
4 traits::{AuthValue, Scheme},
5 Error,
6};
7use async_trait::async_trait;
8
9pub struct Bearer {
10 bearer: Option<Cow<'static, str>>,
11}
12
13unsafe impl Send for Bearer {}
14
15unsafe impl Sync for Bearer {}
16
17impl Default for Bearer {
18 fn default() -> Self {
19 Bearer { bearer: None }
20 }
21}
22
23impl Bearer {
24 pub fn new<T: Into<String>>(bearer: T) -> Self {
25 let bearer: String = bearer.into();
26
27 Bearer {
28 bearer: Some(bearer.into()),
29 }
30 }
31}
32
33#[async_trait]
34impl Scheme for Bearer {
35 fn header_name() -> http_types::headers::HeaderName {
36 http_types::headers::AUTHORIZATION
37 }
38
39 async fn parse(
40 &self,
41 header_value: &http_types::headers::HeaderValue,
42 ) -> crate::Result<crate::traits::AuthValue> {
43 let bearer = if let Some(ref bearer) = self.bearer {
44 bearer.to_string()
45 } else {
46 "Bearer".to_string()
47 };
48
49 if header_value.as_str().len() < bearer.len() + 2 {
50 return Err(Error::Invalid);
51 }
52
53 let mut parts = header_value.as_str().splitn(2, ' ');
54
55 match parts.next() {
56 Some(scheme) if scheme == bearer => {}
57 _ => return Err(Error::MissingScheme),
58 }
59
60 let value = parts.next().ok_or(Error::Invalid)?;
61
62 Ok(AuthValue::Bearer(value.to_string()))
63 }
64}