Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion crates/cgp-component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
mod traits;
mod types;

pub use traits::{CanUseComponent, DelegateComponent, HasCgpProvider, IsProviderFor};
pub use traits::{CanUseComponent, DelegateComponent, IsProviderFor};
pub use types::{UseContext, UseDelegate, UseFields, WithContext, WithProvider};
10 changes: 5 additions & 5 deletions crates/cgp-component/src/traits/can_use_component.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::{HasCgpProvider, IsProviderFor};
use crate::{DelegateComponent, IsProviderFor};

/**
This is a convenient type alias that is used in the same way as [`IsProviderFor`],
but with the `Self` type being the `Context` type rather than the `Provider` type
that implements the provider trait.

The `CanUseComponent` trait is automatically implemented for any CGP `Context` type
that implements the `HasCgpProvider` trait, and when `Contex::CgpProvider` implements
`IsProviderFor<Component, Context, Params>`.
that implements the `DelegateComponent<Component>` trait, and when `Contex::Delegate`
implements `IsProviderFor<Component, Context, Params>`.

This trait is used by `check_components!` to check whether a `Context` implements
a given `Component` through its provider. When there are unsatisfied constraints,
Expand All @@ -17,7 +17,7 @@ pub trait CanUseComponent<Component, Params: ?Sized = ()> {}

impl<Context, Component, Params: ?Sized> CanUseComponent<Component, Params> for Context
where
Context: HasCgpProvider,
Context::CgpProvider: IsProviderFor<Component, Context, Params>,
Context: DelegateComponent<Component>,
Context::Delegate: IsProviderFor<Component, Context, Params>,
{
}
37 changes: 0 additions & 37 deletions crates/cgp-component/src/traits/has_provider.rs

This file was deleted.

2 changes: 0 additions & 2 deletions crates/cgp-component/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
mod can_use_component;
mod delegate_component;
mod has_provider;
mod is_provider;

pub use can_use_component::*;
pub use delegate_component::DelegateComponent;
pub use has_provider::HasCgpProvider;
pub use is_provider::*;
4 changes: 2 additions & 2 deletions crates/cgp-core/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ pub use core::marker::PhantomData;

pub use cgp_async_macro::async_trait;
pub use cgp_component::{
CanUseComponent, DelegateComponent, HasCgpProvider, IsProviderFor, UseContext, UseDelegate,
UseFields, WithContext, WithProvider,
CanUseComponent, DelegateComponent, IsProviderFor, UseContext, UseDelegate, UseFields,
WithContext, WithProvider,
};
pub use cgp_error::{CanRaiseError, CanWrapError, HasErrorType};
pub use cgp_field::impls::{IsMut, IsNothing, IsPresent, IsRef, IsVoid, UseField};
Expand Down
2 changes: 1 addition & 1 deletion crates/cgp-error/src/traits/can_raise_error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgp_component::{DelegateComponent, HasCgpProvider, IsProviderFor, UseContext, UseDelegate};
use cgp_component::{DelegateComponent, IsProviderFor, UseContext, UseDelegate};
use cgp_macro::cgp_component;

use crate::traits::has_error_type::HasErrorType;
Expand Down
2 changes: 1 addition & 1 deletion crates/cgp-error/src/traits/can_wrap_error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgp_component::{DelegateComponent, HasCgpProvider, IsProviderFor, UseContext, UseDelegate};
use cgp_component::{DelegateComponent, IsProviderFor, UseContext, UseDelegate};
use cgp_macro::cgp_component;

use crate::traits::HasErrorType;
Expand Down
2 changes: 1 addition & 1 deletion crates/cgp-error/src/traits/has_error_type.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt::Debug;

use cgp_component::{DelegateComponent, HasCgpProvider, IsProviderFor, UseContext, WithProvider};
use cgp_component::{DelegateComponent, IsProviderFor, UseContext, WithProvider};
use cgp_macro::cgp_type;
use cgp_type::{ProvideType, UseType};

Expand Down
17 changes: 10 additions & 7 deletions crates/cgp-macro-lib/src/derive_component/consumer_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use alloc::vec::Vec;

use proc_macro2::Span;
use quote::{ToTokens, quote};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::{Brace, Eq, For, Impl};
use syn::token::{Brace, Comma, Eq, For, Impl};
use syn::{
Error, GenericParam, Generics, Ident, ImplItem, ImplItemConst, ItemImpl, ItemTrait, Path,
TraitItem, TypeParamBound, Visibility, parse2,
Expand All @@ -17,6 +18,8 @@ pub fn derive_consumer_impl(
consumer_trait: &ItemTrait,
provider_name: &Ident,
context_type: &Ident,
component_name: &Ident,
component_params: &Punctuated<Ident, Comma>,
) -> syn::Result<ItemImpl> {
let consumer_name = &consumer_trait.ident;

Expand Down Expand Up @@ -61,7 +64,7 @@ pub fn derive_consumer_impl(

{
let has_component_constraint: TypeParamBound = parse2(quote! {
HasCgpProvider
DelegateComponent< #component_name < #component_params > >
})?;

let provider_constraint: TypeParamBound = parse2(quote! {
Expand All @@ -75,14 +78,14 @@ pub fn derive_consumer_impl(
})?);

where_clause.predicates.push(parse2(quote! {
#context_type :: CgpProvider : #provider_constraint
#context_type :: Delegate : #provider_constraint
})?);
}
_ => {
generics.where_clause = Some(parse2(quote! {
where
#context_type : #has_component_constraint,
#context_type :: CgpProvider : #provider_constraint
#context_type :: Delegate : #provider_constraint
})?);
}
}
Expand All @@ -98,7 +101,7 @@ pub fn derive_consumer_impl(
TraitItem::Fn(trait_fn) => {
let impl_fn = derive_delegated_fn_impl(
&trait_fn.sig,
&parse2(quote!(#context_type :: CgpProvider))?,
&parse2(quote!(#context_type :: Delegate))?,
)?;

impl_items.push(ImplItem::Fn(impl_fn));
Expand All @@ -121,7 +124,7 @@ pub fn derive_consumer_impl(
let impl_type = derive_delegate_type_impl(
trait_type,
parse2(quote!(
< #context_type :: CgpProvider as #provider_name < #provider_type_generics > > :: #type_name #type_generics
< #context_type :: Delegate as #provider_name < #provider_type_generics > > :: #type_name #type_generics
))?,
);

Expand All @@ -132,7 +135,7 @@ pub fn derive_consumer_impl(
let (_, type_generics, _) = trait_item_const.generics.split_for_impl();

let impl_expr = parse2(quote! {
< #context_type :: CgpProvider as #provider_name < #provider_type_generics > > :: #const_ident #type_generics
< #context_type :: Delegate as #provider_name < #provider_type_generics > > :: #const_ident #type_generics
})?;

let impl_item_const = ImplItemConst {
Expand Down
8 changes: 7 additions & 1 deletion crates/cgp-macro-lib/src/derive_component/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ pub fn derive_component_with_ast(
context_type,
)?;

let consumer_impl = derive_consumer_impl(&consumer_trait, provider_name, context_type)?;
let consumer_impl = derive_consumer_impl(
&consumer_trait,
provider_name,
context_type,
component_name,
component_params,
)?;

let provider_impl = derive_provider_impl(
context_type,
Expand Down
10 changes: 7 additions & 3 deletions crates/cgp-macro-lib/src/derive_context/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ pub fn derive_has_components(
) -> syn::Result<ItemImpl> {
let context_name = &context_struct.ident;

let (impl_generics, ty_generics, where_clause) = context_struct.generics.split_for_impl();
let mut generics = context_struct.generics.clone();
generics.params.insert(0, parse2(quote! { __Name__ })?);

let (impl_generics, _, _) = generics.split_for_impl();
let (_, ty_generics, where_clause) = context_struct.generics.split_for_impl();

parse2(quote! {
impl #impl_generics HasCgpProvider for #context_name #ty_generics
impl #impl_generics DelegateComponent<__Name__> for #context_name #ty_generics
#where_clause
{
type CgpProvider = #provider_name #provider_generics;
type Delegate = #provider_name #provider_generics;
}
})
}
Expand Down
6 changes: 3 additions & 3 deletions crates/cgp-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> TokenStream {
the context provider would be named in the format `{struct_name}Components`.

The macro generates a struct definition for the context provider, and implements
`HasCgpProvider` for the context struct to point to the context provider.
`DelegateComponent` for the context struct to point to the context provider.

## Example

Expand All @@ -748,8 +748,8 @@ pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> TokenStream {
```rust,ignore
struct MyAppComponents;

impl HasCgpProvider for MyApp {
type CgpProvider = MyAppComponents;
impl<Name> DelegateComponent<Name> for MyApp {
type Delegate = MyAppComponents;
}
```

Expand Down
4 changes: 0 additions & 4 deletions crates/cgp-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
pub mod r#async;
pub mod blanket_trait;
pub mod cgp_component;
pub mod cgp_impl;
pub mod check_components;
pub mod compose;
pub mod delegate_and_check_components;
pub mod delegate_components;
pub mod getter;
pub mod has_field;
pub mod has_fields;
pub mod monad;
pub mod preset;
pub mod symbol;
pub mod use_delegate;
1 change: 1 addition & 0 deletions crates/cgp-tests/tests/component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod component_tests;
40 changes: 40 additions & 0 deletions crates/cgp-tests/tests/component_tests/consumer_delegate/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use cgp::prelude::*;

#[cgp_getter]
pub trait HasName {
fn name(&self) -> &str;
}

#[cgp_getter]
pub trait HasCount {
fn count(&self) -> u32;
}

#[derive(HasField)]
pub struct App {
pub name: String,
pub count: u32,
}

delegate_components! {
App {
NameGetterComponent: UseField<Symbol!("name")>,
}
}

impl HasCount for App {
fn count(&self) -> u32 {
self.count
}
}

#[test]
fn test_basic_consumer_delegate() {
let app = App {
name: "John".to_owned(),
count: 42,
};

assert_eq!(app.name(), "John");
assert_eq!(app.count(), 42);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use cgp::prelude::*;

#[cgp_getter {
provider: ValueGetter,
name: ValueGetterComponent<Value>,
}]
pub trait HasValue<Value> {
fn value(&self, _tag: PhantomData<Value>) -> &Value;
}

#[derive(HasField)]
pub struct App {
pub name: String,
pub count: u32,
}

delegate_components! {
App {
ValueGetterComponent<String>: UseField<Symbol!("name")>,
}
}

impl HasValue<u32> for App {
fn value(&self, _tag: PhantomData<u32>) -> &u32 {
&self.count
}
}

#[test]
fn test_generic_consumer_delegate() {
let app = App {
name: "John".to_owned(),
count: 42,
};

assert_eq!(app.value(PhantomData::<String>), "John");
assert_eq!(app.value(PhantomData::<u32>), &42);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod basic;
pub mod generics;
4 changes: 4 additions & 0 deletions crates/cgp-tests/tests/component_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod cgp_component;
pub mod cgp_impl;
pub mod consumer_delegate;
pub mod delegate_components;
3 changes: 3 additions & 0 deletions crates/cgp-tests/tests/preset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#![allow(clippy::module_inception)]

pub mod preset_tests;
36 changes: 36 additions & 0 deletions crates/cgp-tests/tests/preset_tests/basic/consumer_delegate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cgp::prelude::*;

use crate::preset_tests::basic::components::{
BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, HasBar,
};
use crate::preset_tests::basic::preset::{CheckDelegatesForMyPreset, MyPreset};

#[derive(HasField)]
pub struct MyContext {
pub foo: (),
pub bar: (),
}

impl<__Name__> DelegateComponent<__Name__> for MyContext
where
Self: MyPreset::IsPreset<__Name__>,
MyPreset::Components: DelegateComponent<__Name__>,
{
type Delegate = <MyPreset::Components as DelegateComponent<__Name__>>::Delegate;
}

impl HasBar for MyContext {
fn bar(&self) -> &Self::Bar {
&self.bar
}
}

check_components! {
CanUseMyContext for MyContext {
FooTypeProviderComponent,
BarTypeProviderComponent,
FooGetterComponent,
}
}

impl CheckDelegatesForMyPreset for MyContext {}
Loading
Loading