Skip to content

Commit

Permalink
Introduce cgp-type crate with various refactoring (#23)
Browse files Browse the repository at this point in the history
* Add cgp-type crate

* Add DelegateTo impl type

* Implement WithTypeProvider and UseType

* Add UseFieldType

* Add HasFieldMut trait

* Use core::error::Error in cgp-error-std

* Derive HasFieldMut in derive(HasField) macro

* Organize re-exports

* Fix HasFieldMut macro

* Rename UseFieldType to UseField

* Generalize WithTypeProvider to WithProvider

* Reorganize HasFieldMut into its own module

* Add FieldGetter traits

* Implement FieldGetter for any OutTag for UseField<Tag>

* Add UseContext

* Make impl DelegateTo for ProvideType use Component::Delegate as type

* Revert change to ProvideType implementation

* Add changelog
  • Loading branch information
soareschen authored Sep 30, 2024
1 parent 496252f commit 3a19aac
Show file tree
Hide file tree
Showing 34 changed files with 301 additions and 50 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog

## Pre-Release

- Introduce `cgp-type` crate with various refactoring [#23](https://github.com/contextgeneric/cgp/pull/23)
- Introduce `cgp-type` crate, with the `HasType` component.
- Introduce `FieldGetter` as a manual provider trait for `HasField`.
- Introduce `HasFieldMut` trait to `cgp-field`, and auto derive it in `#[derive(HasField)]`.
- Introduce `DelegateTo` in `cgp-component` as a generalized delegation component.
- Introduce `WithProvider` in `cgp-component` as a generalized provider transformation component.
- Introduce `UseContext` in `cgp-component` for generalized implementation of provider via context.
- Replace `DelegateErrorComponents` in `cgp-error` and replace it with `DelegateTo`.
- Use `core::error::Error` instead of `std::error::Error` in `cgp-error-std`.
11 changes: 11 additions & 0 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
"crates/cgp-component",
"crates/cgp-component-macro",
"crates/cgp-component-macro-lib",
"crates/cgp-type",
"crates/cgp-field",
"crates/cgp-field-macro",
"crates/cgp-field-macro-lib",
Expand All @@ -23,7 +24,7 @@ members = [
]

[workspace.package]
rust-version = "1.79"
rust-version = "1.81"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/contextgeneric/cgp"
Expand All @@ -40,6 +41,7 @@ cgp-sync = { path = "./crates/cgp-sync" }
cgp-component = { path = "./crates/cgp-component" }
cgp-component-macro = { path = "./crates/cgp-component-macro" }
cgp-component-macro-lib = { path = "./crates/cgp-component-macro-lib" }
cgp-type = { path = "./crates/cgp-type" }
cgp-field = { path = "./crates/cgp-field" }
cgp-field-macro = { path = "./crates/cgp-field-macro" }
cgp-field-macro-lib = { path = "./crates/cgp-field-macro-lib" }
Expand Down
2 changes: 2 additions & 0 deletions crates/cgp-component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

pub mod traits;
pub mod types;

pub use cgp_component_macro::{define_components, delegate_components, derive_component};
pub use traits::{DelegateComponent, HasComponents};
pub use types::{DelegateTo, UseContext, WithContext, WithProvider};
3 changes: 3 additions & 0 deletions crates/cgp-component/src/types/delegate_to.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use core::marker::PhantomData;

pub struct DelegateTo<Components>(pub PhantomData<Components>);
7 changes: 7 additions & 0 deletions crates/cgp-component/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod delegate_to;
pub mod use_context;
pub mod with_provider;

pub use delegate_to::DelegateTo;
pub use use_context::{UseContext, WithContext};
pub use with_provider::WithProvider;
5 changes: 5 additions & 0 deletions crates/cgp-component/src/types/use_context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use crate::WithProvider;

pub struct UseContext;

pub type WithContext = WithProvider<UseContext>;
3 changes: 3 additions & 0 deletions crates/cgp-component/src/types/with_provider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use core::marker::PhantomData;

pub struct WithProvider<Provider>(pub PhantomData<Provider>);
1 change: 1 addition & 0 deletions crates/cgp-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ description = """
[dependencies]
cgp-async = { version = "0.1.0" }
cgp-component = { version = "0.1.0" }
cgp-type = { version = "0.1.0" }
cgp-error = { version = "0.1.0" }
cgp-field = { version = "0.1.0" }
cgp-inner = { version = "0.1.0" }
1 change: 1 addition & 0 deletions crates/cgp-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub use cgp_component as component;
pub use cgp_error as error;
pub use cgp_field as field;
pub use cgp_inner as inner;
pub use cgp_type as types;
2 changes: 1 addition & 1 deletion crates/cgp-core/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ pub use cgp_component::{
define_components, delegate_components, derive_component, DelegateComponent, HasComponents,
};
pub use cgp_error::{CanRaiseError, HasErrorType};
pub use cgp_field::{symbol, Char, HasField};
pub use cgp_field::{symbol, Char, HasField, HasFieldMut};
7 changes: 6 additions & 1 deletion crates/cgp-error-std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use std::error::Error as StdError;
#![no_std]

extern crate alloc;

use alloc::boxed::Box;
use core::error::Error as StdError;

use cgp_core::error::{ErrorRaiser, ProvideErrorType};
use cgp_core::prelude::*;
Expand Down
1 change: 1 addition & 0 deletions crates/cgp-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ description = """
[dependencies]
cgp-async = { version = "0.1.0" }
cgp-component = { version = "0.1.0" }
cgp-type = { version = "0.1.0" }
13 changes: 12 additions & 1 deletion crates/cgp-error/src/can_raise_error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgp_component::{derive_component, DelegateComponent, HasComponents};
use cgp_component::{derive_component, DelegateComponent, DelegateTo, HasComponents};

use crate::has_error_type::HasErrorType;

Expand All @@ -14,3 +14,14 @@ use crate::has_error_type::HasErrorType;
pub trait CanRaiseError<E>: HasErrorType {
fn raise_error(e: E) -> Self::Error;
}

impl<Context, Error, Components, Delegate> ErrorRaiser<Context, Error> for DelegateTo<Components>
where
Context: HasErrorType,
Components: DelegateComponent<Error, Delegate = Delegate>,
Delegate: ErrorRaiser<Context, Error>,
{
fn raise_error(e: Error) -> Context::Error {
Delegate::raise_error(e)
}
}
19 changes: 0 additions & 19 deletions crates/cgp-error/src/delegate_error.rs

This file was deleted.

11 changes: 10 additions & 1 deletion crates/cgp-error/src/has_error_type.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use core::fmt::Debug;

use cgp_async::Async;
use cgp_component::{derive_component, DelegateComponent, HasComponents};
use cgp_component::{derive_component, DelegateComponent, HasComponents, WithProvider};
use cgp_type::traits::has_type::ProvideType;

/**
This is used for contexts to declare that they have a _unique_ `Self::Error` type.
Expand All @@ -26,3 +27,11 @@ pub trait HasErrorType {
}

pub type ErrorOf<Context> = <Context as HasErrorType>::Error;

impl<Context, Provider, Error> ProvideErrorType<Context> for WithProvider<Provider>
where
Provider: ProvideType<Context, ErrorTypeComponent, Type = Error>,
Error: Async + Debug,
{
type Error = Error;
}
2 changes: 0 additions & 2 deletions crates/cgp-error/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
mod can_raise_error;
mod delegate_error;
mod has_error_type;

pub use can_raise_error::*;
pub use delegate_error::*;
pub use has_error_type::*;
20 changes: 18 additions & 2 deletions crates/cgp-field-macro-lib/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn derive_has_field_impls(item_struct: &ItemStruct) -> Vec<ItemImpl> {

let field_type = &field.ty;

let item_impl: ItemImpl = parse_quote! {
let has_field_impl: ItemImpl = parse_quote! {
impl #impl_generics HasField< #field_symbol >
for #struct_ident #ty_generics
#where_clause
Expand All @@ -36,7 +36,23 @@ pub fn derive_has_field_impls(item_struct: &ItemStruct) -> Vec<ItemImpl> {
}
};

item_impls.push(item_impl);
let has_field_mut_impl: ItemImpl = parse_quote! {
impl #impl_generics HasFieldMut< #field_symbol >
for #struct_ident #ty_generics
#where_clause
{
fn get_field_mut(
&mut self,
key: ::core::marker::PhantomData< #field_symbol >,
) -> &mut Self::Field
{
&mut self. #field_ident
}
}
};

item_impls.push(has_field_impl);
item_impls.push(has_field_mut_impl);
}
}

Expand Down
44 changes: 44 additions & 0 deletions crates/cgp-field-macro-lib/src/tests/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ fn test_basic_derive_fields() {
}
}

impl HasFieldMut<(Char<'b'>, Char<'a'>, Char<'r'>)> for Foo {
fn get_field_mut(
&mut self,
key: ::core::marker::PhantomData<(Char<'b'>, Char<'a'>, Char<'r'>)>,
) -> &mut Self::Field {
&mut self.bar
}
}

impl HasField<(Char<'b'>, Char<'a'>, Char<'z'>)> for Foo {
type Field = Baz;

Expand All @@ -34,6 +43,15 @@ fn test_basic_derive_fields() {
&self.baz
}
}

impl HasFieldMut<(Char<'b'>, Char<'a'>, Char<'z'>)> for Foo {
fn get_field_mut(
&mut self,
key: ::core::marker::PhantomData<(Char<'b'>, Char<'a'>, Char<'z'>)>,
) -> &mut Self::Field {
&mut self.baz
}
}
};

assert!(equal_token_stream(&derived, &expected));
Expand Down Expand Up @@ -67,6 +85,19 @@ fn test_generic_derive_fields() {
}
}

impl<FooParamA, FooParamB: Clone> HasFieldMut<(Char<'b'>, Char<'a'>, Char<'r'>)>
for Foo<FooParamA, FooParamB>
where
FooParamA: Eq,
{
fn get_field_mut(
&mut self,
key: ::core::marker::PhantomData<(Char<'b'>, Char<'a'>, Char<'r'>)>,
) -> &mut Self::Field {
&mut self.bar
}
}

impl<FooParamA, FooParamB: Clone> HasField<(Char<'b'>, Char<'a'>, Char<'z'>)>
for Foo<FooParamA, FooParamB>
where
Expand All @@ -81,6 +112,19 @@ fn test_generic_derive_fields() {
&self.baz
}
}

impl<FooParamA, FooParamB: Clone> HasFieldMut<(Char<'b'>, Char<'a'>, Char<'z'>)>
for Foo<FooParamA, FooParamB>
where
FooParamA: Eq,
{
fn get_field_mut(
&mut self,
key: ::core::marker::PhantomData<(Char<'b'>, Char<'a'>, Char<'z'>)>,
) -> &mut Self::Field {
&mut self.baz
}
}
};

assert!(equal_token_stream(&derived, &expected));
Expand Down
2 changes: 2 additions & 0 deletions crates/cgp-field/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ description = """

[dependencies]
cgp-field-macro = { version = "0.1.0" }
cgp-component = { version = "0.1.0" }
cgp-type = { version = "0.1.0" }
1 change: 1 addition & 0 deletions crates/cgp-field/src/impls/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod use_field;
40 changes: 40 additions & 0 deletions crates/cgp-field/src/impls/use_field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use core::marker::PhantomData;

use cgp_component::WithProvider;
use cgp_type::traits::has_type::ProvideType;

use crate::traits::has_field::{FieldGetter, HasField};
use crate::traits::has_field_mut::{HasFieldMut, MutFieldGetter};

pub struct UseField<Tag>(pub PhantomData<Tag>);

pub type WithField<Tag> = WithProvider<UseField<Tag>>;

impl<Context, TypeTag, FieldTag, Field> ProvideType<Context, TypeTag> for UseField<FieldTag>
where
Context: HasField<FieldTag, Field = Field>,
{
type Type = Field;
}

impl<Context, OutTag, Tag, Field> FieldGetter<Context, OutTag> for UseField<Tag>
where
Context: HasField<Tag, Field = Field>,
{
type Field = Field;

fn get_field(context: &Context, _tag: PhantomData<OutTag>) -> &Self::Field {
context.get_field(PhantomData)
}
}

impl<Context, OutTag, Tag, Field> MutFieldGetter<Context, OutTag> for UseField<Tag>
where
Context: HasFieldMut<Tag, Field = Field>,
{
type Field = Field;

fn get_field_mut(context: &mut Context, _tag: PhantomData<OutTag>) -> &mut Self::Field {
context.get_field_mut(PhantomData)
}
}
3 changes: 2 additions & 1 deletion crates/cgp-field/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#![no_std]

pub mod impls;
pub mod traits;
pub mod types;

pub use cgp_field_macro::{symbol, HasField};
pub use traits::HasField;
pub use traits::{FieldGetter, HasField, HasFieldMut, MutFieldGetter};
pub use types::Char;
Loading

0 comments on commit 3a19aac

Please sign in to comment.