entelix_runnable/
mapping.rs1use std::marker::PhantomData;
9use std::sync::Arc;
10
11use async_trait::async_trait;
12
13use entelix_core::ExecutionContext;
14use entelix_core::error::Result;
15
16use crate::runnable::Runnable;
17
18pub struct Mapping<R, F, I, O, P>
21where
22 R: Runnable<I, O> + 'static,
23 F: Fn(O) -> P + Send + Sync + 'static,
24 I: Send + 'static,
25 O: Send + 'static,
26 P: Send + 'static,
27{
28 inner: Arc<R>,
29 f: Arc<F>,
30 _io: PhantomData<fn(I) -> (O, P)>,
31}
32
33impl<R, F, I, O, P> Mapping<R, F, I, O, P>
34where
35 R: Runnable<I, O> + 'static,
36 F: Fn(O) -> P + Send + Sync + 'static,
37 I: Send + 'static,
38 O: Send + 'static,
39 P: Send + 'static,
40{
41 pub fn new(inner: R, f: F) -> Self {
43 Self {
44 inner: Arc::new(inner),
45 f: Arc::new(f),
46 _io: PhantomData,
47 }
48 }
49}
50
51impl<R, F, I, O, P> std::fmt::Debug for Mapping<R, F, I, O, P>
52where
53 R: Runnable<I, O> + 'static,
54 F: Fn(O) -> P + Send + Sync + 'static,
55 I: Send + 'static,
56 O: Send + 'static,
57 P: Send + 'static,
58{
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 f.debug_struct("Mapping").finish_non_exhaustive()
61 }
62}
63
64#[async_trait]
65impl<R, F, I, O, P> Runnable<I, P> for Mapping<R, F, I, O, P>
66where
67 R: Runnable<I, O> + 'static,
68 F: Fn(O) -> P + Send + Sync + 'static,
69 I: Send + 'static,
70 O: Send + 'static,
71 P: Send + 'static,
72{
73 async fn invoke(&self, input: I, ctx: &ExecutionContext) -> Result<P> {
74 let value = self.inner.invoke(input, ctx).await?;
75 Ok((self.f)(value))
76 }
77}