cgp_dispatch/providers/field_matchers/
extract_handle.rs

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