Closed GlenDC closed 2 months ago
This could be achieved using a the following definition at rama-core/src/service/into.rs
:
use super::{
handler::{Factory, FromContextRequest, ServiceFn},
service_fn, Service,
};
use std::future::Future;
/// utility trait to both services and service functions as a [`rama_core::Service`].
pub trait IntoService<S, Request, X>:
private::Sealed<S, Request, X> + Send + Sync + 'static
{
/// [`rama_core::Service`] to turn `self` into
type Service: Service<S, Request>;
/// convert the type into a [`rama_core::Service`].
fn into_service(self) -> Self::Service;
}
impl<T, S, Request> IntoService<S, Request, ()> for T
where
T: Service<S, Request>,
{
type Service = T;
fn into_service(self) -> Self::Service {
self
}
}
impl<F, S, Request, T, R, O, E> IntoService<S, Request, (T, R, O, E)> for F
where
F: Factory<T, R, O, E>,
R: Future<Output = Result<O, E>>,
T: FromContextRequest<S, Request>,
R: Send + 'static,
O: Send + 'static,
E: Send + Sync + 'static,
{
type Service = ServiceFn<F, T, R, O, E>;
fn into_service(self) -> Self::Service {
service_fn(self)
}
}
mod private {
use crate::{
service::handler::{Factory, FromContextRequest},
Service,
};
use std::future::Future;
pub trait Sealed<S, Request, X> {}
impl<T, S, Request> Sealed<S, Request, ()> for T where T: Service<S, Request> {}
impl<F, S, Request, T, R, O, E> Sealed<S, Request, (T, R, O, E)> for F
where
F: Factory<T, R, O, E>,
R: Future<Output = Result<O, E>>,
T: FromContextRequest<S, Request>,
R: Send + 'static,
O: Send + 'static,
E: Send + Sync + 'static,
{
}
}
However... It would lead to confusion:
layer(...)
still will need to be used service_fn
... and people implementing their own layers that are called directly will also still use. So you'll get a mix and match.. I think better just let it what it is... It's not a lot of effort and it is clear enough.
We already use "into" like traits for stuff like the endpoint services in rama's web service. Perhaps it's time we move this concept also into the more abstract ServiceFn implementation, making it that you do not need to add
service_fn
everywhere.Something to be thought about prior to releasing 0.2