Skip to main content

cgp_handler/providers/
compose.rs

1use cgp_core::prelude::*;
2
3use crate::{
4    AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent, Handler, HandlerComponent,
5    TryComputer, TryComputerComponent,
6};
7
8pub struct ComposeHandlers<ProviderA, ProviderB>(pub PhantomData<(ProviderA, ProviderB)>);
9
10#[cgp_provider]
11impl<Context, Code, Input, ProviderA, ProviderB> Computer<Context, Code, Input>
12    for ComposeHandlers<ProviderA, ProviderB>
13where
14    ProviderA: Computer<Context, Code, Input>,
15    ProviderB: Computer<Context, Code, ProviderA::Output>,
16{
17    type Output = ProviderB::Output;
18
19    fn compute(context: &Context, code: PhantomData<Code>, input: Input) -> Self::Output {
20        let intermediary = ProviderA::compute(context, code, input);
21        ProviderB::compute(context, code, intermediary)
22    }
23}
24
25#[cgp_provider]
26impl<Context, Code, Input, ProviderA, ProviderB> TryComputer<Context, Code, Input>
27    for ComposeHandlers<ProviderA, ProviderB>
28where
29    Context: HasErrorType,
30    ProviderA: TryComputer<Context, Code, Input>,
31    ProviderB: TryComputer<Context, Code, ProviderA::Output>,
32{
33    type Output = ProviderB::Output;
34
35    fn try_compute(
36        context: &Context,
37        code: PhantomData<Code>,
38        input: Input,
39    ) -> Result<Self::Output, Context::Error> {
40        let intermediary = ProviderA::try_compute(context, code, input)?;
41        ProviderB::try_compute(context, code, intermediary)
42    }
43}
44
45#[cgp_provider]
46impl<Context, Code, Input, ProviderA, ProviderB> AsyncComputer<Context, Code, Input>
47    for ComposeHandlers<ProviderA, ProviderB>
48where
49    ProviderA: AsyncComputer<Context, Code, Input>,
50    ProviderB: AsyncComputer<Context, Code, ProviderA::Output>,
51{
52    type Output = ProviderB::Output;
53
54    async fn compute_async(
55        context: &Context,
56        code: PhantomData<Code>,
57        input: Input,
58    ) -> Self::Output {
59        let intermediary = ProviderA::compute_async(context, code, input).await;
60        ProviderB::compute_async(context, code, intermediary).await
61    }
62}
63
64#[cgp_provider]
65impl<Context, Code, Input, ProviderA, ProviderB> Handler<Context, Code, Input>
66    for ComposeHandlers<ProviderA, ProviderB>
67where
68    Context: HasErrorType,
69    ProviderA: Handler<Context, Code, Input>,
70    ProviderB: Handler<Context, Code, ProviderA::Output>,
71{
72    type Output = ProviderB::Output;
73
74    async fn handle(
75        context: &Context,
76        code: PhantomData<Code>,
77        input: Input,
78    ) -> Result<Self::Output, Context::Error> {
79        let intermediary = ProviderA::handle(context, code, input).await?;
80        ProviderB::handle(context, code, intermediary).await
81    }
82}