Skip to content

Commit

Permalink
Quick fix to allow const generic args in derive_component! macro (#16)
Browse files Browse the repository at this point in the history
* Quick fix to allow const generic args in derive_component macro

* Add CI

* Fix clippy

* Fix formatting
  • Loading branch information
soareschen authored Jan 11, 2024
1 parent 2a6e795 commit 9c323af
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 32 deletions.
69 changes: 69 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Rust Unit Tests
on:
pull_request: {}
push:
branches: main

env:
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 1
CARGO_PROFILE_RELEASE_DEBUG: 1
RUST_BACKTRACE: short
CARGO_NET_RETRY: 10
RUSTUP_MAX_RETRIES: 10

# Cancel previous runs of this workflow when a new commit is added to the PR, branch or tag
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: clippy
override: true
- uses: Swatinem/rust-cache@v2
- uses: actions-rs/clippy-check@v1
with:
name: clippy-all-features
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets -- -D warnings

test:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: Swatinem/rust-cache@v2
- name: Install cargo-nextest
run: curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
- uses: actions-rs/cargo@v1
with:
command: test
args: --all-features --no-fail-fast --no-run
- uses: actions-rs/cargo@v1
with:
command: nextest
args: run --all-features --no-fail-fast --workspace --no-capture
47 changes: 30 additions & 17 deletions crates/cgp-component-macro/src/helper/consumer_impl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use syn::punctuated::Punctuated;
use syn::token::{Brace, For, Impl, Plus};
use syn::token::{Brace, Comma, For, Impl, Plus};
use syn::{
parse_quote, GenericParam, Ident, ImplItem, ItemImpl, ItemTrait, Path, TraitItem,
TypeParamBound,
Expand All @@ -15,14 +15,32 @@ pub fn derive_consumer_impl(
) -> ItemImpl {
let consumer_name = &consumer_trait.ident;

let provider_generics = {
let mut provider_generics = consumer_trait.generics.clone();
provider_generics
.params
.insert(0, parse_quote!(#context_type));
provider_generics.where_clause = None;
let consumer_generic_args = {
let mut generic_args: Punctuated<Ident, Comma> = Punctuated::new();

provider_generics
for param in consumer_trait.generics.params.iter() {
match param {
GenericParam::Type(ty) => {
generic_args.push(ty.ident.clone());
}
GenericParam::Const(arg) => {
generic_args.push(arg.ident.clone());
}
GenericParam::Lifetime(_life) => {
unimplemented!()
}
}
}

generic_args
};

let provider_generic_args = {
let mut generic_args = consumer_generic_args.clone();

generic_args.insert(0, parse_quote!(#context_type));

generic_args
};

let impl_generics = {
Expand Down Expand Up @@ -52,7 +70,7 @@ pub fn derive_consumer_impl(
};

let provider_constraint: Punctuated<TypeParamBound, Plus> = parse_quote! {
#provider_name #provider_generics
#provider_name < #provider_generic_args >
};

if let Some(where_clause) = &mut impl_generics.where_clause {
Expand Down Expand Up @@ -103,9 +121,9 @@ pub fn derive_consumer_impl(
};

let impl_type = derive_delegate_type_impl(
&trait_type,
trait_type,
parse_quote!(
< #context_type :: Components as #provider_name #provider_generics > :: #type_name #type_generics
< #context_type :: Components as #provider_name < #provider_generic_args > > :: #type_name #type_generics
),
);

Expand All @@ -115,12 +133,7 @@ pub fn derive_consumer_impl(
}
}

let trait_path: Path = {
let mut trait_generics = consumer_trait.generics.clone();
trait_generics.where_clause = None;

parse_quote!( #consumer_name #trait_generics )
};
let trait_path: Path = parse_quote!( #consumer_name < #consumer_generic_args > );

ItemImpl {
attrs: consumer_trait.attrs.clone(),
Expand Down
4 changes: 2 additions & 2 deletions crates/cgp-component-macro/src/helper/delegate_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ pub fn derive_delegate_type_impl(trait_type: &TraitItemType, delegated_type: Typ
attrs: trait_type.attrs.clone(),
vis: Visibility::Inherited,
defaultness: None,
type_token: trait_type.type_token.clone(),
type_token: trait_type.type_token,
ident: trait_type.ident.clone(),
generics: trait_type.generics.clone(),
eq_token: Eq::default(),
ty: delegated_type,
semi_token: trait_type.semi_token.clone(),
semi_token: trait_type.semi_token,
}
}
35 changes: 22 additions & 13 deletions crates/cgp-component-macro/src/helper/provider_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,24 @@ pub fn derive_provider_impl(

let component_type = Ident::new("Component", Span::call_site());

let provider_generics = {
let mut provider_generics = provider_trait.generics.clone();
provider_generics.where_clause = None;
provider_generics
let provider_generic_args = {
let mut generic_args: Punctuated<Ident, Comma> = Punctuated::new();

for param in provider_trait.generics.params.iter() {
match param {
GenericParam::Type(ty) => {
generic_args.push(ty.ident.clone());
}
GenericParam::Const(arg) => {
generic_args.push(arg.ident.clone());
}
GenericParam::Lifetime(_life) => {
unimplemented!()
}
}
}

generic_args
};

let impl_generics = {
Expand All @@ -37,7 +51,7 @@ pub fn derive_provider_impl(
};

let provider_constraint: Punctuated<TypeParamBound, Plus> = parse_quote! {
#provider_name #provider_generics
#provider_name < #provider_generic_args >
};

if let Some(where_clause) = &mut impl_generics.where_clause {
Expand Down Expand Up @@ -88,9 +102,9 @@ pub fn derive_provider_impl(
};

let impl_type = derive_delegate_type_impl(
&trait_type,
trait_type,
parse_quote!(
< #component_type :: Delegate as #provider_name #provider_generics > :: #type_name #type_generics
< #component_type :: Delegate as #provider_name < #provider_generic_args > > :: #type_name #type_generics
),
);

Expand All @@ -100,12 +114,7 @@ pub fn derive_provider_impl(
}
}

let trait_path: Path = {
let mut trait_generics = provider_trait.generics.clone();
trait_generics.where_clause = None;

parse_quote!( #provider_name #trait_generics )
};
let trait_path: Path = parse_quote!( #provider_name < #provider_generic_args > );

ItemImpl {
attrs: provider_trait.attrs.clone(),
Expand Down
3 changes: 3 additions & 0 deletions crates/cgp-component-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ extern crate proc_macro;

mod helper;

#[cfg(test)]
mod tests;

use proc_macro::TokenStream;

#[proc_macro_attribute]
Expand Down
16 changes: 16 additions & 0 deletions crates/cgp-component-macro/src/tests/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::helper::derive::derive_component;
use quote::quote;

#[test]
fn test_basic_derive_component() {
derive_component(
quote! { FooComponent, FooProvider<Context> },
quote! {
pub trait HasFoo<Bar> {
type Foo;

fn foo(&self) -> Self::Foo;
}
},
);
}
16 changes: 16 additions & 0 deletions crates/cgp-component-macro/src/tests/const_generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::helper::derive::derive_component;
use quote::quote;

#[test]
fn test_derive_component_with_const_generic() {
derive_component(
quote! { FooComponent, FooProvider<Context> },
quote! {
pub trait HasFoo<const BAR: usize> {
type Foo;

fn foo(&self) -> Self::Foo;
}
},
);
}
2 changes: 2 additions & 0 deletions crates/cgp-component-macro/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod basic;
pub mod const_generic;

0 comments on commit 9c323af

Please sign in to comment.