Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
596fce0
Introduce new field traits
soareschen Jun 17, 2025
b8ade37
Initial implementation for derive_builder macro
soareschen Jun 17, 2025
a96ae87
Test deriving Builder
soareschen Jun 17, 2025
b480bfe
Derive HasBuilder
soareschen Jun 17, 2025
b89af53
Add tests for indexed and generic structs
soareschen Jun 17, 2025
a468b9c
Draft implement derive_build_field
soareschen Jun 17, 2025
54c6f30
Test derivation of BuildField
soareschen Jun 17, 2025
732d9e1
Minor refactoring
soareschen Jun 18, 2025
cf44285
Draft implement FinalizeBuild derive
soareschen Jun 18, 2025
6a8ee05
Test derive FinalizeBuild
soareschen Jun 18, 2025
f49d195
Minor refactoring
soareschen Jun 18, 2025
97469d4
Split macro impls into smaller files
soareschen Jun 18, 2025
5f5715f
Add macro util helpers
soareschen Jun 18, 2025
72fdec6
Redesign HasExtractor trait and add HasExtractorRef
soareschen Jun 18, 2025
b95e956
Draft implement derive_extractor_enum
soareschen Jun 18, 2025
1b78dde
Test use of derive(ExtractField)
soareschen Jun 18, 2025
385ee91
Derive ExtractorRef
soareschen Jun 18, 2025
1d555b6
Draft implement ExtractField impls
soareschen Jun 18, 2025
ac06b68
Test deriving ExtractField
soareschen Jun 18, 2025
e559131
Test derive ExtractField for PartialRef
soareschen Jun 18, 2025
1eb5548
Draft implement derive HasExtractor
soareschen Jun 18, 2025
fba4153
Implement derive HasExtractorRef
soareschen Jun 18, 2025
4c705a8
Draft implement derive FinalizeExtract
soareschen Jun 18, 2025
63224fb
Test using derived extractor
soareschen Jun 18, 2025
b424466
Also derive HasField for builders
soareschen Jun 18, 2025
95b1857
Draft implement sum type dispatcher
soareschen Jun 18, 2025
99ba87d
Test sum type dispatcher
soareschen Jun 18, 2025
585feb7
Implement DispatchFields
soareschen Jun 18, 2025
0da31bd
Refactor HasFields instance to simplify single-element tuple
soareschen Jun 18, 2025
1dd5b64
DispatchFields is still causing overflow
soareschen Jun 18, 2025
8c206dc
DispatchFields actually cause Rust to crash
soareschen Jun 18, 2025
dd4ef97
Make DispatchHandlers work without provider for Void
soareschen Jun 19, 2025
06afa5e
Introduce FromVariant trait
soareschen Jun 19, 2025
ecb595c
Implement derive FromVariant
soareschen Jun 19, 2025
cb164c4
Test deriving FromVariant
soareschen Jun 19, 2025
97b6ad1
Implement CanExtractFrom
soareschen Jun 19, 2025
a32aebc
Test open sum type conversions
soareschen Jun 19, 2025
994a141
Define and derive TakeField
soareschen Jun 19, 2025
249525c
Define and derive IntoBuilder
soareschen Jun 19, 2025
1c07577
Implement CanBuildInto
soareschen Jun 19, 2025
2a782eb
Test CanBuildFrom
soareschen Jun 19, 2025
bbe9172
Rename and refactor ExtractFrom to ExtractInto
soareschen Jun 19, 2025
62d6cc4
Bypass infinite recursion error in Rust
soareschen Jun 19, 2025
2af260e
Move dispatcher handler to new cgp-dispatch crate
soareschen Jun 19, 2025
73c9145
Implement UseInputDelegate for CanCompute
soareschen Jun 19, 2025
401a6ac
Implement DispatchHandlers
soareschen Jun 19, 2025
0f974ff
Implement ExtractAndHandle
soareschen Jun 19, 2025
920c58a
Test use of DispatchHandlers
soareschen Jun 19, 2025
91acd2e
Add more tests for DispatchHandlers
soareschen Jun 19, 2025
0a28bf7
Simplify implementation of DispatchFields using DispatchHandlers
soareschen Jun 19, 2025
1752269
Slightly improve tests
soareschen Jun 19, 2025
e7b614b
Implement BuildWithHandlers
soareschen Jun 20, 2025
f593944
Implement builder handlers
soareschen Jun 20, 2025
2d7284b
Test BuildWithHandlers
soareschen Jun 20, 2025
016284b
Add cgp_producer! macro
soareschen Jun 20, 2025
2074dff
Use cgp_producer! in tests
soareschen Jun 20, 2025
25e13ac
Test build fields
soareschen Jun 20, 2025
e6a2b21
Implement Handler for DispatchHandlers
soareschen Jun 20, 2025
c527c00
Implement Handler for extract handlers
soareschen Jun 20, 2025
4302680
Test dispatch of async handlers
soareschen Jun 20, 2025
95cf063
Test async dispatch fields
soareschen Jun 20, 2025
37da135
Merge branch 'main' into builder
soareschen Jun 22, 2025
0b3b053
Rename CanExtractInto to CanDowncast
soareschen Jun 22, 2025
357bcfa
Implement from_extractor and CanUpcast
soareschen Jun 22, 2025
887a108
Rename CanDowncast to CanDowncastFields and add separate CanDowncast …
soareschen Jun 22, 2025
689dfd4
Add test for enums with generics
soareschen Jun 22, 2025
015f280
Re-implement #[cgp_producer] as proc macro
soareschen Jun 22, 2025
d0b8095
Use new #[cgp_producer] macro in tests
soareschen Jun 23, 2025
8f88809
Remove old cgp_producer! macro
soareschen Jun 23, 2025
67964e6
Allow producer provider ident to be specified as attr
soareschen Jun 23, 2025
5c992de
Implement #[cgp_computer] macro
soareschen Jun 23, 2025
34d95a1
Use #[cgp_computer] in tests
soareschen Jun 23, 2025
bc6930c
Remove bug report
soareschen Jun 23, 2025
b90c6b2
Use helper traits to implement PipeHandlers
soareschen Jun 23, 2025
0051ce5
Add HandleFieldValue helper
soareschen Jun 23, 2025
448d116
Implement #[cgp_handler] macro
soareschen Jun 23, 2025
cdd9727
Test and fix expansion of #[cgp_handler]
soareschen Jun 23, 2025
384e3f7
Add more tests for generated handler
soareschen Jun 23, 2025
61bc0b8
Delegate Handler to Promote in #[cgp_computer]
soareschen Jun 23, 2025
b2eb4ae
Delegate to Promote in #[cgp_producer]
soareschen Jun 23, 2025
1bc5905
Add TryComputer as promotion layer between Computer and Handler
soareschen Jun 23, 2025
e4608bf
Add tests for TryComputer
soareschen Jun 23, 2025
4adc9ec
Implement TryComputer for BuildWithHandlers
soareschen Jun 23, 2025
ddf03c8
Implement TryComputer for dispatchers
soareschen Jun 23, 2025
9a0daf1
Test TryComputer in builders and dispatchers
soareschen Jun 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"crates/cgp-error-eyre",
"crates/cgp-error-std",
"crates/cgp-handler",
"crates/cgp-dispatch",
"crates/cgp-run",
"crates/cgp-runtime",
"crates/cgp-inner",
Expand Down Expand Up @@ -49,6 +50,7 @@ cgp-field = { path = "./crates/cgp-field" }
cgp-error = { path = "./crates/cgp-error" }
cgp-error-extra = { path = "./crates/cgp-error-extra" }
cgp-handler = { path = "./crates/cgp-handler" }
cgp-dispatch = { path = "./crates/cgp-dispatch" }
cgp-run = { path = "./crates/cgp-run" }
cgp-runtime = { path = "./crates/cgp-runtime" }
cgp-inner = { path = "./crates/cgp-inner" }
11 changes: 8 additions & 3 deletions crates/cgp-core/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub use core::marker::PhantomData;

