use crate::ModelIden;
use crate::resolver::{AuthData, Result};
use std::pin::Pin;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum AuthResolver {
ResolverFn(Arc<Box<dyn AuthResolverFn>>),
ResolverAsyncFn(Arc<Box<dyn AuthResolverAsyncFn>>),
}
impl AuthResolver {
pub fn from_resolver_fn(resolver_fn: impl IntoAuthResolverFn) -> Self {
AuthResolver::ResolverFn(resolver_fn.into_resolver_fn())
}
pub fn from_resolver_async_fn(resolver_fn: impl IntoAuthResolverAsyncFn) -> Self {
AuthResolver::ResolverAsyncFn(resolver_fn.into_async_auth_resolver())
}
}
impl AuthResolver {
pub(crate) async fn resolve(&self, model_iden: ModelIden) -> Result<Option<AuthData>> {
match self {
AuthResolver::ResolverFn(resolver_fn) => resolver_fn.clone().exec_fn(model_iden),
AuthResolver::ResolverAsyncFn(resolver_fn) => resolver_fn.exec_fn(model_iden).await,
}
}
}
pub trait AuthResolverAsyncFn: Send + Sync {
fn exec_fn(&self, model_iden: ModelIden) -> Pin<Box<dyn Future<Output = Result<Option<AuthData>>> + Send>>;
fn clone_box(&self) -> Box<dyn AuthResolverAsyncFn>;
}
impl<F> AuthResolverAsyncFn for F
where
F: Fn(ModelIden) -> Pin<Box<dyn Future<Output = Result<Option<AuthData>>> + Send>> + Send + Sync + Clone + 'static,
{
fn exec_fn(&self, model_iden: ModelIden) -> Pin<Box<dyn Future<Output = Result<Option<AuthData>>> + Send>> {
self(model_iden)
}
fn clone_box(&self) -> Box<dyn AuthResolverAsyncFn> {
Box::new(self.clone())
}
}
impl std::fmt::Debug for dyn AuthResolverAsyncFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AuthResolverAsyncFn")
}
}
impl Clone for Box<dyn AuthResolverAsyncFn> {
fn clone(&self) -> Self {
self.clone_box()
}
}
pub trait IntoAuthResolverAsyncFn {
fn into_async_auth_resolver(self) -> Arc<Box<dyn AuthResolverAsyncFn>>;
}
impl IntoAuthResolverAsyncFn for Arc<Box<dyn AuthResolverAsyncFn>> {
fn into_async_auth_resolver(self) -> Arc<Box<dyn AuthResolverAsyncFn>> {
self
}
}
impl<F> IntoAuthResolverAsyncFn for F
where
F: Fn(ModelIden) -> Pin<Box<dyn Future<Output = Result<Option<AuthData>>> + Send>> + Send + Sync + Clone + 'static,
{
fn into_async_auth_resolver(self) -> Arc<Box<dyn AuthResolverAsyncFn>> {
Arc::new(Box::new(self))
}
}
pub trait AuthResolverFn: Send + Sync {
fn exec_fn(&self, model_iden: ModelIden) -> Result<Option<AuthData>>;
fn clone_box(&self) -> Box<dyn AuthResolverFn>;
}
impl<F> AuthResolverFn for F
where
F: FnOnce(ModelIden) -> Result<Option<AuthData>> + Send + Sync + Clone + 'static,
{
fn exec_fn(&self, model_iden: ModelIden) -> Result<Option<AuthData>> {
(self.clone())(model_iden)
}
fn clone_box(&self) -> Box<dyn AuthResolverFn> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn AuthResolverFn> {
fn clone(&self) -> Box<dyn AuthResolverFn> {
self.clone_box()
}
}
impl std::fmt::Debug for dyn AuthResolverFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AuthResolverFn")
}
}
pub trait IntoAuthResolverFn {
fn into_resolver_fn(self) -> Arc<Box<dyn AuthResolverFn>>;
}
impl IntoAuthResolverFn for Arc<Box<dyn AuthResolverFn>> {
fn into_resolver_fn(self) -> Arc<Box<dyn AuthResolverFn>> {
self
}
}
impl<F> IntoAuthResolverFn for F
where
F: FnOnce(ModelIden) -> Result<Option<AuthData>> + Send + Sync + Clone + 'static,
{
fn into_resolver_fn(self) -> Arc<Box<dyn AuthResolverFn>> {
Arc::new(Box::new(self))
}
}