diff --git a/crates/cgp-dispatch/src/providers/dispatch_fields.rs b/crates/cgp-dispatch/src/providers/dispatch_fields.rs index 50a7c897..6b171911 100644 --- a/crates/cgp-dispatch/src/providers/dispatch_fields.rs +++ b/crates/cgp-dispatch/src/providers/dispatch_fields.rs @@ -1,10 +1,19 @@ use cgp_core::prelude::*; -use cgp_handler::{Computer, ComputerComponent, Handler, HandlerComponent}; +use cgp_handler::{ + Computer, ComputerComponent, HandleFieldValue, Handler, HandlerComponent, TryComputer, + TryComputerComponent, +}; -use crate::{DispatchHandlers, ExtractFieldAndHandle}; +use crate::{DispatchHandlers, DispatchHandlersRef, ExtractFieldAndHandle}; pub struct DispatchFields(pub PhantomData); +pub struct DispatchFieldsRef(pub PhantomData); + +pub type DispatchFieldValues = DispatchFields>; + +pub type DispatchFieldValueRefs = DispatchFieldsRef>; + #[cgp_provider] impl Computer for DispatchFields @@ -20,6 +29,26 @@ where } } +#[cgp_provider] +impl TryComputer + for DispatchFields +where + Context: HasErrorType, + Input: HasFields, + Fields: FieldsToExtractFieldHandlers, + DispatchHandlers: TryComputer, +{ + type Output = Output; + + fn try_compute( + context: &Context, + code: PhantomData, + input: Input, + ) -> Result { + DispatchHandlers::try_compute(context, code, input) + } +} + #[cgp_provider] impl Handler for DispatchFields @@ -40,6 +69,64 @@ where } } +#[cgp_provider] +impl Computer + for DispatchFieldsRef +where + Input: HasFieldsRef, + for<'b> Input::FieldsRef<'b>: FieldsToExtractFieldHandlers, + for<'b> DispatchHandlersRef< as FieldsToExtractFieldHandlers>::Handlers>: + Computer, +{ + type Output = Output; + + fn compute(context: &Context, code: PhantomData, input: &Input) -> Output { + DispatchHandlersRef::compute(context, code, input) + } +} + +#[cgp_provider] +impl TryComputer + for DispatchFieldsRef +where + Context: HasErrorType, + Input: HasFieldsRef, + for<'b> Input::FieldsRef<'b>: FieldsToExtractFieldHandlers, + for<'b> DispatchHandlersRef< as FieldsToExtractFieldHandlers>::Handlers>: + TryComputer, +{ + type Output = Output; + + fn try_compute( + context: &Context, + code: PhantomData, + input: &Input, + ) -> Result { + DispatchHandlersRef::try_compute(context, code, input) + } +} + +#[cgp_provider] +impl Handler + for DispatchFieldsRef +where + Context: HasAsyncErrorType, + Input: Send + Sync + HasFieldsRef, + for<'b> Input::FieldsRef<'b>: FieldsToExtractFieldHandlers, + for<'b> DispatchHandlersRef< as FieldsToExtractFieldHandlers>::Handlers>: + Handler, +{ + type Output = Output; + + async fn handle( + context: &Context, + code: PhantomData, + input: &Input, + ) -> Result { + DispatchHandlersRef::handle(context, code, input).await + } +} + trait FieldsToExtractFieldHandlers { type Handlers; } diff --git a/crates/cgp-dispatch/src/providers/dispatch_handlers.rs b/crates/cgp-dispatch/src/providers/dispatch_handlers.rs index 59560515..145c99fd 100644 --- a/crates/cgp-dispatch/src/providers/dispatch_handlers.rs +++ b/crates/cgp-dispatch/src/providers/dispatch_handlers.rs @@ -6,6 +6,7 @@ use cgp_handler::{ }; pub struct DispatchHandlers(pub PhantomData); +pub struct DispatchHandlersRef(pub PhantomData); #[cgp_provider] impl Computer @@ -77,6 +78,90 @@ where } } +#[cgp_provider] +impl TryComputer + for DispatchHandlersRef +where + Context: HasErrorType, + Input: HasExtractorRef, + Handlers: for<'b> TryDispatchComputer< + Context, + Code, + Input::ExtractorRef<'b>, + Output = Output, + Remainder: FinalizeExtract, + >, +{ + type Output = Output; + + fn try_compute( + _context: &Context, + code: PhantomData, + input: &Input, + ) -> Result { + let res = Handlers::try_compute(_context, code, input.extractor_ref())?; + + match res { + Ok(output) => Ok(output), + Err(remainder) => remainder.finalize_extract(), + } + } +} +#[cgp_provider] +impl Computer + for DispatchHandlersRef +where + Input: HasExtractorRef, + Handlers: for<'b> DispatchComputer< + Context, + Code, + Input::ExtractorRef<'b>, + Output = Output, + Remainder: FinalizeExtract, + >, +{ + type Output = Output; + + fn compute(_context: &Context, code: PhantomData, input: &Input) -> Output { + let res = Handlers::compute(_context, code, input.extractor_ref()); + + match res { + Ok(output) => output, + Err(remainder) => remainder.finalize_extract(), + } + } +} + +#[cgp_provider] +impl Handler + for DispatchHandlersRef +where + Context: HasAsyncErrorType, + Input: HasExtractorRef + Send + Sync, + Handlers: for<'b> DispatchHandler< + Context, + Code, + Input::ExtractorRef<'b>, + Output = Output, + Remainder: FinalizeExtract, + >, +{ + type Output = Output; + + async fn handle( + _context: &Context, + code: PhantomData, + input: &Input, + ) -> Result { + let res = Handlers::handle(_context, code, input.extractor_ref()).await?; + + match res { + Ok(output) => Ok(output), + Err(remainder) => Err(remainder.finalize_extract()), + } + } +} + trait DispatchComputer { type Output; diff --git a/crates/cgp-handler/src/providers/field.rs b/crates/cgp-handler/src/providers/field.rs index 5a0a5f5d..739eb9dc 100644 --- a/crates/cgp-handler/src/providers/field.rs +++ b/crates/cgp-handler/src/providers/field.rs @@ -4,7 +4,7 @@ use crate::{ Computer, ComputerComponent, Handler, HandlerComponent, TryComputer, TryComputerComponent, }; -pub struct HandleFieldValue(pub PhantomData); +pub struct HandleFieldValue(pub PhantomData); #[cgp_provider] impl Computer>