Skip to main content

cgp_dispatch/providers/field_matchers/
extract_handle.rs

1use cgp_core::field::impls::CanDowncastFields;
2use cgp_core::prelude::*;
3use cgp_handler::{AsyncComputer, AsyncComputerComponent, Computer, ComputerComponent};
4
5pub struct DowncastAndHandle<Input, Provider = UseContext>(pub PhantomData<(Input, Provider)>);
6
7#[cgp_provider]
8impl<Context, Code, Input, Provider, Inner, Output, Remainder> Computer<Context, Code, Input>
9    for DowncastAndHandle<Inner, Provider>
10where
11    Input: CanDowncastFields<Inner, Remainder = Remainder>,
12    Provider: Computer<Context, Code, Inner, Output = Output>,
13{
14    type Output = Result<Output, Remainder>;
15
16    fn compute(
17        context: &Context,
18        tag: PhantomData<Code>,
19        input: Input,
20    ) -> Result<Output, Remainder> {
21        let inner = input.downcast_fields(PhantomData::<Inner>)?;
22        let output = Provider::compute(context, tag, inner);
23        Ok(output)
24    }
25}
26
27#[cgp_provider]
28impl<Context, Code, Input, Provider, Inner, Output, Remainder> AsyncComputer<Context, Code, Input>
29    for DowncastAndHandle<Inner, Provider>
30where
31    Input: CanDowncastFields<Inner, Remainder = Remainder>,
32    Provider: AsyncComputer<Context, Code, Inner, Output = Output>,
33{
34    type Output = Result<Output, Remainder>;
35
36    async fn compute_async(
37        context: &Context,
38        tag: PhantomData<Code>,
39        input: Input,
40    ) -> Result<Output, Remainder> {
41        let inner = input.downcast_fields(PhantomData::<Inner>);
42
43        match inner {
44            Ok(inner) => {
45                let output = Provider::compute_async(context, tag, inner).await;
46                Ok(output)
47            }
48            Err(remainder) => Err(remainder),
49        }
50    }
51}