aws_credential_types/
token_fn.rs
1use crate::provider::{future, token::ProvideToken};
9use std::fmt::{self, Debug, Formatter};
10use std::future::Future;
11use std::marker::PhantomData;
12
13#[derive(Copy, Clone)]
17pub struct ProvideTokenFn<'c, T> {
18 f: T,
19 phantom: PhantomData<&'c T>,
20}
21
22impl<T> Debug for ProvideTokenFn<'_, T> {
23 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
24 write!(f, "ProvideTokenFn")
25 }
26}
27
28impl<'c, T, F> ProvideToken for ProvideTokenFn<'c, T>
29where
30 T: Fn() -> F + Send + Sync + 'c,
31 F: Future<Output = crate::provider::token::Result> + Send + 'static,
32{
33 fn provide_token<'a>(&'a self) -> future::ProvideToken<'a>
34 where
35 Self: 'a,
36 {
37 future::ProvideToken::new((self.f)())
38 }
39}
40
41pub fn provide_token_fn<'c, T, F>(f: T) -> ProvideTokenFn<'c, T>
62where
63 T: Fn() -> F + Send + Sync + 'c,
64 F: Future<Output = crate::provider::token::Result> + Send + 'static,
65{
66 ProvideTokenFn {
67 f,
68 phantom: Default::default(),
69 }
70}
71
72#[cfg(test)]
73mod test {
74 use super::*;
75 use crate::Token;
76
77 fn assert_send_sync<T: Send + Sync>() {}
78
79 #[test]
80 fn creds_are_send_sync() {
81 assert_send_sync::<Token>()
82 }
83
84 #[tokio::test]
86 async fn provide_token_fn_closure_can_borrow() {
87 fn check_is_str_ref(_input: &str) {}
88 async fn test_async_provider(input: String) -> crate::provider::token::Result {
89 Ok(Token::new(input, None))
90 }
91
92 let things_to_borrow = vec!["one".to_string(), "two".to_string()];
93
94 let mut providers = Vec::new();
95 for thing in &things_to_borrow {
96 let provider = provide_token_fn(move || {
97 check_is_str_ref(thing);
98 test_async_provider(thing.into())
99 });
100 providers.push(provider);
101 }
102
103 let (two, one) = (providers.pop().unwrap(), providers.pop().unwrap());
104 assert_eq!("one", one.provide_token().await.unwrap().token());
105 assert_eq!("two", two.provide_token().await.unwrap().token());
106 }
107}