diff --git a/crates/cgp-component/src/macros/delegate_all.rs b/crates/cgp-component/src/macros/delegate_all.rs new file mode 100644 index 0000000..d13b2b8 --- /dev/null +++ b/crates/cgp-component/src/macros/delegate_all.rs @@ -0,0 +1,16 @@ +#[macro_export] +macro_rules! delegate_all { + ( + $source_marker:ident, + $source:ty, + $target:ty + $(,)? + ) => { + impl DelegateComponent for $target + where + Self: $source_marker, + { + type Delegate = $source; + } + }; +} diff --git a/crates/cgp-component/src/macros/delegate_component.rs b/crates/cgp-component/src/macros/delegate_component.rs index 8e9da11..64a68c8 100644 --- a/crates/cgp-component/src/macros/delegate_component.rs +++ b/crates/cgp-component/src/macros/delegate_component.rs @@ -1,7 +1,11 @@ #[macro_export] macro_rules! delegate_component { - ( $target:ident $( < $( $param:ident ),* $(,)? > )?; - $name:ty : $forwarded:ty $(,)? + ( + $target:ident + $( < $( $param:ident ),* $(,)? > )? + { + $name:ty : $forwarded:ty $(,)? + } ) => { impl< $( $( $param ),* )* > $crate::traits::delegate_component::DelegateComponent< $name > diff --git a/crates/cgp-component/src/macros/delegate_components.rs b/crates/cgp-component/src/macros/delegate_components.rs index 011faef..68e81fb 100644 --- a/crates/cgp-component/src/macros/delegate_components.rs +++ b/crates/cgp-component/src/macros/delegate_components.rs @@ -1,44 +1,141 @@ #[macro_export] macro_rules! delegate_components { - ( $target:ident $( < $( $param:ident ),* $(,)? > )? ; ) => { + ( + #[mark_component( $marker:ident )] + #[mark_delegate( $delegate_marker:ident )] + $target:ident + $( < $( $param:ident ),* $(,)? > )? + { + $( $rest:tt )* + } + ) => { + $crate::delegate_components!( + @mark_component( $marker ) + @target( $target $( < $( $param ),* > )? ) + @body( $( $rest )* ) + ); + pub trait $marker < Component > {} + + $crate::expand_delegate_constraints!( + @target( $target $( < $( $param ),* > )? ) + @body( $( $rest )* ) + @head_buf( + pub trait $delegate_marker $( < $( $param ),* > )? : Sized + ) + @tail_buf( + {} + ) + ); + + $crate::expand_delegate_constraints!( + @target( $target $( < $( $param ),* > )? ) + @body( $( $rest )* ) + @head_buf( + impl $delegate_marker $( < $( $param ),* > )? for Components + where + Components: Sized + ) + @tail_buf( + {} + ) + ); }; - ( $target:ident $( < $( $param:ident ),* $(,)? > )?; - [ ] : $forwarded:ty - $( , $( $rest:tt )* )? + ( + $( #[mark_component( $marker:ident )] )? + $target:ident + $( < $( $param:ident ),* $(,)? > )? + { + $( $rest:tt )* + } ) => { + $( + pub trait $marker < Component > {} + )? + $crate::delegate_components!( - $target $( < $( $param ),* > )* ; - $( $( $rest )* )? + $( @mark_component( $marker ) )? + @target( $target $( < $( $param ),* > )? ) + @body( $( $rest )* ) ); }; - ( $target:ident $( < $( $param:ident ),* $(,)? > )? ; - [ $name:ty $(, $($names:tt)* )?] : $forwarded:ty - $( , $( $rest:tt )* )? + ( + $( @mark_component( $marker:ident ) )? + @target( + $target:ident + $( < $( $param:ident ),* $(,)? > )? + ) + @body( ) ) => { - $crate::delegate_component!( - $target $( < $( $param ),* > )*; - $name : $forwarded - ); + }; + ( + $( @mark_component( $marker:ident ) )? + @target( + $target:ident + $( < $( $param:ident ),* $(,)? > )? + ) + @body( + [ ] : $forwarded:ty + $( , $( $rest:tt )* )? + ) + ) => { + $crate::delegate_components!( + $( @mark_component( $marker ) )? + @target( $target $( < $( $param ),* > )? ) + @body( + $( $( $rest )* )? + ) + ); + }; + ( + $( @mark_component( $marker:ident ) )? + @target( + $target:ident + $( < $( $param:ident ),* $(,)? > )? + ) + @body( + [ $name:ty $(, $($names:tt)* )?] : $forwarded:ty + $( , $( $rest:tt )* )? + ) + ) => { $crate::delegate_components!( - $target $( < $( $param ),* > )* ; - [ $( $( $names )* )? ] : $forwarded - $( , $( $rest )* )? + $( @mark_component( $marker ) )? + @target( $target $( < $( $param ),* > )? ) + @body( + $name : $forwarded, + [ $( $( $names )* )? ] : $forwarded + $( , $( $rest )* )? + ) ); }; - ( $target:ident $( < $( $param:ident ),* $(,)? > )? ; - $name:ty : $forwarded:ty - $( , $( $rest:tt )* )? + ( + $( @mark_component( $marker:ident ) )? + @target( + $target:ident + $( < $( $param:ident ),* $(,)? > )? + ) + @body( + $name:ty : $forwarded:ty + $( , $( $rest:tt )* )? + ) ) => { $crate::delegate_component!( - $target $( < $( $param ),* > )*; - $name : $forwarded + $target + $( < $( $param ),* > )* + { + $name : $forwarded + } ); + $( impl $marker < $name > for T {} )? + $crate::delegate_components!( - $target $( < $( $param ),* > )* ; - $( $( $rest )* )? + $( @mark_component( $marker ) )? + @target( $target $( < $( $param ),* > )? ) + @body( + $( $( $rest )* )? + ) ); }; } diff --git a/crates/cgp-component/src/macros/expand_delegate_constraints.rs b/crates/cgp-component/src/macros/expand_delegate_constraints.rs new file mode 100644 index 0000000..9a35c14 --- /dev/null +++ b/crates/cgp-component/src/macros/expand_delegate_constraints.rs @@ -0,0 +1,71 @@ +#[macro_export] +macro_rules! expand_delegate_constraints { + ( + @target( $target:ty ) + @body( ) + @head_buf( $( $head:tt )* ) + @tail_buf( $( $tail:tt )* ) + ) => { + $( $head )* + $( $tail )* + }; + ( + @target( $target:ty ) + @body( + [ ] : $forwarded:ty + $( , $( $rest:tt )* )? + ) + @head_buf( $( $head:tt )* ) + @tail_buf( $( $tail:tt )* ) + ) => { + $crate::expand_delegate_constraints!( + @target( $target ) + @body( + $( $( $rest )* )? + ) + @head_buf( $( $head )* ) + @tail_buf( $( $tail )* ) + ); + }; + ( + @target( $target:ty ) + @body( + [ $name:ty $(, $($names:tt)* )?] : $forwarded:ty + $( , $( $rest:tt )* )? + ) + @head_buf( $( $head:tt )* ) + @tail_buf( $( $tail:tt )* ) + ) => { + $crate::expand_delegate_constraints!( + @target( $target ) + @body( + $name : $forwarded, + [ $( $( $names )* )? ] : $forwarded, + $( $( $rest )* )? + ) + @head_buf( $( $head )* ) + @tail_buf( $( $tail )* ) + ); + }; + ( + @target( $target:ty ) + @body( + $name:ty : $forwarded:ty + $( , $( $rest:tt )* )? + ) + @head_buf( $( $head:tt )* ) + @tail_buf( $( $tail:tt )* ) + ) => { + $crate::expand_delegate_constraints!( + @target( $target ) + @body( + $( $( $rest )* )? + ) + @head_buf( + $( $head )* + + $crate::traits::delegate_component::DelegateComponent< $name, Delegate = $target > + ) + @tail_buf( $( $tail )* ) + ); + }; +} diff --git a/crates/cgp-component/src/macros/mod.rs b/crates/cgp-component/src/macros/mod.rs index b95a8c9..52b991e 100644 --- a/crates/cgp-component/src/macros/mod.rs +++ b/crates/cgp-component/src/macros/mod.rs @@ -1,2 +1,4 @@ +pub mod delegate_all; pub mod delegate_component; pub mod delegate_components; +pub mod expand_delegate_constraints; diff --git a/crates/cgp-core/src/lib.rs b/crates/cgp-core/src/lib.rs index 9b85e10..d06b4c6 100644 --- a/crates/cgp-core/src/lib.rs +++ b/crates/cgp-core/src/lib.rs @@ -3,7 +3,8 @@ pub mod prelude; pub use cgp_component::{ - delegate_component, delegate_components, derive_component, DelegateComponent, HasComponents, + delegate_all, delegate_component, delegate_components, derive_component, DelegateComponent, + HasComponents, }; pub use cgp_async::{async_trait, Async};