use crate::authorities::AttachAuthorities;
use futures_core::future::BoxFuture;
use rocket::fairing::{Fairing, Info, Kind};
use rocket::{Data, Request};
use std::collections::HashSet;
use std::hash::Hash;
type Extractor<Type> = Box<
dyn for<'a> Fn(&'a mut Request<'_>) -> BoxFuture<'a, Option<HashSet<Type>>>
+ Send
+ Sync
+ 'static,
>;
pub struct GrantsFairing<Type> {
extractor: Extractor<Type>,
}
impl<Type: Eq + Hash + Send + Sync + 'static> GrantsFairing<Type> {
pub fn with_extractor_fn<F>(extractor_fn: F) -> Self
where
F: for<'a> Fn(&'a mut Request<'_>) -> BoxFuture<'a, Option<HashSet<Type>>>
+ Send
+ Sync
+ 'static,
{
Self {
extractor: Box::new(extractor_fn),
}
}
}
#[rocket::async_trait]
impl<Type: Eq + Hash + Send + Sync + 'static> Fairing for GrantsFairing<Type> {
fn info(&self) -> Info {
Info {
name: "Rocket-Grants Extractor",
kind: Kind::Request,
}
}
async fn on_request(&self, mut req: &mut Request<'_>, _data: &mut Data<'_>) {
let authorities: Option<HashSet<Type>> = (self.extractor)(req).await;
req.attach(authorities);
}
}