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-core/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use cgp_field::types::{
pub use cgp_macro::{
BuildField, CgpData, CgpRecord, CgpVariant, ExtractField, FromVariant, HasField, HasFields,
Product, Sum, Symbol, cgp_auto_getter, cgp_component, cgp_context, cgp_getter, cgp_impl,
cgp_new_provider, cgp_preset, cgp_provider, cgp_type, check_components,
cgp_inherit, cgp_new_provider, cgp_preset, cgp_provider, cgp_type, check_components,
delegate_and_check_components, delegate_components, product, re_export_imports, replace_with,
};
pub use cgp_type::{HasType, ProvideType, UseType};
10 changes: 6 additions & 4 deletions crates/cgp-macro-lib/src/derive_context/derive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use quote::quote;
use syn::{AngleBracketedGenericArguments, Ident, ItemImpl, ItemStruct, parse_quote, parse2};
use syn::{Ident, ItemImpl, ItemStruct, parse_quote, parse2};

use crate::parse::TypeGenerics;
use crate::parse::{SimpleType, TypeGenerics};

pub fn derive_has_components(
provider_name: &Ident,
Expand All @@ -28,9 +28,11 @@ pub fn derive_has_components(
pub fn derive_delegate_preset(
provider_name: &Ident,
provider_generics: &Option<TypeGenerics>,
preset_name: &Ident,
preset_generics: &Option<AngleBracketedGenericArguments>,
preset: &SimpleType,
) -> syn::Result<(ItemImpl, ItemImpl)> {
let preset_name = &preset.name;
let preset_generics = &preset.generics;

let provider_params = match provider_generics {
Some(generics) => {
let params = &generics.generics.params;
Expand Down
10 changes: 3 additions & 7 deletions crates/cgp-macro-lib/src/entrypoints/cgp_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,9 @@ pub fn cgp_context(attr: TokenStream, body: TokenStream) -> syn::Result<TokenStr
};

match &context_spec.preset {
Some((preset_path, preset_generics)) => {
let (delegate_impl, is_provider_impl) = derive_delegate_preset(
provider_name,
provider_generics,
preset_path,
preset_generics,
)?;
Some(preset) => {
let (delegate_impl, is_provider_impl) =
derive_delegate_preset(provider_name, provider_generics, preset)?;

Ok(quote! {
#base_derived
Expand Down
25 changes: 25 additions & 0 deletions crates/cgp-macro-lib/src/entrypoints/cgp_inherit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{ItemStruct, parse2};

use crate::derive_context::derive_delegate_preset;
use crate::parse::{SimpleType, TypeGenerics};

pub fn cgp_inherit(attr: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
let context_struct: ItemStruct = parse2(body)?;

let preset: SimpleType = parse2(attr)?;

let type_generics = TypeGenerics::try_from(&context_struct.generics)?;

let (delegate_impl, is_provider_impl) =
derive_delegate_preset(&context_struct.ident, &Some(type_generics), &preset)?;

Ok(quote! {
#context_struct

#delegate_impl

#is_provider_impl
})
}
2 changes: 2 additions & 0 deletions crates/cgp-macro-lib/src/entrypoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod cgp_context;
mod cgp_data;
mod cgp_getter;
mod cgp_impl;
mod cgp_inherit;
mod cgp_new_provider;
mod cgp_preset;
mod cgp_provider;
Expand All @@ -28,6 +29,7 @@ pub use cgp_context::*;
pub use cgp_data::*;
pub use cgp_getter::*;
pub use cgp_impl::*;
pub use cgp_inherit::*;
pub use cgp_new_provider::*;
pub use cgp_preset::*;
pub use cgp_provider::*;
Expand Down
17 changes: 5 additions & 12 deletions crates/cgp-macro-lib/src/parse/context_spec.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use syn::Ident;
use syn::parse::{Parse, ParseStream};
use syn::token::{Colon, Lt};
use syn::{AngleBracketedGenericArguments, Ident};

use crate::parse::TypeGenerics;
use crate::parse::{SimpleType, TypeGenerics};

pub struct ContextSpec {
pub provider_name: Ident,
pub provider_generics: Option<TypeGenerics>,
pub preset: Option<(Ident, Option<AngleBracketedGenericArguments>)>,
pub preset: Option<SimpleType>,
}

impl Parse for ContextSpec {
Expand All @@ -24,15 +24,8 @@ impl Parse for ContextSpec {

let preset = match colon {
Some(_) => {
let path = input.parse()?;

let generics = if input.peek(Lt) {
Some(input.parse()?)
} else {
None
};

Some((path, generics))
let preset = input.parse()?;
Some(preset)
}
None => None,
};
Expand Down
7 changes: 7 additions & 0 deletions crates/cgp-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,13 @@ pub fn cgp_context(attr: TokenStream, item: TokenStream) -> TokenStream {
.into()
}

#[proc_macro_attribute]
pub fn cgp_inherit(attr: TokenStream, item: TokenStream) -> TokenStream {
cgp_macro_lib::cgp_inherit(attr.into(), item.into())
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}

/**
The `#[blanket_trait]` macro can be used to define trait aliases that contain
empty body and trivial blanket implementations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@ use crate::preset_tests::basic::components::{
};
use crate::preset_tests::basic::preset::{CheckDelegatesForMyPreset, MyPreset};

#[cgp_inherit(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
Expand Down
28 changes: 28 additions & 0 deletions crates/cgp-tests/tests/preset_tests/generics/consumer_delegate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use cgp::prelude::*;

use crate::preset_tests::generics::components::{
BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent,
};
use crate::preset_tests::generics::preset::MyGenericPreset;

#[cgp_inherit(MyGenericPreset<T>)]
#[derive(HasField)]
pub struct MyContext<T> {
pub foo: T,
pub bar: T,
}

check_components! {
<T> CanUseMyContext for MyContext<T> {
FooTypeProviderComponent,
BarTypeProviderComponent,
BarGetterComponent,
}
}

check_components! {
<const I: usize, T>
CanUseFooGetter for MyContext<T> {
FooGetterComponent<Index<I>>: Index<I>,
}
}
1 change: 1 addition & 0 deletions crates/cgp-tests/tests/preset_tests/generics/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod components;
pub mod consumer_delegate;
pub mod contexts;
pub mod preset;
Loading