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