use crate::ServiceTarget;
use crate::resolver::Result;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum ServiceTargetResolver {
ResolverFn(Arc<Box<dyn ServiceTargetResolverFn>>),
ResolverAsyncFn(Arc<Box<dyn ServiceTargetResolverAsyncFn>>),
}
impl ServiceTargetResolver {
pub fn from_resolver_fn(resolver_fn: impl IntoServiceTargetResolverFn) -> Self {
ServiceTargetResolver::ResolverFn(resolver_fn.into_resolver_fn())
}
pub fn from_resolver_async_fn(resolver_fn: impl IntoServiceTargetResolverAsyncFn) -> Self {
ServiceTargetResolver::ResolverAsyncFn(resolver_fn.into_resolver_async_fn())
}
}
impl ServiceTargetResolver {
pub(crate) async fn resolve(&self, service_target: ServiceTarget) -> Result<ServiceTarget> {
match self {
ServiceTargetResolver::ResolverFn(resolver_fn) => resolver_fn.clone().exec_fn(service_target),
ServiceTargetResolver::ResolverAsyncFn(resolver_fn) => resolver_fn.clone().exec_fn(service_target).await,
}
}
}
pub trait ServiceTargetResolverFn: Send + Sync {
fn exec_fn(&self, service_target: ServiceTarget) -> Result<ServiceTarget>;
fn clone_box(&self) -> Box<dyn ServiceTargetResolverFn>;
}
impl<F> ServiceTargetResolverFn for F
where
F: FnOnce(ServiceTarget) -> Result<ServiceTarget> + Send + Sync + Clone + 'static,
{
fn exec_fn(&self, service_target: ServiceTarget) -> Result<ServiceTarget> {
(self.clone())(service_target)
}
fn clone_box(&self) -> Box<dyn ServiceTargetResolverFn> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn ServiceTargetResolverFn> {
fn clone(&self) -> Box<dyn ServiceTargetResolverFn> {
self.clone_box()
}
}
impl std::fmt::Debug for dyn ServiceTargetResolverFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ServiceTargetResolverFn")
}
}
pub trait IntoServiceTargetResolverFn {
fn into_resolver_fn(self) -> Arc<Box<dyn ServiceTargetResolverFn>>;
}
impl IntoServiceTargetResolverFn for Arc<Box<dyn ServiceTargetResolverFn>> {
fn into_resolver_fn(self) -> Arc<Box<dyn ServiceTargetResolverFn>> {
self
}
}
impl<F> IntoServiceTargetResolverFn for F
where
F: FnOnce(ServiceTarget) -> Result<ServiceTarget> + Send + Sync + Clone + 'static,
{
fn into_resolver_fn(self) -> Arc<Box<dyn ServiceTargetResolverFn>> {
Arc::new(Box::new(self))
}
}
pub trait ServiceTargetResolverAsyncFn: Send + Sync {
fn exec_fn(&self, service_target: ServiceTarget) -> Pin<Box<dyn Future<Output = Result<ServiceTarget>> + Send>>;
fn clone_box(&self) -> Box<dyn ServiceTargetResolverAsyncFn>;
}
impl<F> ServiceTargetResolverAsyncFn for F
where
F: Fn(ServiceTarget) -> Pin<Box<dyn Future<Output = Result<ServiceTarget>> + Send>> + Send + Sync + Clone + 'static,
{
fn exec_fn(&self, service_target: ServiceTarget) -> Pin<Box<dyn Future<Output = Result<ServiceTarget>> + Send>> {
self.clone()(service_target)
}
fn clone_box(&self) -> Box<dyn ServiceTargetResolverAsyncFn> {
Box::new(self.clone())
}
}
impl std::fmt::Debug for dyn ServiceTargetResolverAsyncFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ServiceTargetResolverAsyncFn")
}
}
impl Clone for Box<dyn ServiceTargetResolverAsyncFn> {
fn clone(&self) -> Self {
self.clone_box()
}
}
pub trait IntoServiceTargetResolverAsyncFn {
fn into_resolver_async_fn(self) -> Arc<Box<dyn ServiceTargetResolverAsyncFn>>;
}
impl IntoServiceTargetResolverAsyncFn for Arc<Box<dyn ServiceTargetResolverAsyncFn>> {
fn into_resolver_async_fn(self) -> Arc<Box<dyn ServiceTargetResolverAsyncFn>> {
self
}
}
impl<F> IntoServiceTargetResolverAsyncFn for F
where
F: Fn(ServiceTarget) -> Pin<Box<dyn Future<Output = Result<ServiceTarget>> + Send>> + Send + Sync + Clone + 'static,
{
fn into_resolver_async_fn(self) -> Arc<Box<dyn ServiceTargetResolverAsyncFn>> {
Arc::new(Box::new(self))
}
}