cgp_dispatch/providers/field_matchers/
extract_field.rs

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