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
12 changes: 11 additions & 1 deletion crates/cgp-macro-lib/src/cgp_fn/attributes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use syn::punctuated::Punctuated;
use syn::token::Comma;
use syn::{Attribute, TypeParamBound, WherePredicate};
use syn::{Attribute, GenericParam, TypeParamBound, WherePredicate};

use crate::cgp_fn::{FunctionAttributes, UseTypeSpec};
use crate::cgp_impl::UseProviderSpec;
Expand All @@ -17,23 +17,33 @@ pub fn parse_function_attributes(
if ident == "extend" {
let extend_bound = attribute
.parse_args_with(Punctuated::<TypeParamBound, Comma>::parse_terminated)?;

parsed_attributes.extend.extend(extend_bound);
} else if ident == "extend_where" {
let where_predicates = attribute
.parse_args_with(Punctuated::<WherePredicate, Comma>::parse_terminated)?;

parsed_attributes.extend_where.extend(where_predicates);
} else if ident == "uses" {
let uses =
attribute.parse_args_with(Punctuated::<SimpleType, Comma>::parse_terminated)?;

parsed_attributes.uses.extend(uses);
} else if ident == "use_type" {
let use_type = attribute
.parse_args_with(Punctuated::<UseTypeSpec, Comma>::parse_terminated)?;

parsed_attributes.use_type.extend(use_type);
} else if ident == "use_provider" {
let use_provider = attribute
.parse_args_with(Punctuated::<UseProviderSpec, Comma>::parse_terminated)?;

parsed_attributes.use_provider.extend(use_provider);
} else if ident == "impl_generics" {
let impl_generics = attribute
.parse_args_with(Punctuated::<GenericParam, Comma>::parse_terminated)?;

parsed_attributes.impl_generics.extend(impl_generics);
} else {
rest_attributes.push(attribute);
}
Expand Down
5 changes: 5 additions & 0 deletions crates/cgp-macro-lib/src/cgp_fn/item_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ pub fn derive_item_impl(
.params
.insert(0, parse2(quote! { __Context__ })?);

item_impl
.generics
.params
.extend(attributes.impl_generics.clone());

{
let mut bounds: Punctuated<TypeParamBound, Plus> = Punctuated::default();
bounds.extend(attributes.extend.clone());
Expand Down
3 changes: 2 additions & 1 deletion crates/cgp-macro-lib/src/cgp_fn/spec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use syn::token::Mut;
use syn::{Ident, Type, TypeParamBound, WherePredicate};
use syn::{GenericParam, Ident, Type, TypeParamBound, WherePredicate};

use crate::cgp_fn::UseTypeSpec;
use crate::cgp_impl::UseProviderSpec;
Expand All @@ -22,4 +22,5 @@ pub struct FunctionAttributes {
pub uses: Vec<SimpleType>,
pub use_type: Vec<UseTypeSpec>,
pub use_provider: Vec<UseProviderSpec>,
pub impl_generics: Vec<GenericParam>,
}
32 changes: 32 additions & 0 deletions crates/cgp-tests/tests/cgp_fn_tests/impl_generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use core::fmt::Display;

use cgp::prelude::*;

#[cgp_fn]
#[impl_generics(Name: Display)]
pub fn greet(&self, #[implicit] name: &Name) -> String
where
Name: Display,
{
format!("Hello, {}!", name)
}

#[cgp_fn]
#[uses(Greet)]
pub fn test_greet(&self) {
assert_eq!(self.greet(), "Hello, John!");
}

#[derive(HasField)]
pub struct Person {
pub name: String,
}

#[test]
fn test_impl_generics() {
let person = Person {
name: "John".to_string(),
};

person.test_greet();
}
1 change: 1 addition & 0 deletions crates/cgp-tests/tests/cgp_fn_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod extend;
pub mod foreign_type;
pub mod foreign_type_equality;
pub mod generics;
pub mod impl_generics;
pub mod multi;
pub mod mutable;
pub mod nested_foreign_type;
Expand Down
Loading