protect_endpoints_core/authorities/
extractor.rs

1use std::collections::HashSet;
2use std::future::Future;
3use std::hash::Hash;
4
5/// Trait for extracting authorities from the request.
6/// By default, is implemented for functions with signature `fn(&mut Request) -> Result<HashSet<Type>, Into<Response>`.
7/// But can be implemented for custom structures and enums.
8pub trait AuthoritiesExtractor<'a, Request, Type, Error> {
9    type Future: Future<Output = Result<HashSet<Type>, Error>> + Send;
10
11    fn extract(&self, request: &'a mut Request) -> Self::Future;
12}
13
14impl<'a, F, O, Request, Type, Error> AuthoritiesExtractor<'a, Request, Type, Error> for F
15where
16    F: Fn(&'a mut Request) -> O,
17    Request: 'a,
18    O: Future<Output = Result<HashSet<Type>, Error>> + Send,
19    Type: Eq + Hash + 'static,
20{
21    type Future = O;
22
23    fn extract(&self, req: &'a mut Request) -> Self::Future {
24        (self)(req)
25    }
26}
27
28#[cfg(test)]
29mod tests {
30    use super::AuthoritiesExtractor;
31    use std::collections::HashSet;
32
33    struct FakeRequest;
34
35    async fn extractor(_req: &mut FakeRequest) -> Result<HashSet<String>, ()> {
36        Ok(HashSet::from(["TEST_PERMISSION".to_string()]))
37    }
38
39    #[tokio::test]
40    async fn test_fn_mut_extractor_impl() {
41        let authorities: Result<_, ()> = extractor.extract(&mut FakeRequest).await;
42
43        authorities
44            .unwrap()
45            .iter()
46            .for_each(|perm| assert_eq!("TEST_PERMISSION", perm.as_str()));
47    }
48}