1use cgp_core::prelude::*;
2
3use crate::{
4 Computer, ComputerComponent, Handler, HandlerComponent, Producer, TryComputer,
5 TryComputerComponent,
6};
7
8pub struct Promote<Provider>(pub PhantomData<Provider>);
9
10pub struct TryPromote<Provider>(pub PhantomData<Provider>);
11
12pub type Promote2<Provider> = Promote<Promote<Provider>>;
13
14pub type Promote3<Provider> = Promote<Promote2<Provider>>;
15
16#[cgp_provider]
17impl<Context, Code, Input, Output, Provider> Handler<Context, Code, Input> for Promote<Provider>
18where
19 Context: HasAsyncErrorType,
20 Provider: TryComputer<Context, Code, Input, Output = Output>,
21 Code: Send,
22 Input: Send,
23 Output: Send,
24{
25 type Output = Output;
26
27 async fn handle(
28 context: &Context,
29 tag: PhantomData<Code>,
30 input: Input,
31 ) -> Result<Output, Context::Error> {
32 Provider::try_compute(context, tag, input)
33 }
34}
35
36#[cgp_provider]
37impl<Context, Code, Input, Output, Provider> Computer<Context, Code, Input> for Promote<Provider>
38where
39 Provider: Producer<Context, Code, Output = Output>,
40{
41 type Output = Output;
42
43 fn compute(context: &Context, code: PhantomData<Code>, _input: Input) -> Self::Output {
44 Provider::produce(context, code)
45 }
46}
47
48#[cgp_provider]
49impl<Context, Code, Input, Output, Provider> TryComputer<Context, Code, Input> for Promote<Provider>
50where
51 Context: HasErrorType,
52 Provider: Computer<Context, Code, Input, Output = Output>,
53{
54 type Output = Output;
55
56 fn try_compute(
57 context: &Context,
58 code: PhantomData<Code>,
59 input: Input,
60 ) -> Result<Self::Output, Context::Error> {
61 Ok(Provider::compute(context, code, input))
62 }
63}
64
65#[cgp_provider]
66impl<Context, Code, Input, Output, Error, Provider> Handler<Context, Code, Input>
67 for TryPromote<Provider>
68where
69 Context: CanRaiseAsyncError<Error>,
70 Provider: Computer<Context, Code, Input, Output = Result<Output, Error>>,
71 Code: Send,
72 Input: Send,
73 Output: Send,
74 Error: Send,
75{
76 type Output = Output;
77
78 async fn handle(
79 context: &Context,
80 tag: PhantomData<Code>,
81 input: Input,
82 ) -> Result<Output, Context::Error> {
83 Provider::compute(context, tag, input).map_err(Context::raise_error)
84 }
85}
86
87#[cgp_provider]
88impl<Context, Code, Input, Output, Error, Provider> TryComputer<Context, Code, Input>
89 for TryPromote<Provider>
90where
91 Context: CanRaiseError<Error>,
92 Provider: Computer<Context, Code, Input, Output = Result<Output, Error>>,
93{
94 type Output = Output;
95
96 fn try_compute(
97 context: &Context,
98 tag: PhantomData<Code>,
99 input: Input,
100 ) -> Result<Output, Context::Error> {
101 Provider::compute(context, tag, input).map_err(Context::raise_error)
102 }
103}