1use std::sync::{Arc, RwLock};
4
5pub trait Auth: Send + Sync {
7 fn authorization_header(&self) -> Option<String>;
9}
10
11#[derive(Clone)]
13pub struct BearerAuth {
14 provider: Arc<dyn Fn() -> String + Send + Sync>,
15}
16
17impl std::fmt::Debug for BearerAuth {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 f.debug_struct("BearerAuth").finish_non_exhaustive()
20 }
21}
22
23impl BearerAuth {
24 pub fn new(token: impl Into<String>) -> Self {
26 let token = token.into();
27 Self::dynamic(move || token.clone())
28 }
29
30 pub fn dynamic(provider: impl Fn() -> String + Send + Sync + 'static) -> Self {
32 Self {
33 provider: Arc::new(provider),
34 }
35 }
36
37 pub fn shared(token: Arc<RwLock<String>>) -> Self {
39 Self::dynamic(move || token.read().expect("token lock poisoned").clone())
40 }
41}
42
43impl Auth for BearerAuth {
44 fn authorization_header(&self) -> Option<String> {
45 let mut token = (self.provider)().trim().to_string();
46 if token.is_empty() {
47 return None;
48 }
49 if let Some(rest) = token.strip_prefix("Bearer ") {
50 token = rest.to_string();
51 }
52 Some(format!("Bearer {token}"))
53 }
54}
55
56#[derive(Clone, Copy, Debug, Default)]
58pub struct NoAuth;
59
60impl Auth for NoAuth {
61 fn authorization_header(&self) -> Option<String> {
62 None
63 }
64}