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
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ fn derive_blanket_impl(item_trait: &ItemTrait) -> syn::Result<TokenStream> {
if let FnArg::Typed(pat_type) = arg {
let arg_ident = Ident::new(&format!("arg_{}", i), pat_type.span());
arg_idents.push(arg_ident.clone());
pat_type.pat = Box::new(Pat::Ident(PatIdent {
*pat_type.pat = Pat::Ident(PatIdent {
ident: arg_ident,
attrs: Default::default(),
by_ref: Default::default(),
mutability: Default::default(),
subpat: Default::default(),
}));
});

let mut arg_type = pat_type.ty.as_ref().clone();
if let Type::Reference(arg_type) = &mut arg_type {
Expand Down
48 changes: 32 additions & 16 deletions crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, quote};
use syn::parse::discouraged::Speculative;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::token::{Colon, For};
use syn::{Error, FnArg, Ident, ImplItem, ItemImpl, Type, parse2};
use syn::{FnArg, Ident, ImplItem, ItemImpl, Type, parse_quote, parse2};

use crate::derive_provider::{
derive_component_name_from_provider_impl, derive_is_provider_for, derive_provider_struct,
Expand All @@ -16,18 +15,36 @@ use crate::replace_self::{

pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
let spec: ImplProviderSpec = parse2(attr)?;
let item_impl: ItemImpl = parse2(body)?;

let consumer_trait_path = &item_impl
.trait_
.as_ref()
.ok_or_else(|| Error::new(item_impl.span(), "expect impl trait to contain path"))?
.1;

let consumer_trait_path: SimpleType = parse2(consumer_trait_path.to_token_stream())?;

let provider_impl =
transform_impl_trait(&item_impl, &consumer_trait_path, &spec.provider_type)?;
let mut item_impl: ItemImpl = parse2(body)?;

let provider_impl = match &item_impl.trait_ {
Some((_, path, _)) => {
let consumer_trait_path = parse2(path.to_token_stream())?;
let context_type = item_impl.self_ty.as_ref();
transform_impl_trait(
&item_impl,
&consumer_trait_path,
&spec.provider_type,
context_type,
)?
}
None => {
let consumer_trait_path = parse2(item_impl.self_ty.to_token_stream())?;
let context_type = parse_quote! { __Context__ };

item_impl
.generics
.params
.insert(0, parse_quote! { __Context__ });

transform_impl_trait(
&item_impl,
&consumer_trait_path,
&spec.provider_type,
&context_type,
)?
}
};

let component_type = match &spec.component_type {
Some(component_type) => component_type.clone(),
Expand Down Expand Up @@ -92,9 +109,8 @@ pub fn transform_impl_trait(
item_impl: &ItemImpl,
consumer_trait_path: &SimpleType,
provider_type: &Type,
context_type: &Type,
) -> syn::Result<ItemImpl> {
let context_type = item_impl.self_ty.as_ref();

let context_var = if let Ok(ident) = parse2::<Ident>(context_type.to_token_stream()) {
to_snake_case_ident(&ident)
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use cgp::prelude::*;

#[cgp_component(FooProvider)]
pub trait CanDoFoo {
fn foo(&self, value: u32) -> String;
}

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

#[cgp_impl(new ValueToString)]
impl FooProvider {
fn foo(&self, value: u32) -> String {
value.to_string()
}
}

pub mod inner {
use core::fmt::Display;

use cgp::prelude::*;

use super::{FooProvider, FooProviderComponent, HasName};

#[cgp_impl(new WithNamePrefix)]
impl FooProvider
where
Self: HasName,
{
fn foo(&self, value: u32) -> String {
format!("{}: {}", self.name(), value)
}
}

pub struct Foo<Tag> {
pub tag: Tag,
}

#[cgp_impl(new WithFooTag: FooProviderComponent)]
impl<Tag> FooProvider for Foo<Tag>
where
Tag: Display,
{
fn foo(&self, value: u32) -> String {
format!("{}: {}", self.tag, value)
}
}
}
1 change: 1 addition & 0 deletions crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod basic;
pub mod implicit_context;
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.90"
channel = "1.93"
profile = "default"
Loading