pub use cgp_async::{async_trait, Async, MaybeSend, MaybeSync};
pub use cgp_component::{
CanUseComponent, DelegateComponent, HasCgpProvider, IsProviderFor, UseContext, UseDelegate,
Expand All @@ -8,12 +10,15 @@ pub use cgp_error::{
HasErrorType,
};
pub use cgp_field::{
Char, Cons, Either, Field, FieldGetter, FromFields, HasField, HasFieldMut, HasFields,
HasFieldsRef, Index, MutFieldGetter, Nil, ToFields, ToFieldsRef, UseField, Void,
BuildField, Char, Cons, Either, ExtractField, Field, FieldGetter, FinalizeBuild,
FinalizeExtract, FromFields, FromVariant, HasBuilder, HasExtractor, HasExtractorRef, HasField,
HasFieldMut, HasFields, HasFieldsRef, Index, IntoBuilder, IsNothing, IsPresent, IsVoid,
MapType, MutFieldGetter, Nil, TakeField, ToFields, ToFieldsRef, UseField, Void,
};
pub use cgp_macro::{
cgp_auto_getter, cgp_component, cgp_context, cgp_getter, cgp_new_provider, cgp_preset,
cgp_provider, cgp_type, check_components, delegate_and_check_components, delegate_components,
product, re_export_imports, replace_with, symbol, HasField, HasFields, Product, Sum,
product, re_export_imports, replace_with, symbol, BuildField, ExtractField, FromVariant,
HasField, HasFields, Product, Sum,
};
pub use cgp_type::{HasType, ProvideType, UseType};
14 changes: 14 additions & 0 deletions crates/cgp-dispatch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "cgp-dispatch"
version = "0.4.1"
edition = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
authors = { workspace = true }
rust-version = { workspace = true }
keywords = { workspace = true }
description = "Generalized handler interfaces for functional programming"

[dependencies]
cgp-core = { version = "0.4.1" }
cgp-handler = { version = "0.4.1" }
5 changes: 5 additions & 0 deletions crates/cgp-dispatch/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#![no_std]

mod providers;

pub use providers::*;
162 changes: 162 additions & 0 deletions crates/cgp-dispatch/src/providers/build_handlers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use cgp_core::prelude::*;
use cgp_handler::{Computer, ComputerComponent, TryComputer, TryComputerComponent};

pub struct BuildWithHandlers<Output, Handlers>(pub PhantomData<(Output, Handlers)>);

#[cgp_provider]
impl<Context, Code, Input, Output, Builder, Handlers> Computer<Context, Code, Input>
for BuildWithHandlers<Output, Handlers>
where
Output: HasBuilder<Builder = Builder>,
Handlers: BuilderComputer<Context, Code, Input, Builder>,
Handlers::Output: FinalizeBuild<Output = Output>,
{
type Output = Output;

fn compute(context: &Context, code: PhantomData<Code>, input: Input) -> Self::Output {
Handlers::build(context, code, input, Output::builder()).finalize_build()
}
}

#[cgp_provider]
impl<Context, Code, Input, Output, Builder, Handlers> TryComputer<Context, Code, Input>
for BuildWithHandlers<Output, Handlers>
where
Context: HasErrorType,
Output: HasBuilder<Builder = Builder>,
Handlers: TryBuilderComputer<Context, Code, Input, Builder>,
Handlers::Output: FinalizeBuild<Output = Output>,
{
type Output = Output;

fn try_compute(
context: &Context,
code: PhantomData<Code>,
input: Input,
) -> Result<Self::Output, Context::Error> {
Ok(Handlers::try_build(context, code, input, Output::builder())?.finalize_build())
}
}

pub trait BuilderComputer<Context, Code, Input, Builder> {
type Output;

fn build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Self::Output;
}

pub trait TryBuilderComputer<Context, Code, Input, Builder>
where
Context: HasErrorType,
{
type Output;

fn try_build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Result<Self::Output, Context::Error>;
}

impl<
Context,
Code,
Input,
Builder,
NextBuilder,
Output,
CurrentHandler,
NextHandler,
RestHandlers,
> BuilderComputer<Context, Code, Input, Builder>
for Cons<CurrentHandler, Cons<NextHandler, RestHandlers>>
where
CurrentHandler: BuilderComputer<Context, Code, Input, Builder, Output = NextBuilder>,
Cons<NextHandler, RestHandlers>:
BuilderComputer<Context, Code, Input, NextBuilder, Output = Output>,
Input: Clone,
{
type Output = Output;

fn build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Self::Output {
let next_builder = CurrentHandler::build(context, code, input.clone(), builder);
Cons::build(context, code, input, next_builder)
}
}

impl<
Context,
Code,
Input,
Builder,
NextBuilder,
Output,
CurrentHandler,
NextHandler,
RestHandlers,
> TryBuilderComputer<Context, Code, Input, Builder>
for Cons<CurrentHandler, Cons<NextHandler, RestHandlers>>
where
Context: HasErrorType,
CurrentHandler: TryBuilderComputer<Context, Code, Input, Builder, Output = NextBuilder>,
Cons<NextHandler, RestHandlers>:
TryBuilderComputer<Context, Code, Input, NextBuilder, Output = Output>,
Input: Clone,
{
type Output = Output;

fn try_build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Result<Self::Output, Context::Error> {
let next_builder = CurrentHandler::try_build(context, code, input.clone(), builder)?;
Cons::try_build(context, code, input, next_builder)
}
}

impl<Context, Code, Input, Builder, Handler, Output> BuilderComputer<Context, Code, Input, Builder>
for Cons<Handler, Nil>
where
Handler: BuilderComputer<Context, Code, Input, Builder, Output = Output>,
{
type Output = Output;

fn build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Self::Output {
Handler::build(context, code, input, builder)
}
}

impl<Context, Code, Input, Builder, Handler, Output>
TryBuilderComputer<Context, Code, Input, Builder> for Cons<Handler, Nil>
where
Context: HasErrorType,
Handler: TryBuilderComputer<Context, Code, Input, Builder, Output = Output>,
{
type Output = Output;

fn try_build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Result<Self::Output, Context::Error> {
Handler::try_build(context, code, input, builder)
}
}
45 changes: 45 additions & 0 deletions crates/cgp-dispatch/src/providers/builders/build_field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use cgp_core::prelude::*;
use cgp_handler::{Computer, TryComputer};

use crate::{BuilderComputer, TryBuilderComputer};

pub struct HandleAndBuildField<Tag, Provider = UseContext>(pub PhantomData<(Tag, Provider)>);

impl<Context, Code, Input, Tag, Value, Provider, Output, Builder>
BuilderComputer<Context, Code, Input, Builder> for HandleAndBuildField<Tag, Provider>
where
Provider: Computer<Context, Code, Input, Output = Value>,
Builder: BuildField<Tag, Value = Value, Output = Output>,
{
type Output = Output;

fn build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Self::Output {
let value = Provider::compute(context, code, input);
builder.build_field(PhantomData::<Tag>, value)
}
}

impl<Context, Code, Input, Tag, Value, Provider, Output, Builder>
TryBuilderComputer<Context, Code, Input, Builder> for HandleAndBuildField<Tag, Provider>
where
Context: HasErrorType,
Provider: TryComputer<Context, Code, Input, Output = Value>,
Builder: BuildField<Tag, Value = Value, Output = Output>,
{
type Output = Output;

fn try_build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Result<Self::Output, Context::Error> {
let value = Provider::try_compute(context, code, input)?;
Ok(builder.build_field(PhantomData::<Tag>, value))
}
}
46 changes: 46 additions & 0 deletions crates/cgp-dispatch/src/providers/builders/handle_and_build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use cgp_core::field::CanBuildFrom;
use cgp_core::prelude::*;
use cgp_handler::{Computer, TryComputer};

use crate::{BuilderComputer, TryBuilderComputer};

pub struct HandleAndBuild<Provider = UseContext>(pub PhantomData<Provider>);

impl<Context, Code, Input, Builder, Provider, Output> BuilderComputer<Context, Code, Input, Builder>
for HandleAndBuild<Provider>
where
Provider: Computer<Context, Code, Input>,
Builder: CanBuildFrom<Provider::Output, Output = Output>,
{
type Output = Output;

fn build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Self::Output {
let output = Provider::compute(context, code, input);
builder.build_from(output)
}
}

impl<Context, Code, Input, Builder, Provider, Output>
TryBuilderComputer<Context, Code, Input, Builder> for HandleAndBuild<Provider>
where
Context: HasErrorType,
Provider: TryComputer<Context, Code, Input>,
Builder: CanBuildFrom<Provider::Output, Output = Output>,
{
type Output = Output;

fn try_build(
context: &Context,
code: PhantomData<Code>,
input: Input,
builder: Builder,
) -> Result<Self::Output, Context::Error> {
let output = Provider::try_compute(context, code, input)?;
Ok(builder.build_from(output))
}
}
5 changes: 5 additions & 0 deletions crates/cgp-dispatch/src/providers/builders/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod build_field;
mod handle_and_build;

pub use build_field::*;
pub use handle_and_build::*;
Loading
Loading