use std::fmt::{Debug, Formatter};
use crate::Service;
#[derive(Clone)]
pub struct Execute<E>(E);
impl<E> Execute<E> {
#[must_use]
pub fn new<In, Out, F>(e: E) -> Self
where
E: Fn(In) -> F + Send + Sync + 'static,
In: Send + 'static,
F: Future<Output = Out> + Send + 'static,
Out: Send + 'static,
{
Self(e)
}
}
impl<E, F, In, Out> Service<In> for Execute<E>
where
E: Fn(In) -> F + Send + Sync,
F: Future<Output = Out> + Send,
{
type Out = Out;
fn execute(&self, input: In) -> impl Future<Output = Self::Out> + Send {
self.0(input)
}
}
#[cfg(any(feature = "tower-service", test))]
impl<E, F, Req, Res, Err> tower_service::Service<Req> for Execute<E>
where
E: Fn(Req) -> F + Send + Sync,
F: Future<Output = Result<Res, Err>> + Send,
{
type Response = Res;
type Error = Err;
type Future = F;
fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
std::task::Poll::Ready(Ok(()))
}
fn call(&mut self, req: Req) -> Self::Future {
self.0(req)
}
}
impl<E> Debug for Execute<E> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Execute").finish_non_exhaustive()
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn debug() {
let svc = Execute::new(|x: i32| async move { x });
assert!(format!("{svc:?}").contains("Execute"));
}
}