1use core::ops::Deref;
2
3use cgp_core::prelude::*;
4
5use crate::{
6 Computer, ComputerComponent, ComputerRef, ComputerRefComponent, Handler, HandlerComponent,
7 HandlerRef, HandlerRefComponent, TryComputer, TryComputerComponent, TryComputerRef,
8 TryComputerRefComponent,
9};
10
11pub struct PromoteRef<Provider>(pub PhantomData<Provider>);
12
13#[cgp_provider]
14impl<Context, Code, Input, Target, Provider> Handler<Context, Code, Input> for PromoteRef<Provider>
15where
16 Context: HasAsyncErrorType,
17 Provider: HandlerRef<Context, Code, Target>,
18 Input: Deref<Target = Target> + Async,
19 Code: Send,
20{
21 type Output = Provider::Output;
22
23 async fn handle(
24 context: &Context,
25 tag: PhantomData<Code>,
26 input: Input,
27 ) -> Result<Self::Output, Context::Error> {
28 Provider::handle_ref(context, tag, input.deref()).await
29 }
30}
31
32#[cgp_provider]
33impl<Context, Code, Input, Provider, Output> HandlerRef<Context, Code, Input>
34 for PromoteRef<Provider>
35where
36 Context: HasAsyncErrorType,
37 Provider: for<'a> Handler<Context, Code, &'a Input, Output = Output>,
38 Code: Send,
39 Input: Sync,
40{
41 type Output = Output;
42
43 async fn handle_ref(
44 context: &Context,
45 tag: PhantomData<Code>,
46 input: &Input,
47 ) -> Result<Self::Output, Context::Error> {
48 Provider::handle(context, tag, input).await
49 }
50}
51
52#[cgp_provider]
53impl<Context, Code, Input, Target, Provider> TryComputer<Context, Code, Input>
54 for PromoteRef<Provider>
55where
56 Context: HasErrorType,
57 Provider: TryComputerRef<Context, Code, Target>,
58 Input: Deref<Target = Target>,
59{
60 type Output = Provider::Output;
61
62 fn try_compute(
63 context: &Context,
64 tag: PhantomData<Code>,
65 input: Input,
66 ) -> Result<Self::Output, Context::Error> {
67 Provider::try_compute_ref(context, tag, input.deref())
68 }
69}
70
71#[cgp_provider]
72impl<Context, Code, Input, Provider, Output> TryComputerRef<Context, Code, Input>
73 for PromoteRef<Provider>
74where
75 Context: HasErrorType,
76 Provider: for<'a> TryComputer<Context, Code, &'a Input, Output = Output>,
77{
78 type Output = Output;
79
80 fn try_compute_ref(
81 context: &Context,
82 tag: PhantomData<Code>,
83 input: &Input,
84 ) -> Result<Self::Output, Context::Error> {
85 Provider::try_compute(context, tag, input)
86 }
87}
88
89#[cgp_provider]
90impl<Context, Code, Input, Target, Provider> Computer<Context, Code, Input> for PromoteRef<Provider>
91where
92 Provider: ComputerRef<Context, Code, Target>,
93 Input: Deref<Target = Target>,
94{
95 type Output = Provider::Output;
96
97 fn compute(context: &Context, tag: PhantomData<Code>, input: Input) -> Self::Output {
98 Provider::compute_ref(context, tag, input.deref())
99 }
100}
101
102#[cgp_provider]
103impl<Context, Code, Input, Provider, Output> ComputerRef<Context, Code, Input>
104 for PromoteRef<Provider>
105where
106 Provider: for<'a> Computer<Context, Code, &'a Input, Output = Output>,
107{
108 type Output = Output;
109
110 fn compute_ref(context: &Context, tag: PhantomData<Code>, input: &Input) -> Self::Output {
111 Provider::compute(context, tag, input)
112 }
113}