wesichain_core/
binding.rs1use std::marker::PhantomData;
2
3use crate::{Runnable, StreamEvent, WesichainError};
4use async_trait::async_trait;
5use futures::stream::BoxStream;
6
7use futures::StreamExt;
8
9pub trait Bindable: Sized + Send + Sync + 'static {
11 fn bind(&mut self, args: crate::Value) -> Result<(), WesichainError>;
14}
15
16pub struct RunnableBinding<R, Input, Output> {
18 pub(crate) bound: R,
19 pub(crate) args: crate::Value,
20 pub(crate) _marker: PhantomData<(Input, Output)>,
21}
22
23impl<R, Input, Output> RunnableBinding<R, Input, Output> {
24 pub fn new(bound: R, args: crate::Value) -> Self {
25 Self {
26 bound,
27 args,
28 _marker: PhantomData,
29 }
30 }
31}
32
33#[async_trait]
34impl<R, Input, Output> Runnable<Input, Output> for RunnableBinding<R, Input, Output>
35where
36 R: Runnable<Input, Output> + Send + Sync,
37 Input: Bindable + Clone + Send + 'static,
38 Output: Send + Sync + 'static,
39{
40 async fn invoke(&self, mut input: Input) -> Result<Output, WesichainError> {
41 input.bind(self.args.clone())?;
42 self.bound.invoke(input).await
43 }
44
45 fn stream(&self, mut input: Input) -> BoxStream<'_, Result<StreamEvent, WesichainError>> {
46 if let Err(e) = input.bind(self.args.clone()) {
57 return futures::stream::once(async move { Err(e) }).boxed();
58 }
59
60 self.bound.stream(input)
61 }
62}