use std::{convert::Infallible, fmt, marker::PhantomData};
use crate::{Ctx, IntoService, IntoServiceFactory, Service, ServiceFactory};
#[inline]
pub fn fn_service<F, Req, Res, Err>(f: F) -> FnService<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err>,
{
FnService { f, _t: PhantomData }
}
#[inline]
pub fn fn_service_st<F, St, Req, Res, Err>(f: F) -> FnServiceSt<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err>,
{
FnServiceSt { f, _t: PhantomData }
}
pub struct FnService<F, Req, Res, Err> {
f: F,
_t: PhantomData<(Req, Res, Err)>,
}
impl<F, Req, Res, Err> Clone for FnService<F, Req, Res, Err>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_t: PhantomData,
}
}
}
impl<F, Req, Res, Err> fmt::Debug for FnService<F, Req, Res, Err> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FnService")
.field("f", &std::any::type_name::<F>())
.finish()
}
}
impl<F, St, Req, Res, Err> Service<St, Req> for FnService<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err>,
{
type Res = Res;
type Error = Err;
#[inline]
async fn call(&self, req: Req, _: Ctx<'_, Self, St>) -> Result<Res, Err> {
(self.f)(req).await
}
}
impl<F, St, Req, Res, Err> IntoServiceFactory<FnServiceFactory<F, Req, Res, Err>, St, Req>
for FnService<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn into_factory(self) -> FnServiceFactory<F, Req, Res, Err> {
FnServiceFactory {
f: self.f,
_t: PhantomData,
}
}
}
impl<F, St, Req, Res, Err> IntoService<FnService<F, Req, Res, Err>, St, Req> for F
where
F: AsyncFn(Req) -> Result<Res, Err>,
{
#[inline]
fn into_service(self) -> FnService<F, Req, Res, Err> {
FnService {
f: self,
_t: PhantomData,
}
}
}
pub struct FnServiceSt<F, St, Req, Res, Err> {
f: F,
_t: PhantomData<(St, Req, Res, Err)>,
}
impl<F, St, Req, Res, Err> Clone for FnServiceSt<F, St, Req, Res, Err>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_t: PhantomData,
}
}
}
impl<F, St, Req, Res, Err> fmt::Debug for FnServiceSt<F, St, Req, Res, Err> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FnServiceSt")
.field("f", &std::any::type_name::<F>())
.finish()
}
}
impl<F, St, Req, Res, Err> Service<St, Req> for FnServiceSt<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err>,
{
type Res = Res;
type Error = Err;
#[inline]
async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<Res, Err> {
(self.f)(ctx.st(), req).await
}
}
impl<F, St, Req, Res, Err> IntoServiceFactory<FnServiceStFactory<F, St, Req, Res, Err>, St, Req>
for FnServiceSt<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn into_factory(self) -> FnServiceStFactory<F, St, Req, Res, Err> {
FnServiceStFactory {
f: self.f,
ph: PhantomData,
}
}
}
impl<F, St, Req, Res, Err> IntoService<FnServiceSt<F, St, Req, Res, Err>, St, Req> for F
where
F: AsyncFn(&St, Req) -> Result<Res, Err>,
{
#[inline]
fn into_service(self) -> FnServiceSt<F, St, Req, Res, Err> {
FnServiceSt {
f: self,
_t: PhantomData,
}
}
}
pub struct FnServiceFactory<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
f: F,
_t: PhantomData<(Req,)>,
}
impl<F, Req, Res, Err> FnServiceFactory<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
fn new(f: F) -> Self {
FnServiceFactory { f, _t: PhantomData }
}
}
impl<F, Req, Res, Err> Clone for FnServiceFactory<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_t: PhantomData,
}
}
}
impl<F, Req, Res, Err> fmt::Debug for FnServiceFactory<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FnServiceFactory")
.field("f", &std::any::type_name::<F>())
.finish()
}
}
impl<F, St, Req, Res, Err> ServiceFactory<St, Req> for FnServiceFactory<F, Req, Res, Err>
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
type Res = Res;
type Error = Err;
type Service = FnService<F, Req, Res, Err>;
type InitError = Infallible;
#[inline]
async fn create(&self, _: &St) -> Result<Self::Service, Self::InitError> {
Ok(FnService {
f: self.f.clone(),
_t: PhantomData,
})
}
}
impl<St, F, Req, Res, Err> IntoServiceFactory<FnServiceFactory<F, Req, Res, Err>, St, Req> for F
where
F: AsyncFn(Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn into_factory(self) -> FnServiceFactory<F, Req, Res, Err> {
FnServiceFactory::new(self)
}
}
pub struct FnServiceStFactory<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
f: F,
ph: PhantomData<(St, Req, Res, Err)>,
}
impl<F, St, Req, Res, Err> Clone for FnServiceStFactory<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
ph: PhantomData,
}
}
}
impl<F, St, Req, Res, Err> fmt::Debug for FnServiceStFactory<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FnServiceStFactory")
.field("f", &std::any::type_name::<F>())
.finish()
}
}
impl<F, St, Req, Res, Err> ServiceFactory<St, Req> for FnServiceStFactory<F, St, Req, Res, Err>
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
type Res = Res;
type Error = Err;
type Service = FnServiceSt<F, St, Req, Res, Err>;
type InitError = Infallible;
#[inline]
async fn create(&self, _: &St) -> Result<Self::Service, Self::InitError> {
Ok(FnServiceSt {
f: self.f.clone(),
_t: PhantomData,
})
}
}
impl<F, St, Req, Res, Err> IntoServiceFactory<FnServiceStFactory<F, St, Req, Res, Err>, St, Req>
for F
where
F: AsyncFn(&St, Req) -> Result<Res, Err> + Clone,
{
#[inline]
fn into_factory(self) -> FnServiceStFactory<F, St, Req, Res, Err> {
FnServiceStFactory {
f: self,
ph: PhantomData,
}
}
}
#[inline]
pub fn fn_factory<F, S, St, Req, Err>(f: F) -> FnFactory<F, S, St, Req, Err>
where
F: AsyncFn(&St) -> Result<S, Err>,
S: Service<St, Req>,
{
FnFactory { f, _t: PhantomData }
}
pub struct FnFactory<F, S, St, Req, Err>
where
F: AsyncFn(&St) -> Result<S, Err>,
S: Service<St, Req>,
{
f: F,
_t: PhantomData<(S, St, Req, Err)>,
}
impl<F, S, St, Req, Err> ServiceFactory<St, Req> for FnFactory<F, S, St, Req, Err>
where
F: AsyncFn(&St) -> Result<S, Err>,
S: Service<St, Req>,
{
type Res = S::Res;
type Error = S::Error;
type Service = S;
type InitError = Err;
#[inline]
async fn create(&self, st: &St) -> Result<Self::Service, Self::InitError> {
(self.f)(st).await
}
}
impl<F, S, St, Req, Err> Clone for FnFactory<F, S, St, Req, Err>
where
F: AsyncFn(&St) -> Result<S, Err> + Clone,
S: Service<St, Req>,
{
#[inline]
fn clone(&self) -> Self {
FnFactory {
f: self.f.clone(),
_t: PhantomData,
}
}
}
impl<F, S, St, Req, Err> fmt::Debug for FnFactory<F, S, St, Req, Err>
where
F: AsyncFn(&St) -> Result<S, Err>,
S: Service<St, Req>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FnFactory")
.field("f", &std::any::type_name::<F>())
.finish()
}
}
impl<F, S, St, Req, Err> IntoServiceFactory<FnFactory<F, S, St, Req, Err>, St, Req> for F
where
F: AsyncFn(&St) -> Result<S, Err>,
S: Service<St, Req>,
{
#[inline]
fn into_factory(self) -> FnFactory<F, S, St, Req, Err> {
FnFactory {
f: self,
_t: PhantomData,
}
}
}
#[cfg(test)]
#[path = "../tests/unit/fn_service.rs"]
mod tests;