From a4ae2378cec966874660f3a6c2f2df1c77015fc1 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 16:49:53 +0200 Subject: [PATCH 01/29] Add product types --- crates/macros/cgp-macro-core/src/types/mod.rs | 1 + .../cgp-macro-core/src/types/product/mod.rs | 5 +++ .../src/types/product/product_expr.rs | 35 +++++++++++++++++++ .../src/types/product/product_type.rs | 35 +++++++++++++++++++ .../cgp-macro-lib/src/entrypoints/mod.rs | 2 ++ .../cgp-macro-lib/src/entrypoints/product.rs | 22 ++++++++++++ crates/macros/cgp-macro/src/lib.rs | 16 +++++---- 7 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/product/mod.rs create mode 100644 crates/macros/cgp-macro-core/src/types/product/product_expr.rs create mode 100644 crates/macros/cgp-macro-core/src/types/product/product_type.rs create mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/product.rs diff --git a/crates/macros/cgp-macro-core/src/types/mod.rs b/crates/macros/cgp-macro-core/src/types/mod.rs index 024cae30..08edf9dc 100644 --- a/crates/macros/cgp-macro-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/mod.rs @@ -20,3 +20,4 @@ pub mod keywords; pub mod namespace; pub mod path; pub mod provider_impl; +pub mod product; diff --git a/crates/macros/cgp-macro-core/src/types/product/mod.rs b/crates/macros/cgp-macro-core/src/types/product/mod.rs new file mode 100644 index 00000000..425c0670 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/product/mod.rs @@ -0,0 +1,5 @@ +mod product_type; +mod product_expr; + +pub use product_expr::*; +pub use product_type::*; diff --git a/crates/macros/cgp-macro-core/src/types/product/product_expr.rs b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs new file mode 100644 index 00000000..48082cf8 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs @@ -0,0 +1,35 @@ +use syn::Type; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::token::Comma; +use quote::quote; + +use crate::exports::{Cons, Nil}; +use crate::functions::parse_internal; + + +pub struct ProductExpr { + pub types: Punctuated +} + +impl ProductExpr { + pub fn eval(&self) -> syn::Result { + let mut out = quote!(#Nil); + + for ty in self.types.iter().rev() { + out = quote! { + #Cons(#ty, #out) + }; + } + + parse_internal(out) + } +} + +impl Parse for ProductExpr { + fn parse(input: ParseStream) -> syn::Result { + let types = Punctuated::parse_terminated(input)?; + + Ok(Self { types }) + } +} diff --git a/crates/macros/cgp-macro-core/src/types/product/product_type.rs b/crates/macros/cgp-macro-core/src/types/product/product_type.rs new file mode 100644 index 00000000..70ad6ed3 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/product/product_type.rs @@ -0,0 +1,35 @@ +use syn::Type; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::token::Comma; +use quote::quote; + +use crate::exports::{Cons, Nil}; +use crate::functions::parse_internal; + + +pub struct ProductType { + pub types: Punctuated +} + +impl ProductType { + pub fn eval(&self) -> syn::Result { + let mut out = quote!(#Nil); + + for ty in self.types.iter().rev() { + out = quote! { + #Cons< #ty, #out > + }; + } + + parse_internal(out) + } +} + +impl Parse for ProductType { + fn parse(input: ParseStream) -> syn::Result { + let types = Punctuated::parse_terminated(input)?; + + Ok(Self { types }) + } +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs index 18100ecc..213884cd 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs @@ -19,7 +19,9 @@ mod derive_extract_field; mod derive_from_variant; mod derive_has_fields; mod path; +mod product; +pub use product::*; pub use blanket_trait::*; pub use cgp_auto_getter::*; pub use cgp_component::*; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/product.rs b/crates/macros/cgp-macro-lib/src/entrypoints/product.rs new file mode 100644 index 00000000..af6a06e4 --- /dev/null +++ b/crates/macros/cgp-macro-lib/src/entrypoints/product.rs @@ -0,0 +1,22 @@ +use cgp_macro_core::types::product::{ProductExpr, ProductType}; +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +#[allow(non_snake_case)] +pub fn Product(body: TokenStream) -> syn::Result { + let product_type: ProductType = parse2(body)?; + + let evaluated = product_type.eval()?; + + Ok(evaluated.to_token_stream()) +} + + +pub fn product(body: TokenStream) -> syn::Result { + let product_expr: ProductExpr = parse2(body)?; + + let evaluated = product_expr.eval()?; + + Ok(evaluated.to_token_stream()) +} diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index d85df306..69d0ea2c 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -797,7 +797,16 @@ pub fn Symbol(body: TokenStream) -> TokenStream { #[proc_macro] #[allow(non_snake_case)] pub fn Product(body: TokenStream) -> TokenStream { - cgp_macro_lib::make_product_type(body.into()).into() + cgp_macro_lib::Product(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn product(body: TokenStream) -> TokenStream { + cgp_macro_lib::product(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() } /** @@ -843,11 +852,6 @@ pub fn Path(body: TokenStream) -> TokenStream { .into() } -#[proc_macro] -pub fn product(body: TokenStream) -> TokenStream { - cgp_macro_lib::make_product_expr(body.into()).into() -} - #[proc_macro_derive(HasField)] pub fn derive_fields(item: TokenStream) -> TokenStream { cgp_macro_lib::derive_has_field(item.into()) From 2ac945fd2174fb3821ae343a331ef8591851c447 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 16:54:22 +0200 Subject: [PATCH 02/29] Implement SumType --- crates/macros/cgp-macro-core/src/exports.rs | 2 ++ crates/macros/cgp-macro-core/src/types/mod.rs | 3 +- .../cgp-macro-core/src/types/product/mod.rs | 2 +- .../src/types/product/product_expr.rs | 5 ++- .../src/types/product/product_type.rs | 5 ++- crates/macros/cgp-macro-core/src/types/sum.rs | 34 +++++++++++++++++++ .../cgp-macro-lib/src/entrypoints/mod.rs | 4 ++- .../cgp-macro-lib/src/entrypoints/path.rs | 3 +- .../cgp-macro-lib/src/entrypoints/product.rs | 1 - .../cgp-macro-lib/src/entrypoints/sum.rs | 13 +++++++ crates/macros/cgp-macro/src/lib.rs | 6 ++-- 11 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/sum.rs create mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/sum.rs diff --git a/crates/macros/cgp-macro-core/src/exports.rs b/crates/macros/cgp-macro-core/src/exports.rs index 1bd2ae8e..7e625a52 100644 --- a/crates/macros/cgp-macro-core/src/exports.rs +++ b/crates/macros/cgp-macro-core/src/exports.rs @@ -3,6 +3,8 @@ use crate::export_constructs; export_constructs! { Nil, Cons, + Void, + Either, Chars, Symbol, Index, diff --git a/crates/macros/cgp-macro-core/src/types/mod.rs b/crates/macros/cgp-macro-core/src/types/mod.rs index 08edf9dc..5b6dbcad 100644 --- a/crates/macros/cgp-macro-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/mod.rs @@ -19,5 +19,6 @@ pub mod keyword; pub mod keywords; pub mod namespace; pub mod path; -pub mod provider_impl; pub mod product; +pub mod provider_impl; +pub mod sum; diff --git a/crates/macros/cgp-macro-core/src/types/product/mod.rs b/crates/macros/cgp-macro-core/src/types/product/mod.rs index 425c0670..b19cd7d0 100644 --- a/crates/macros/cgp-macro-core/src/types/product/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/product/mod.rs @@ -1,5 +1,5 @@ -mod product_type; mod product_expr; +mod product_type; pub use product_expr::*; pub use product_type::*; diff --git a/crates/macros/cgp-macro-core/src/types/product/product_expr.rs b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs index 48082cf8..a9a96c42 100644 --- a/crates/macros/cgp-macro-core/src/types/product/product_expr.rs +++ b/crates/macros/cgp-macro-core/src/types/product/product_expr.rs @@ -1,15 +1,14 @@ +use quote::quote; use syn::Type; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::token::Comma; -use quote::quote; use crate::exports::{Cons, Nil}; use crate::functions::parse_internal; - pub struct ProductExpr { - pub types: Punctuated + pub types: Punctuated, } impl ProductExpr { diff --git a/crates/macros/cgp-macro-core/src/types/product/product_type.rs b/crates/macros/cgp-macro-core/src/types/product/product_type.rs index 70ad6ed3..95dea299 100644 --- a/crates/macros/cgp-macro-core/src/types/product/product_type.rs +++ b/crates/macros/cgp-macro-core/src/types/product/product_type.rs @@ -1,15 +1,14 @@ +use quote::quote; use syn::Type; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::token::Comma; -use quote::quote; use crate::exports::{Cons, Nil}; use crate::functions::parse_internal; - pub struct ProductType { - pub types: Punctuated + pub types: Punctuated, } impl ProductType { diff --git a/crates/macros/cgp-macro-core/src/types/sum.rs b/crates/macros/cgp-macro-core/src/types/sum.rs new file mode 100644 index 00000000..b13e8432 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/sum.rs @@ -0,0 +1,34 @@ +use quote::quote; +use syn::Type; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::token::Comma; + +use crate::exports::{Either, Void}; +use crate::functions::parse_internal; + +pub struct SumType { + pub types: Punctuated, +} + +impl SumType { + pub fn eval(&self) -> syn::Result { + let mut out = quote!(#Void); + + for ty in self.types.iter().rev() { + out = quote! { + #Either< #ty, #out > + }; + } + + parse_internal(out) + } +} + +impl Parse for SumType { + fn parse(input: ParseStream) -> syn::Result { + let types = Punctuated::parse_terminated(input)?; + + Ok(Self { types }) + } +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs index 213884cd..df052dd7 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs @@ -20,8 +20,8 @@ mod derive_from_variant; mod derive_has_fields; mod path; mod product; +mod sum; -pub use product::*; pub use blanket_trait::*; pub use cgp_auto_getter::*; pub use cgp_component::*; @@ -43,3 +43,5 @@ pub use derive_extract_field::*; pub use derive_from_variant::*; pub use derive_has_fields::*; pub use path::*; +pub use product::*; +pub use sum::*; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/path.rs b/crates/macros/cgp-macro-lib/src/entrypoints/path.rs index c69a3272..b040e5b6 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/path.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/path.rs @@ -3,7 +3,8 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; -pub fn path(body: TokenStream) -> syn::Result { +#[allow(non_snake_case)] +pub fn Path(body: TokenStream) -> syn::Result { let unipath: UniPath = parse2(body)?; Ok(unipath.to_token_stream()) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/product.rs b/crates/macros/cgp-macro-lib/src/entrypoints/product.rs index af6a06e4..54a2ba83 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/product.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/product.rs @@ -12,7 +12,6 @@ pub fn Product(body: TokenStream) -> syn::Result { Ok(evaluated.to_token_stream()) } - pub fn product(body: TokenStream) -> syn::Result { let product_expr: ProductExpr = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/sum.rs b/crates/macros/cgp-macro-lib/src/entrypoints/sum.rs new file mode 100644 index 00000000..b8ca75ec --- /dev/null +++ b/crates/macros/cgp-macro-lib/src/entrypoints/sum.rs @@ -0,0 +1,13 @@ +use cgp_macro_core::types::sum::SumType; +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +#[allow(non_snake_case)] +pub fn Sum(body: TokenStream) -> syn::Result { + let sum_type: SumType = parse2(body)?; + + let evaluated = sum_type.eval()?; + + Ok(evaluated.to_token_stream()) +} diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index 69d0ea2c..2845de70 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -841,13 +841,15 @@ pub fn product(body: TokenStream) -> TokenStream { #[proc_macro] #[allow(non_snake_case)] pub fn Sum(body: TokenStream) -> TokenStream { - cgp_macro_lib::make_sum_type(body.into()).into() + cgp_macro_lib::Sum(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() } #[proc_macro] #[allow(non_snake_case)] pub fn Path(body: TokenStream) -> TokenStream { - cgp_macro_lib::path(body.into()) + cgp_macro_lib::Path(body.into()) .unwrap_or_else(syn::Error::into_compile_error) .into() } From e83dd8d2c3941582ea87635b87b3059f88ac0c41 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 16:55:38 +0200 Subject: [PATCH 03/29] Remove old product and sum constructs --- crates/macros/cgp-macro-lib/src/lib.rs | 2 - crates/macros/cgp-macro-lib/src/product.rs | 45 ---------------------- 2 files changed, 47 deletions(-) delete mode 100644 crates/macros/cgp-macro-lib/src/product.rs diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index e709d0fe..31ed0876 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -11,14 +11,12 @@ pub(crate) mod derive_builder; pub(crate) mod derive_extractor; pub(crate) mod derive_has_fields; pub(crate) mod field; -pub(crate) mod product; pub(crate) mod symbol; pub(crate) mod type_component; mod entrypoints; pub use field::derive_has_field; -pub use product::{make_product_expr, make_product_type, make_sum_type}; pub use symbol::make_symbol; pub use crate::entrypoints::*; diff --git a/crates/macros/cgp-macro-lib/src/product.rs b/crates/macros/cgp-macro-lib/src/product.rs deleted file mode 100644 index c771b2f2..00000000 --- a/crates/macros/cgp-macro-lib/src/product.rs +++ /dev/null @@ -1,45 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::parse::{Parse, ParseStream}; -use syn::punctuated::Punctuated; -use syn::token::Comma; -use syn::{Expr, Type}; - -pub struct ParsePunctuated(pub Punctuated); - -impl Parse for ParsePunctuated { - fn parse(input: ParseStream) -> syn::Result { - let types = Punctuated::parse_terminated(input)?; - Ok(ParsePunctuated(types)) - } -} - -pub fn make_product_type(input: TokenStream) -> TokenStream { - let types: ParsePunctuated = syn::parse2(input).unwrap(); - - types.0.iter().rfold(quote! { ε }, |res, item| { - quote! { - π< #item , #res > - } - }) -} - -pub fn make_sum_type(input: TokenStream) -> TokenStream { - let types: ParsePunctuated = syn::parse2(input).unwrap(); - - types.0.iter().rfold(quote! { θ }, |res, item| { - quote! { - σ< #item , #res > - } - }) -} - -pub fn make_product_expr(input: TokenStream) -> TokenStream { - let types: ParsePunctuated = syn::parse2(input).unwrap(); - - types.0.iter().rfold(quote! { ε }, |res, item| { - quote! { - π( #item , #res ) - } - }) -} From 88df1bb83d38dc51c230ed45c364c984b61567f2 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 16:56:32 +0200 Subject: [PATCH 04/29] Remove obsolete preset constructs --- .../src/entrypoints/cgp_preset.rs | 271 ------------------ .../src/entrypoints/re_export_imports.rs | 56 ---- .../src/entrypoints/replace_with.rs | 16 -- 3 files changed, 343 deletions(-) delete mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/cgp_preset.rs delete mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/re_export_imports.rs delete mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/replace_with.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_preset.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_preset.rs deleted file mode 100644 index 089f78e5..00000000 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_preset.rs +++ /dev/null @@ -1,271 +0,0 @@ -use std::collections::HashSet; - -use cgp_macro_core::functions::to_snake_case_str; -use cgp_macro_core::types::empty_struct::EmptyStruct; -use cgp_macro_core::types::generics::ImplGenerics; -use cgp_macro_core::types::ident::IdentWithTypeArgs; -use proc_macro2::{Span, TokenStream}; -use quote::{ToTokens, TokenStreamExt, quote}; -use syn::punctuated::Punctuated; -use syn::token::{At, Comma}; -use syn::{GenericParam, Ident, ItemTrait, TypeParamBound, parse_quote, parse2}; - -use crate::delegate_components::impl_delegate_components; -use crate::parse::{DefinePreset, DelegateEntry}; -use crate::preset::{define_substitution_macro, impl_components_is_preset}; - -pub fn define_preset(body: TokenStream) -> syn::Result { - let ast: DefinePreset = syn::parse2(body)?; - - let delegate_entries: Punctuated, Comma> = ast - .delegate_entries - .iter() - .map(|entry| entry.entry.clone()) - .collect(); - - let mut parent_presets = ast.parent_presets.clone(); - - let mut remaining_parents = parent_presets - .iter_mut() - .filter(|parent| parent.has_expanded.is_none()); - - let m_parent = if let Some(parent_preset) = remaining_parents.next() { - parent_preset.has_expanded = Some(At(Span::call_site())); - Some(parent_preset.parent_type.clone()) - } else { - None - }; - - if let Some(parent) = m_parent { - let parent_ident = &parent.ident; - let parent_generics = &parent.type_args; - - let parent_components_ident = Ident::new( - &format!("__{parent_ident}Components__"), - parent_ident.span(), - ); - - let wrapper_attribute = match ast.provider_wrapper { - Some(wrapper) => quote! { - #[wrap_provider( #wrapper )] - }, - None => TokenStream::new(), - }; - - let preset_type_spec = &ast.preset; - - let mut overrides: Punctuated<&Ident, Comma> = Punctuated::default(); - - for entry in ast.delegate_entries.iter() { - if entry.is_override.is_some() { - for component in entry.entry.keys.iter() { - overrides.push(&component.ty.ident); - } - } - } - - let filter = if !overrides.is_empty() { - quote! { - [ #overrides ], - } - } else { - TokenStream::new() - }; - - let preset_entries = &ast.delegate_entries; - - let output = quote! { - use #parent_ident ::components::*; - - #parent_ident :: with_components! { - #filter - | #parent_components_ident | { - cgp_preset! { - #wrapper_attribute - #preset_type_spec: #parent_presets { - #parent_components_ident -> #parent_ident :: Components #parent_generics, - #preset_entries - } - } - } - } - }; - - return Ok(output); - } - - let provider_struct_name = Ident::new("Components", Span::call_site()); - - let preset_module_name = &ast.preset.name; - - let preset_generic_args = &ast.preset.generics; - - let preset_generics: ImplGenerics = syn::parse2(quote!( #preset_generic_args ))?; - - let provider_type = { - let type_generics = preset_generics.split_for_impl().1; - parse2(quote! { #provider_struct_name #type_generics })? - }; - - let preset_trait_name = Ident::new("IsPreset", Span::call_site()); - - let preset_trait: ItemTrait = parse_quote! { - #[doc(hidden)] - pub trait #preset_trait_name {} - }; - - let impl_delegate_items = { - let namespaces_preset_type = parse2(quote! { - #preset_module_name :: #provider_type - })?; - - let items = - impl_delegate_components(&namespaces_preset_type, &preset_generics, &delegate_entries)?; - - let mut stream = TokenStream::new(); - stream.append_all(items); - - stream - }; - - let impl_is_preset_items = impl_components_is_preset( - &preset_trait_name, - &provider_type, - &preset_generics, - &delegate_entries, - ); - - let provider_struct = EmptyStruct { - ident: provider_struct_name.clone(), - generics: preset_generics.generics.clone(), - }; - - let export_provider = match ast.provider_wrapper { - Some(wrapper) => { - let (impl_generics, type_generics, _) = preset_generics.generics.split_for_impl(); - - quote! { - pub type Provider #impl_generics = #wrapper < #provider_struct_name #type_generics >; - } - } - None => { - quote! { - pub use #provider_struct_name as Provider; - } - } - }; - - let mut mod_output = quote! { - #provider_struct - - #export_provider - - #preset_trait - }; - - mod_output.append_all(impl_is_preset_items); - - { - let with_components_macro_name = Ident::new( - &format!( - "with_{}", - to_snake_case_str(&preset_module_name.to_string()) - ), - Span::call_site(), - ); - - let all_components: Punctuated<_, Comma> = delegate_entries - .iter() - .flat_map(|entry| entry.keys.clone().into_iter()) - .collect(); - - let with_components_macro = define_substitution_macro( - &with_components_macro_name, - &all_components.to_token_stream(), - ); - - mod_output.extend(with_components_macro); - mod_output.extend(quote! { - pub use #with_components_macro_name as with_components; - }) - } - - let re_exports_mod = { - let mut parent_exports = TokenStream::new(); - - for parent in parent_presets.iter() { - let parent_ident = &parent.parent_type.ident; - parent_exports.append_all(quote! { - #[doc(hidden)] - #[doc(no_inline)] - pub use super:: #parent_ident ::components::*; - }); - } - - quote! { - #[doc(hidden)] - #[allow(unused_imports)] - mod re_exports { - #[doc(hidden)] - #[doc(no_inline)] - pub use super::super::super::re_exports::*; - - #[doc(hidden)] - #[doc(no_inline)] - pub use super::super::*; - - #parent_exports - } - } - }; - - let components_mod = { - let mut components: HashSet = HashSet::default(); - - for entry in delegate_entries.iter() { - for component in entry.keys.iter() { - let component_name = &component.ty.ident; - components.insert(component_name.clone()); - - for param in component.generics.generics.params.iter() { - if let GenericParam::Type(param) = param { - for bound in param.bounds.iter() { - if let TypeParamBound::Trait(bound) = bound - && let Some(segment) = bound.path.segments.first() - { - components.insert(segment.ident.clone()); - } - } - } - } - } - } - - let components_list: Punctuated = Punctuated::from_iter(components); - - quote! { - #[doc(hidden)] - pub mod components { - #[doc(hidden)] - #[doc(no_inline)] - pub use super::re_exports::{ #components_list }; - } - } - }; - - mod_output.append_all(re_exports_mod); - mod_output.append_all(components_mod); - - let output = quote! { - #impl_delegate_items - - #[allow(non_snake_case)] - pub mod #preset_module_name { - use super::*; - - #mod_output - } - }; - - Ok(output) -} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/re_export_imports.rs b/crates/macros/cgp-macro-lib/src/entrypoints/re_export_imports.rs deleted file mode 100644 index f6ede771..00000000 --- a/crates/macros/cgp-macro-lib/src/entrypoints/re_export_imports.rs +++ /dev/null @@ -1,56 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use quote::{TokenStreamExt, quote}; -use syn::token::Pub; -use syn::{Attribute, Ident, Item, ItemMod, ItemUse, Visibility, parse_quote, parse2}; - -pub fn re_export_imports(attrs: TokenStream, body: TokenStream) -> syn::Result { - let export_mod_name: Ident = if !attrs.is_empty() { - parse2(attrs)? - } else { - Ident::new("re_exports", Span::call_site()) - }; - - let mut re_exports: Vec = Vec::new(); - - let item_mod: ItemMod = parse2(body)?; - - let mod_name = &item_mod.ident; - - let doc_hidden: Attribute = parse_quote! { #[doc(hidden)] }; - let doc_no_inline: Attribute = parse_quote! { #[doc(no_inline)] }; - - if let Some(content) = &item_mod.content { - for item in content.1.iter() { - if let Item::Use(use_item) = item { - let mut re_export = use_item.clone(); - - re_export.vis = Visibility::Public(Pub(Span::call_site())); - re_export.attrs.push(doc_hidden.clone()); - re_export.attrs.push(doc_no_inline.clone()); - - re_exports.push(re_export); - } - } - } - - let mut mod_body = TokenStream::new(); - mod_body.append_all(re_exports); - - let export_mod: ItemMod = parse2(quote! { - #[doc(hidden)] - #[allow(unused_imports)] - mod #export_mod_name { - #mod_body - } - })?; - - let out = quote! { - #item_mod - - #export_mod - - pub use #mod_name ::*; - }; - - Ok(out) -} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/replace_with.rs b/crates/macros/cgp-macro-lib/src/entrypoints/replace_with.rs deleted file mode 100644 index bf8d42b9..00000000 --- a/crates/macros/cgp-macro-lib/src/entrypoints/replace_with.rs +++ /dev/null @@ -1,16 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::punctuated::Punctuated; -use syn::token::Comma; - -use crate::for_each_replace::{ReplaceSpecs, replace_stream}; - -pub fn replace_with(tokens: TokenStream) -> syn::Result { - let specs: ReplaceSpecs = syn::parse2(tokens)?; - - let items: Punctuated = specs.replacements.into_iter().collect(); - - let tokens = quote! { [ #items ] }; - - Ok(replace_stream(&specs.target_ident, &tokens, specs.body)) -} From f1feea7c7cc4b11c6db8852dfde40ad057790eb8 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 17:11:12 +0200 Subject: [PATCH 05/29] Migrate Symbol --- .../types/cgp_getter/to_use_fields_impl.rs | 2 +- .../src/types/field/field_name.rs | 2 +- .../cgp-macro-core/src/types/field/symbol.rs | 27 ++++++++++++++----- .../src/types/path/path_element.rs | 2 +- .../cgp-macro-lib/src/entrypoints/mod.rs | 2 ++ .../cgp-macro-lib/src/entrypoints/symbol.rs | 11 ++++++++ crates/macros/cgp-macro/src/lib.rs | 2 +- 7 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs index 6c5447f5..18fa6484 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs @@ -53,7 +53,7 @@ impl ItemCgpGetter { ReceiverMode::Type(ty) => ty.clone(), }; - let field_name = Symbol::new(field.field_name.clone()); + let field_name = Symbol::from_ident(field.field_name.clone()); let tag_type: Type = parse_internal!(#field_name); let method = derive_getter_method( diff --git a/crates/macros/cgp-macro-core/src/types/field/field_name.rs b/crates/macros/cgp-macro-core/src/types/field/field_name.rs index 5e8ea365..253bc360 100644 --- a/crates/macros/cgp-macro-core/src/types/field/field_name.rs +++ b/crates/macros/cgp-macro-core/src/types/field/field_name.rs @@ -11,7 +11,7 @@ pub enum FieldName { impl From for FieldName { fn from(value: Ident) -> Self { - Self::Ident(Symbol::new(value)) + Self::Ident(Symbol::from_ident(value)) } } diff --git a/crates/macros/cgp-macro-core/src/types/field/symbol.rs b/crates/macros/cgp-macro-core/src/types/field/symbol.rs index e7081e47..667d7365 100644 --- a/crates/macros/cgp-macro-core/src/types/field/symbol.rs +++ b/crates/macros/cgp-macro-core/src/types/field/symbol.rs @@ -1,17 +1,32 @@ -use proc_macro2::{Literal, TokenStream}; +use proc_macro2::{Literal, Span, TokenStream}; use quote::{ToTokens, quote_spanned}; -use syn::{Ident, Type, parse_quote}; +use syn::parse::{Parse, ParseStream}; +use syn::{Ident, LitStr, Type, parse_quote}; use crate::traits::ToType; #[derive(Debug, Clone)] pub struct Symbol { - pub ident: Ident, + pub ident: String, + pub span: Span, } impl Symbol { - pub fn new(ident: Ident) -> Self { - Self { ident } + pub fn from_ident(ident: Ident) -> Self { + Self { + ident: ident.to_string(), + span: ident.span(), + } + } +} + +impl Parse for Symbol { + fn parse(input: ParseStream) -> syn::Result { + let literal: LitStr = input.parse()?; + Ok(Self { + ident: literal.value(), + span: literal.span(), + }) } } @@ -19,7 +34,7 @@ impl ToTokens for Symbol { fn to_tokens(&self, tokens: &mut TokenStream) { use crate::exports::{Chars, Nil, Symbol}; - let span = self.ident.span(); + let span = self.span; let str_value = self.ident.to_string(); let chars = str_value.chars().rev().fold( diff --git a/crates/macros/cgp-macro-core/src/types/path/path_element.rs b/crates/macros/cgp-macro-core/src/types/path/path_element.rs index 285ff91d..ea1cdc73 100644 --- a/crates/macros/cgp-macro-core/src/types/path/path_element.rs +++ b/crates/macros/cgp-macro-core/src/types/path/path_element.rs @@ -24,7 +24,7 @@ impl Parse for PathElement { && path_char.is_ascii_lowercase() && !is_primitive_type(&path_str) { - Self::Symbol(Symbol::new(path_ident)) + Self::Symbol(Symbol::from_ident(path_ident)) } else { Self::Type(ty) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs index df052dd7..45606933 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs @@ -21,6 +21,7 @@ mod derive_has_fields; mod path; mod product; mod sum; +mod symbol; pub use blanket_trait::*; pub use cgp_auto_getter::*; @@ -45,3 +46,4 @@ pub use derive_has_fields::*; pub use path::*; pub use product::*; pub use sum::*; +pub use symbol::*; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs b/crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs new file mode 100644 index 00000000..ef86bf9c --- /dev/null +++ b/crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs @@ -0,0 +1,11 @@ +use cgp_macro_core::types::field::Symbol; +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +#[allow(non_snake_case)] +pub fn Symbol(body: TokenStream) -> syn::Result { + let symbol: Symbol = parse2(body)?; + + Ok(symbol.to_token_stream()) +} diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index 2845de70..31c4e62c 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -761,7 +761,7 @@ pub fn blanket_trait(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro] #[allow(non_snake_case)] pub fn Symbol(body: TokenStream) -> TokenStream { - cgp_macro_lib::make_symbol(body.into()) + cgp_macro_lib::Symbol(body.into()) .unwrap_or_else(syn::Error::into_compile_error) .into() } From ffbc0093e13626fd85f28c952eeb15dbb3ffcf00 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 17:17:14 +0200 Subject: [PATCH 06/29] Remove old symbol constructs --- .../src/derive_builder/has_field_impls.rs | 2 +- .../src/derive_builder/update_field_impls.rs | 2 +- .../cgp-macro-lib/src/derive_builder/utils.rs | 20 ++++++-------- .../derive_extractor/extract_field_impls.rs | 4 +-- .../src/derive_has_fields/product.rs | 5 ++-- .../src/derive_has_fields/sum.rs | 4 +-- .../src/entrypoints/derive_from_variant.rs | 4 +-- crates/macros/cgp-macro-lib/src/field.rs | 6 ++--- crates/macros/cgp-macro-lib/src/lib.rs | 2 -- crates/macros/cgp-macro-lib/src/symbol.rs | 27 ------------------- 10 files changed, 20 insertions(+), 56 deletions(-) delete mode 100644 crates/macros/cgp-macro-lib/src/symbol.rs diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs b/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs index f35cc11b..c186cea0 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs +++ b/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs @@ -15,7 +15,7 @@ pub fn derive_has_field_impls( for (current_index, current_field) in context_struct.fields.iter().enumerate() { let field_member = field_to_member(current_index, current_field); - let tag_type = field_to_tag(current_index, current_field)?; + let tag_type = field_to_tag(current_index, current_field); let value_type = ¤t_field.ty; let mut generics = context_struct.generics.clone(); diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs b/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs index 91fb0a3e..58344779 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs +++ b/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs @@ -65,7 +65,7 @@ pub fn derive_update_field_impls( #builder_ident < #output_generic_args > })?; - let tag_type = field_to_tag(current_index, current_field)?; + let tag_type = field_to_tag(current_index, current_field); let (impl_generics, _, where_clause) = generics.split_for_impl(); diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs b/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs index 07f86f90..200b3135 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs +++ b/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs @@ -1,13 +1,9 @@ +use cgp_macro_core::types::field::{FieldName, Index, Symbol}; use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, quote}; use syn::spanned::Spanned; use syn::token::Colon; -use syn::{ - AngleBracketedGenericArguments, Field, FieldValue, Generics, Ident, LitInt, Member, Type, - parse2, -}; - -use crate::symbol::symbol_from_string; +use syn::{AngleBracketedGenericArguments, Field, FieldValue, Generics, Ident, Member, parse2}; pub fn to_generic_args(generics: &Generics) -> syn::Result { if generics.params.is_empty() { @@ -24,13 +20,13 @@ pub fn field_to_member(index: usize, field: &Field) -> Member { } } -pub fn field_to_tag(index: usize, field: &Field) -> syn::Result { +pub fn field_to_tag(index: usize, field: &Field) -> FieldName { match &field.ident { - Some(ident) => symbol_from_string(&ident.to_string()), - None => { - let index = LitInt::new(&format!("{index}"), field.span()); - parse2(quote! { δ< #index > }) - } + Some(ident) => FieldName::Ident(Symbol::from_ident(ident.clone())), + None => FieldName::Index(Index { + index, + span: field.span(), + }), } } diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs index ccb941aa..a22de9c8 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs @@ -1,9 +1,9 @@ +use cgp_macro_core::types::field::Symbol; use quote::quote; use syn::{Arm, GenericArgument, Ident, ItemEnum, ItemImpl, Type, parse2}; use crate::derive_builder::{index_to_generic_ident, to_generic_args}; use crate::derive_extractor::get_variant_type; -use crate::symbol::symbol_from_string; pub fn derive_extract_field_impls( context_enum: &ItemEnum, @@ -83,7 +83,7 @@ pub fn derive_extract_field_impls( } }; - let tag_type = symbol_from_string(¤t_variant.ident.to_string())?; + let tag_type = Symbol::from_ident(current_variant.ident.clone()); let source_type: Type = parse2(quote! { #extractor_ident < #source_generic_args > diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs b/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs index 7ca37440..2d08e105 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs +++ b/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs @@ -1,10 +1,9 @@ +use cgp_macro_core::types::field::Symbol; use proc_macro2::TokenStream; use quote::quote; use syn::spanned::Spanned; use syn::{Error, Fields, LitInt, Type, parse2}; -use crate::symbol::symbol_from_string; - pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> syn::Result { let mut fields_type = quote! { ε }; @@ -15,7 +14,7 @@ pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> Error::new_spanned(field, "expect struct field to contain name identifier") })?; - let field_tag = symbol_from_string(&field_name.to_string())?; + let field_tag = Symbol::from_ident(field_name.clone()); let field_type = &field.ty; fields_type = parse2(quote! { diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs b/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs index 8f9ce680..7c358380 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs +++ b/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs @@ -1,3 +1,4 @@ +use cgp_macro_core::types::field::Symbol; use proc_macro2::TokenStream; use quote::quote; use syn::punctuated::Punctuated; @@ -5,7 +6,6 @@ use syn::token::Comma; use syn::{Type, Variant, parse2}; use crate::derive_has_fields::product::item_fields_to_product_type; -use crate::symbol::symbol_from_string; pub fn variants_to_sum_type( variants: &Punctuated, @@ -15,7 +15,7 @@ pub fn variants_to_sum_type( for variant in variants.iter().rev() { let variant_ident = &variant.ident; - let variant_symbol = symbol_from_string(&variant_ident.to_string())?; + let variant_symbol = Symbol::from_ident(variant_ident.clone()); let variant_fields = item_fields_to_product_type(&variant.fields, reference)?; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs index ffcf6bce..56a575b0 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs @@ -1,9 +1,9 @@ +use cgp_macro_core::types::field::Symbol; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; use crate::derive_extractor::get_variant_type; -use crate::symbol::symbol_from_string; pub fn derive_from_variant(body: TokenStream) -> syn::Result { let item_enum: ItemEnum = parse2(body)?; @@ -20,7 +20,7 @@ pub fn derive_from_variant_from_enum(item_enum: &ItemEnum) -> syn::Result syn::Result> { let struct_ident = &item_struct.ident; @@ -20,7 +18,7 @@ pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Resu for field in fields.named.iter() { let field_ident = field.ident.as_ref().unwrap(); - let field_symbol = symbol_from_string(&field_ident.to_string())?; + let field_symbol = Symbol::from_ident(field_ident.clone()); let field_type = &field.ty; diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index 31ed0876..faa53862 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -11,12 +11,10 @@ pub(crate) mod derive_builder; pub(crate) mod derive_extractor; pub(crate) mod derive_has_fields; pub(crate) mod field; -pub(crate) mod symbol; pub(crate) mod type_component; mod entrypoints; pub use field::derive_has_field; -pub use symbol::make_symbol; pub use crate::entrypoints::*; diff --git a/crates/macros/cgp-macro-lib/src/symbol.rs b/crates/macros/cgp-macro-lib/src/symbol.rs deleted file mode 100644 index c7b9ff51..00000000 --- a/crates/macros/cgp-macro-lib/src/symbol.rs +++ /dev/null @@ -1,27 +0,0 @@ -use proc_macro2::{Literal, Span, TokenStream}; -use quote::quote_spanned; -use syn::{LitStr, Type, parse2}; - -pub fn symbol_from_string(value: &str) -> syn::Result { - parse2(symbol_from_string_spanned(Span::call_site(), value)) -} - -pub fn symbol_from_string_spanned(span: Span, value: &str) -> TokenStream { - let mut chars = quote_spanned! { span => ε }; - - for c in value.chars().rev() { - chars = quote_spanned! { span => ζ< #c, #chars > }; - } - - let len = Literal::usize_unsuffixed(value.len()); - - quote_spanned! { span => ψ< #len, #chars > } -} - -pub fn make_symbol(input: TokenStream) -> syn::Result { - let literal: LitStr = syn::parse2(input)?; - - let symbol = symbol_from_string_spanned(literal.span(), &literal.value()); - - Ok(symbol) -} From 54840bda8e9837ebb46dd9fb44e36ef1e72a3aca Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 20:20:10 +0200 Subject: [PATCH 07/29] Draft implement ItemCgpType --- .../cgp-macro-core/src/types/cgp_type/item.rs | 111 ++++++++++++++++++ .../cgp-macro-core/src/types/cgp_type/mod.rs | 3 + crates/macros/cgp-macro-core/src/types/mod.rs | 1 + 3 files changed, 115 insertions(+) create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_type/item.rs create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_type/mod.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs new file mode 100644 index 00000000..6c5aaf53 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -0,0 +1,111 @@ +use syn::spanned::Spanned; +use syn::{Error, ItemImpl, TraitItem, TraitItemType}; + +use crate::parse_internal; +use crate::types::cgp_component::EvaluatedCgpComponent; +use crate::types::provider_impl::derive_is_provider_for; +use crate::visitors::get_bounds_and_replace_self_assoc_type; + +pub struct ItemCgpType { + pub item_component: EvaluatedCgpComponent, +} + +impl ItemCgpType { + pub fn to_trait_item_type(&self) -> syn::Result { + let consumer_trait = &self.item_component.consumer_trait; + + if consumer_trait.items.len() != 1 { + return Err(Error::new( + consumer_trait.span(), + "type trait should contain exactly one associated type item", + )); + } + + match consumer_trait.items.first() { + Some(TraitItem::Type(item_type)) => { + if !item_type.generics.params.is_empty() + || item_type.generics.where_clause.is_some() + { + return Err(Error::new( + consumer_trait.span(), + "generic associated type and where clause are not supported", + )); + } + + Ok(item_type.clone()) + } + _ => Err(Error::new( + consumer_trait.span(), + "type trait should contain exactly one associated type item", + )), + } + } + + pub fn to_item_impls(&self) -> syn::Result> { + let context_name = &self.item_component.args.context_ident; + let component_name = self.item_component.args.component_name.to_type(); + + let provider_trait = &self.item_component.provider_trait; + let provider_trait_name = &provider_trait.ident; + + let item_type = self.to_trait_item_type()?; + + let type_name = &item_type.ident; + + let type_bounds = get_bounds_and_replace_self_assoc_type(&item_type); + + let mut generics = provider_trait.generics.clone(); + generics.params.insert(0, parse_internal!(#type_name)); + generics + .make_where_clause() + .predicates + .push(parse_internal! { + #type_name: #type_bounds, + }); + + let (_, type_generics, _) = provider_trait.generics.split_for_impl(); + let (impl_generics, _, where_clause) = generics.split_for_impl(); + + let use_type_impl: ItemImpl = parse_internal! { + impl #impl_generics + #provider_trait_name #type_generics + for UseType< #type_name > + #where_clause + { + type #type_name = #type_name; + } + }; + + let use_type_is_provider_impl = derive_is_provider_for(&component_name, &use_type_impl)?; + + generics.params.insert(0, parse_internal!(__Provider__)); + generics + .make_where_clause() + .predicates + .push(parse_internal! { + __Provider__: TypeProvider< #context_name, #component_name, Type = #type_name > + }); + + let (impl_generics, _, where_clause) = generics.split_for_impl(); + + let with_provider_impl: ItemImpl = parse_internal! { + impl #impl_generics + #provider_trait_name #type_generics + for WithProvider< __Provider__ > + #where_clause + { + type #type_name = #type_name; + } + }; + + let with_provider_is_provider_impl = + derive_is_provider_for(&component_name, &with_provider_impl)?; + + Ok(vec![ + use_type_impl, + use_type_is_provider_impl, + with_provider_impl, + with_provider_is_provider_impl, + ]) + } +} diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/mod.rs new file mode 100644 index 00000000..95e0a691 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/mod.rs @@ -0,0 +1,3 @@ +mod item; + +pub use item::*; diff --git a/crates/macros/cgp-macro-core/src/types/mod.rs b/crates/macros/cgp-macro-core/src/types/mod.rs index 5b6dbcad..473ae9f3 100644 --- a/crates/macros/cgp-macro-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/mod.rs @@ -6,6 +6,7 @@ pub mod cgp_fn; pub mod cgp_getter; pub mod cgp_impl; pub mod cgp_provider; +pub mod cgp_type; pub mod check_components; pub mod delegate_and_check_components; pub mod delegate_component; From a7b62870098c8241d5cc2fd98b671679efe4a050 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 20:26:19 +0200 Subject: [PATCH 08/29] Implement ItemCgpType::to_items --- .../cgp-macro-core/src/types/cgp_type/item.rs | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs index 6c5aaf53..4c4fc224 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -1,9 +1,9 @@ use syn::spanned::Spanned; -use syn::{Error, ItemImpl, TraitItem, TraitItemType}; +use syn::{Error, Item, ItemImpl, TraitItem, TraitItemType}; use crate::parse_internal; use crate::types::cgp_component::EvaluatedCgpComponent; -use crate::types::provider_impl::derive_is_provider_for; +use crate::types::provider_impl::{ItemProviderImpl, ItemProviderImpls}; use crate::visitors::get_bounds_and_replace_self_assoc_type; pub struct ItemCgpType { @@ -11,6 +11,16 @@ pub struct ItemCgpType { } impl ItemCgpType { + pub fn to_items(&self) -> syn::Result> { + let mut items = self.item_component.to_items()?; + + let item_impls = self.to_item_provider_impls()?.to_item_impls()?; + + items.extend(item_impls.into_iter().map(Item::from)); + + Ok(items) + } + pub fn to_trait_item_type(&self) -> syn::Result { let consumer_trait = &self.item_component.consumer_trait; @@ -41,9 +51,9 @@ impl ItemCgpType { } } - pub fn to_item_impls(&self) -> syn::Result> { + pub fn to_item_provider_impls(&self) -> syn::Result { let context_name = &self.item_component.args.context_ident; - let component_name = self.item_component.args.component_name.to_type(); + let component_type = self.item_component.args.component_name.to_type(); let provider_trait = &self.item_component.provider_trait; let provider_trait_name = &provider_trait.ident; @@ -76,14 +86,17 @@ impl ItemCgpType { } }; - let use_type_is_provider_impl = derive_is_provider_for(&component_name, &use_type_impl)?; + let use_type_provider = ItemProviderImpl { + component_type: component_type.clone(), + item_impl: use_type_impl, + }; generics.params.insert(0, parse_internal!(__Provider__)); generics .make_where_clause() .predicates .push(parse_internal! { - __Provider__: TypeProvider< #context_name, #component_name, Type = #type_name > + __Provider__: TypeProvider< #context_name, #component_type, Type = #type_name > }); let (impl_generics, _, where_clause) = generics.split_for_impl(); @@ -98,14 +111,13 @@ impl ItemCgpType { } }; - let with_provider_is_provider_impl = - derive_is_provider_for(&component_name, &with_provider_impl)?; + let with_provider_provider = ItemProviderImpl { + component_type: component_type.clone(), + item_impl: with_provider_impl, + }; - Ok(vec![ - use_type_impl, - use_type_is_provider_impl, - with_provider_impl, - with_provider_is_provider_impl, - ]) + Ok(ItemProviderImpls { + items: vec![use_type_provider, with_provider_provider], + }) } } From 683ec1aa5a1193742cb567c04cd37f0446f7da34 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 20:32:13 +0200 Subject: [PATCH 09/29] Migate cgp_type impl --- .../cgp-macro-core/src/types/cgp_type/item.rs | 58 +++++------ .../cgp-macro-lib/src/entrypoints/cgp_type.rs | 18 ++-- crates/macros/cgp-macro-lib/src/lib.rs | 1 - .../src/type_component/derive.rs | 95 ------------------- .../cgp-macro-lib/src/type_component/mod.rs | 3 - 5 files changed, 36 insertions(+), 139 deletions(-) delete mode 100644 crates/macros/cgp-macro-lib/src/type_component/derive.rs delete mode 100644 crates/macros/cgp-macro-lib/src/type_component/mod.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs index 4c4fc224..55ac1991 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -1,5 +1,5 @@ use syn::spanned::Spanned; -use syn::{Error, Item, ItemImpl, TraitItem, TraitItemType}; +use syn::{Error, Item, ItemImpl, ItemTrait, TraitItem, TraitItemType}; use crate::parse_internal; use crate::types::cgp_component::EvaluatedCgpComponent; @@ -22,33 +22,7 @@ impl ItemCgpType { } pub fn to_trait_item_type(&self) -> syn::Result { - let consumer_trait = &self.item_component.consumer_trait; - - if consumer_trait.items.len() != 1 { - return Err(Error::new( - consumer_trait.span(), - "type trait should contain exactly one associated type item", - )); - } - - match consumer_trait.items.first() { - Some(TraitItem::Type(item_type)) => { - if !item_type.generics.params.is_empty() - || item_type.generics.where_clause.is_some() - { - return Err(Error::new( - consumer_trait.span(), - "generic associated type and where clause are not supported", - )); - } - - Ok(item_type.clone()) - } - _ => Err(Error::new( - consumer_trait.span(), - "type trait should contain exactly one associated type item", - )), - } + extract_item_type_from_trait(&self.item_component.consumer_trait) } pub fn to_item_provider_impls(&self) -> syn::Result { @@ -70,7 +44,7 @@ impl ItemCgpType { .make_where_clause() .predicates .push(parse_internal! { - #type_name: #type_bounds, + #type_name: #type_bounds }); let (_, type_generics, _) = provider_trait.generics.split_for_impl(); @@ -121,3 +95,29 @@ impl ItemCgpType { }) } } + +pub fn extract_item_type_from_trait(consumer_trait: &ItemTrait) -> syn::Result { + if consumer_trait.items.len() != 1 { + return Err(Error::new( + consumer_trait.span(), + "type trait should contain exactly one associated type item", + )); + } + + match consumer_trait.items.first() { + Some(TraitItem::Type(item_type)) => { + if !item_type.generics.params.is_empty() || item_type.generics.where_clause.is_some() { + return Err(Error::new( + consumer_trait.span(), + "generic associated type and where clause are not supported", + )); + } + + Ok(item_type.clone()) + } + _ => Err(Error::new( + consumer_trait.span(), + "type trait should contain exactly one associated type item", + )), + } +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs index fa92f47a..d36e8a82 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs @@ -1,12 +1,11 @@ use alloc::format; use cgp_macro_core::types::cgp_component::{CgpComponentRawArgs, ItemCgpComponent}; +use cgp_macro_core::types::cgp_type::{ItemCgpType, extract_item_type_from_trait}; use proc_macro2::TokenStream; use quote::quote; use syn::{Ident, ItemTrait, parse2}; -use crate::type_component::{derive_type_providers, extract_item_type_from_trait}; - pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> syn::Result { let mut raw_args: CgpComponentRawArgs = parse2(attrs.clone())?; @@ -28,16 +27,13 @@ pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> syn::Result syn::Result<&TraitItemType> { - if consumer_trait.items.len() != 1 { - return Err(Error::new( - consumer_trait.span(), - "type trait should contain exactly one associated type item", - )); - } - - match consumer_trait.items.first() { - Some(TraitItem::Type(item_type)) => { - if !item_type.generics.params.is_empty() || item_type.generics.where_clause.is_some() { - return Err(Error::new( - consumer_trait.span(), - "generic associated type and where clause are not supported", - )); - } - - Ok(item_type) - } - _ => Err(Error::new( - consumer_trait.span(), - "type trait should contain exactly one associated type item", - )), - } -} - -pub fn derive_type_providers( - spec: &CgpComponentArgs, - provider_trait: &ItemTrait, - item_type: &TraitItemType, -) -> syn::Result> { - let context_name = &spec.context_ident; - - let component_name: Type = { parse2(spec.component_name.to_token_stream())? }; - - let provider_trait_name = &provider_trait.ident; - - let (impl_generics, type_generics, where_clause) = provider_trait.generics.split_for_impl(); - - let impl_generics_params = parse2::(impl_generics.to_token_stream())?.params; - - let predicates = where_clause - .map(|c| c.predicates.clone()) - .unwrap_or_default(); - - let type_name = &item_type.ident; - - let type_bounds = get_bounds_and_replace_self_assoc_type(item_type); - - let use_type_impl: ItemImpl = parse2(quote! { - impl< #type_name, #impl_generics_params > - #provider_trait_name #type_generics - for UseType< #type_name > - where - #type_name: #type_bounds, - #predicates - { - type #type_name = #type_name; - } - })?; - - let use_type_is_provider_impl = derive_is_provider_for(&component_name, &use_type_impl)?; - - let with_provider_impl: ItemImpl = parse2(quote! { - impl< __Provider__, #type_name, #impl_generics_params > - #provider_trait_name #type_generics - for WithProvider< __Provider__ > - where - __Provider__: TypeProvider< #context_name, #component_name, Type = #type_name >, - #type_name: #type_bounds, - #predicates - { - type #type_name = #type_name; - } - })?; - - let with_provider_is_provider_impl = - derive_is_provider_for(&component_name, &with_provider_impl)?; - - Ok(vec![ - use_type_impl, - use_type_is_provider_impl, - with_provider_impl, - with_provider_is_provider_impl, - ]) -} diff --git a/crates/macros/cgp-macro-lib/src/type_component/mod.rs b/crates/macros/cgp-macro-lib/src/type_component/mod.rs deleted file mode 100644 index 61eca8a7..00000000 --- a/crates/macros/cgp-macro-lib/src/type_component/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod derive; - -pub use derive::*; From 849b43f4974718002a0996a4374be3577817dd10 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 21:35:47 +0200 Subject: [PATCH 10/29] Implement ItemCgpRecord --- .../cgp-macro-core/src/types/cgp_data/mod.rs | 3 + .../src/types/cgp_data/record.rs | 117 +++++++++++++++++ crates/macros/cgp-macro-core/src/types/mod.rs | 1 + .../cgp-macro-lib/src/entrypoints/cgp_data.rs | 2 +- .../src/entrypoints/cgp_record.rs | 14 ++- .../src/entrypoints/derive_has_field.rs | 16 +++ .../cgp-macro-lib/src/entrypoints/mod.rs | 2 + crates/macros/cgp-macro-lib/src/field.rs | 118 ------------------ crates/macros/cgp-macro-lib/src/lib.rs | 3 - 9 files changed, 148 insertions(+), 128 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/record.rs create mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs delete mode 100644 crates/macros/cgp-macro-lib/src/field.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs new file mode 100644 index 00000000..67d5f59a --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -0,0 +1,3 @@ +mod record; + +pub use record::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs new file mode 100644 index 00000000..869c8c3e --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -0,0 +1,117 @@ +use syn::spanned::Spanned; +use syn::{Fields, ItemImpl, ItemStruct, LitInt, parse_quote}; + +use crate::types::field::{Index, Symbol}; + +pub struct ItemCgpRecord { + pub item_struct: ItemStruct, +} + +impl ItemCgpRecord { + pub fn to_has_field_impls(&self) -> syn::Result> { + let item_struct = &self.item_struct; + + let struct_ident = &item_struct.ident; + + let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl(); + + let mut item_impls = Vec::new(); + + match &item_struct.fields { + Fields::Named(fields) => { + for field in fields.named.iter() { + let field_ident = field.ident.as_ref().unwrap(); + + let field_symbol = Symbol::from_ident(field_ident.clone()); + + let field_type = &field.ty; + + let has_field_impl: ItemImpl = parse_quote! { + impl #impl_generics HasField< #field_symbol > + for #struct_ident #ty_generics + #where_clause + { + type Value = #field_type; + + fn get_field( + &self, + key: ::core::marker::PhantomData< #field_symbol >, + ) -> &Self::Value + { + &self. #field_ident + } + } + }; + + let has_field_mut_impl: ItemImpl = parse_quote! { + impl #impl_generics HasFieldMut< #field_symbol > + for #struct_ident #ty_generics + #where_clause + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< #field_symbol >, + ) -> &mut Self::Value + { + &mut self. #field_ident + } + } + }; + + item_impls.push(has_field_impl); + item_impls.push(has_field_mut_impl); + } + } + Fields::Unnamed(fields) => { + for (i, field) in fields.unnamed.iter().enumerate() { + let field_tag = Index { + index: i, + span: field.span(), + }; + + let field_ident = LitInt::new(&format!("{i}"), field.span()); + + let field_type = &field.ty; + + let has_field_impl: ItemImpl = parse_quote! { + impl #impl_generics HasField< #field_tag > + for #struct_ident #ty_generics + #where_clause + { + type Value = #field_type; + + fn get_field( + &self, + key: ::core::marker::PhantomData< #field_tag >, + ) -> &Self::Value + { + &self. #field_ident + } + } + }; + + let has_field_mut_impl: ItemImpl = parse_quote! { + impl #impl_generics HasFieldMut< #field_tag > + for #struct_ident #ty_generics + #where_clause + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< #field_tag >, + ) -> &mut Self::Value + { + &mut self. #field_ident + } + } + }; + + item_impls.push(has_field_impl); + item_impls.push(has_field_mut_impl); + } + } + _ => {} + } + + Ok(item_impls) + } +} diff --git a/crates/macros/cgp-macro-core/src/types/mod.rs b/crates/macros/cgp-macro-core/src/types/mod.rs index 473ae9f3..c2325812 100644 --- a/crates/macros/cgp-macro-core/src/types/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/mod.rs @@ -2,6 +2,7 @@ pub mod attributes; pub mod blanket_trait; pub mod cgp_auto_getter; pub mod cgp_component; +pub mod cgp_data; pub mod cgp_fn; pub mod cgp_getter; pub mod cgp_impl; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs index 66a2b80f..bf7d0a28 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs @@ -7,7 +7,7 @@ pub fn derive_cgp_data(body: TokenStream) -> syn::Result { let item: Item = parse2(body)?; match item { - Item::Struct(item_struct) => derive_cgp_record_from_struct(&item_struct), + Item::Struct(item_struct) => derive_cgp_record_from_struct(item_struct), Item::Enum(item_enum) => derive_cgp_variant_from_enum(&item_enum), _ => Err(Error::new_spanned( item, diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs index a1bb5c27..0131b70d 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs @@ -1,20 +1,22 @@ +use cgp_macro_core::types::cgp_data::ItemCgpRecord; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemStruct, parse2}; use crate::derive_build_field_from_struct; use crate::derive_has_fields::derive_has_fields_impls_from_struct; -use crate::field::derive_has_field_impls_from_struct; pub fn derive_cgp_record(body: TokenStream) -> syn::Result { let item_struct = parse2(body)?; - derive_cgp_record_from_struct(&item_struct) + derive_cgp_record_from_struct(item_struct) } -pub fn derive_cgp_record_from_struct(item_struct: &ItemStruct) -> syn::Result { - let has_field_impls = derive_has_field_impls_from_struct(item_struct)?; - let has_fields_impls = derive_has_fields_impls_from_struct(item_struct)?; - let build_field_impls = derive_build_field_from_struct(item_struct)?; +pub fn derive_cgp_record_from_struct(item_struct: ItemStruct) -> syn::Result { + let record = ItemCgpRecord { item_struct }; + + let has_field_impls = record.to_has_field_impls()?; + let has_fields_impls = derive_has_fields_impls_from_struct(&record.item_struct)?; + let build_field_impls = derive_build_field_from_struct(&record.item_struct)?; Ok(quote! { #( #has_field_impls )* diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs new file mode 100644 index 00000000..72116fbc --- /dev/null +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs @@ -0,0 +1,16 @@ +use cgp_macro_core::types::cgp_data::ItemCgpRecord; +use proc_macro2::TokenStream; +use quote::quote; +use syn::ItemStruct; + +pub fn derive_has_field(input: TokenStream) -> syn::Result { + let item_struct: ItemStruct = syn::parse2(input)?; + + let record = ItemCgpRecord { item_struct }; + + let item_impls = record.to_has_field_impls()?; + + Ok(quote! { + #( #item_impls )* + }) +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs index 45606933..c627dc19 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs @@ -17,6 +17,7 @@ mod delegate_components; mod derive_build_field; mod derive_extract_field; mod derive_from_variant; +mod derive_has_field; mod derive_has_fields; mod path; mod product; @@ -42,6 +43,7 @@ pub use delegate_components::*; pub use derive_build_field::*; pub use derive_extract_field::*; pub use derive_from_variant::*; +pub use derive_has_field::*; pub use derive_has_fields::*; pub use path::*; pub use product::*; diff --git a/crates/macros/cgp-macro-lib/src/field.rs b/crates/macros/cgp-macro-lib/src/field.rs deleted file mode 100644 index 7c77386b..00000000 --- a/crates/macros/cgp-macro-lib/src/field.rs +++ /dev/null @@ -1,118 +0,0 @@ -use alloc::vec::Vec; - -use cgp_macro_core::types::field::Symbol; -use proc_macro2::TokenStream; -use quote::quote; -use syn::spanned::Spanned; -use syn::{Fields, ItemImpl, ItemStruct, LitInt, parse_quote}; - -pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Result> { - let struct_ident = &item_struct.ident; - - let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl(); - - let mut item_impls = Vec::new(); - - match &item_struct.fields { - Fields::Named(fields) => { - for field in fields.named.iter() { - let field_ident = field.ident.as_ref().unwrap(); - - let field_symbol = Symbol::from_ident(field_ident.clone()); - - let field_type = &field.ty; - - let has_field_impl: ItemImpl = parse_quote! { - impl #impl_generics HasField< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - type Value = #field_type; - - fn get_field( - &self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &Self::Value - { - &self. #field_ident - } - } - }; - - let has_field_mut_impl: ItemImpl = parse_quote! { - impl #impl_generics HasFieldMut< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - fn get_field_mut( - &mut self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &mut Self::Value - { - &mut self. #field_ident - } - } - }; - - item_impls.push(has_field_impl); - item_impls.push(has_field_mut_impl); - } - } - Fields::Unnamed(fields) => { - for (i, field) in fields.unnamed.iter().enumerate() { - let field_ident = LitInt::new(&format!("{i}"), field.span()); - let field_symbol = quote! { δ< #field_ident > }; - - let field_type = &field.ty; - - let has_field_impl: ItemImpl = parse_quote! { - impl #impl_generics HasField< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - type Value = #field_type; - - fn get_field( - &self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &Self::Value - { - &self. #field_ident - } - } - }; - - let has_field_mut_impl: ItemImpl = parse_quote! { - impl #impl_generics HasFieldMut< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - fn get_field_mut( - &mut self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &mut Self::Value - { - &mut self. #field_ident - } - } - }; - - item_impls.push(has_field_impl); - item_impls.push(has_field_mut_impl); - } - } - _ => {} - } - - Ok(item_impls) -} - -pub fn derive_has_field(input: TokenStream) -> syn::Result { - let item_struct: ItemStruct = syn::parse2(input)?; - - let item_impls = derive_has_field_impls_from_struct(&item_struct)?; - - Ok(quote! { - #( #item_impls )* - }) -} diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index 7e6e2c62..ffe8e5f2 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -10,10 +10,7 @@ extern crate alloc; pub(crate) mod derive_builder; pub(crate) mod derive_extractor; pub(crate) mod derive_has_fields; -pub(crate) mod field; mod entrypoints; -pub use field::derive_has_field; - pub use crate::entrypoints::*; From 2087dd17148bdb9bdbd7235d565a56879194a906 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 21:44:02 +0200 Subject: [PATCH 11/29] Move derive_has_fields --- .../src/types/cgp_data}/derive_has_fields/derive_enum.rs | 8 ++++---- .../types/cgp_data}/derive_has_fields/derive_struct.rs | 8 ++++---- .../types/cgp_data}/derive_has_fields/from_fields_enum.rs | 2 +- .../cgp_data}/derive_has_fields/from_fields_struct.rs | 0 .../src/types/cgp_data}/derive_has_fields/mod.rs | 8 ++++++++ .../src/types/cgp_data}/derive_has_fields/product.rs | 3 ++- .../src/types/cgp_data}/derive_has_fields/sum.rs | 4 ++-- .../types/cgp_data}/derive_has_fields/to_fields_enum.rs | 2 +- .../cgp_data}/derive_has_fields/to_fields_ref_enum.rs | 2 +- .../cgp_data}/derive_has_fields/to_fields_ref_struct.rs | 2 +- .../types/cgp_data}/derive_has_fields/to_fields_struct.rs | 0 crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs | 2 ++ crates/macros/cgp-macro-core/src/types/cgp_data/record.rs | 4 ++++ crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs | 3 +-- .../macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs | 2 +- .../cgp-macro-lib/src/entrypoints/derive_has_fields.rs | 7 +++---- crates/macros/cgp-macro-lib/src/lib.rs | 1 - 17 files changed, 35 insertions(+), 23 deletions(-) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/derive_enum.rs (83%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/derive_struct.rs (82%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/from_fields_enum.rs (94%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/from_fields_struct.rs (100%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/mod.rs (53%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/product.rs (97%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/sum.rs (86%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/to_fields_enum.rs (97%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/to_fields_ref_enum.rs (91%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/to_fields_ref_struct.rs (92%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_has_fields/to_fields_struct.rs (100%) diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/derive_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs similarity index 83% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/derive_enum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs index 61600c6a..cf3a467a 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/derive_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs @@ -2,10 +2,10 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; -use crate::derive_has_fields::from_fields_enum::derive_from_fields_for_enum; -use crate::derive_has_fields::sum::variants_to_sum_type; -use crate::derive_has_fields::to_fields_enum::derive_to_fields_for_enum; -use crate::derive_has_fields::to_fields_ref_enum::derive_to_fields_ref_for_enum; +use crate::types::cgp_data::{ + derive_from_fields_for_enum, derive_to_fields_for_enum, derive_to_fields_ref_for_enum, + variants_to_sum_type, +}; pub fn derive_has_fields_impls_from_enum(item_enum: &ItemEnum) -> syn::Result> { let struct_name = &item_enum.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/derive_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs similarity index 82% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/derive_struct.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs index a33b60f0..a1fe3309 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/derive_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs @@ -2,10 +2,10 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemImpl, ItemStruct, parse2}; -use crate::derive_has_fields::from_fields_struct::derive_from_fields_for_struct; -use crate::derive_has_fields::product::item_fields_to_product_type; -use crate::derive_has_fields::to_fields_ref_struct::derive_to_fields_ref_for_struct; -use crate::derive_has_fields::to_fields_struct::derive_to_fields_for_struct; +use crate::types::cgp_data::{ + derive_from_fields_for_struct, derive_to_fields_for_struct, derive_to_fields_ref_for_struct, + item_fields_to_product_type, +}; pub fn derive_has_fields_impls_from_struct(item_struct: &ItemStruct) -> syn::Result> { let struct_name = &item_struct.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/from_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs similarity index 94% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/from_fields_enum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs index 9390fec5..566ee892 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/from_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; -use crate::derive_has_fields::from_fields_struct::derive_from_field_params; +use crate::types::cgp_data::derive_from_field_params; pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { let enum_name = &item_enum.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/from_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/from_fields_struct.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/mod.rs similarity index 53% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/mod.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/mod.rs index 8b42af8f..7393c6ab 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/mod.rs @@ -11,3 +11,11 @@ mod to_fields_struct; pub use derive_enum::*; pub use derive_struct::*; +pub use from_fields_enum::*; +pub use from_fields_struct::*; +pub use product::*; +pub use sum::*; +pub use to_fields_enum::*; +pub use to_fields_ref_enum::*; +pub use to_fields_ref_struct::*; +pub use to_fields_struct::*; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs similarity index 97% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs index 2d08e105..6d92987e 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/product.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs @@ -1,9 +1,10 @@ -use cgp_macro_core::types::field::Symbol; use proc_macro2::TokenStream; use quote::quote; use syn::spanned::Spanned; use syn::{Error, Fields, LitInt, Type, parse2}; +use crate::types::field::Symbol; + pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> syn::Result { let mut fields_type = quote! { ε }; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs similarity index 86% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs index 7c358380..2c97d9c7 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/sum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs @@ -1,11 +1,11 @@ -use cgp_macro_core::types::field::Symbol; use proc_macro2::TokenStream; use quote::quote; use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{Type, Variant, parse2}; -use crate::derive_has_fields::product::item_fields_to_product_type; +use crate::types::cgp_data::item_fields_to_product_type; +use crate::types::field::Symbol; pub fn variants_to_sum_type( variants: &Punctuated, diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs similarity index 97% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_enum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs index f9c188dd..d2fba0f8 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs @@ -5,7 +5,7 @@ use syn::spanned::Spanned; use syn::token::Comma; use syn::{Error, Fields, Ident, ItemEnum, ItemImpl, Variant, parse2}; -use crate::derive_has_fields::to_fields_struct::{FieldLabel, derive_to_fields_constructor}; +use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; pub fn derive_to_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { let enum_name = &item_enum.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs similarity index 91% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_enum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs index 4b03d43d..3663f9c5 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; -use crate::derive_has_fields::to_fields_enum::derive_to_fields_match_arms; +use crate::types::cgp_data::derive_to_fields_match_arms; pub fn derive_to_fields_ref_for_enum(item_enum: &ItemEnum) -> syn::Result { let struct_name = &item_enum.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs similarity index 92% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_struct.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs index 7aa238f6..d55d4ae8 100644 --- a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_ref_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{ItemImpl, ItemStruct, Lifetime, parse_quote, parse2}; -use crate::derive_has_fields::to_fields_struct::{FieldLabel, derive_to_fields_constructor}; +use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; pub fn derive_to_fields_ref_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; diff --git a/crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/derive_has_fields/to_fields_struct.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index 67d5f59a..7f5aaad2 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -1,3 +1,5 @@ +mod derive_has_fields; mod record; +pub use derive_has_fields::*; pub use record::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index 869c8c3e..e1c4c4a7 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -114,4 +114,8 @@ impl ItemCgpRecord { Ok(item_impls) } + + // pub fn to_has_fields_impls(&self) -> syn::Result> { + + // } } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs index 0131b70d..99a2c02b 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs @@ -1,10 +1,9 @@ -use cgp_macro_core::types::cgp_data::ItemCgpRecord; +use cgp_macro_core::types::cgp_data::{ItemCgpRecord, derive_has_fields_impls_from_struct}; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemStruct, parse2}; use crate::derive_build_field_from_struct; -use crate::derive_has_fields::derive_has_fields_impls_from_struct; pub fn derive_cgp_record(body: TokenStream) -> syn::Result { let item_struct = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs index 9f578253..43c084de 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs @@ -1,8 +1,8 @@ +use cgp_macro_core::types::cgp_data::derive_has_fields_impls_from_enum; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, parse2}; -use crate::derive_has_fields::derive_has_fields_impls_from_enum; use crate::{derive_extract_field_from_enum, derive_from_variant_from_enum}; pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs index 538178ce..d910d3d9 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs @@ -1,11 +1,10 @@ +use cgp_macro_core::types::cgp_data::{ + derive_has_fields_impls_from_enum, derive_has_fields_impls_from_struct, +}; use proc_macro2::TokenStream; use quote::quote; use syn::{Error, Item, parse2}; -use crate::derive_has_fields::{ - derive_has_fields_impls_from_enum, derive_has_fields_impls_from_struct, -}; - pub fn derive_has_fields(body: TokenStream) -> syn::Result { let item: Item = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index ffe8e5f2..6815b9df 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -9,7 +9,6 @@ extern crate alloc; pub(crate) mod derive_builder; pub(crate) mod derive_extractor; -pub(crate) mod derive_has_fields; mod entrypoints; From a9de6625b3b83b8de4c74a30488b4e037b4d6767 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 21:49:10 +0200 Subject: [PATCH 12/29] Move derive_builder --- .../types/cgp_data}/derive_builder/builder_struct.rs | 2 +- .../cgp_data}/derive_builder/finalize_build_impl.rs | 2 +- .../types/cgp_data}/derive_builder/has_builder_impl.rs | 2 +- .../types/cgp_data}/derive_builder/has_field_impls.rs | 2 +- .../cgp_data}/derive_builder/into_builder_impl.rs | 2 +- .../src/types/cgp_data}/derive_builder/mod.rs | 0 .../src/types/cgp_data}/derive_builder/partial_data.rs | 2 +- .../cgp_data}/derive_builder/update_field_impls.rs | 2 +- .../src/types/cgp_data}/derive_builder/utils.rs | 3 ++- crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs | 2 ++ .../macros/cgp-macro-core/src/types/cgp_data/record.rs | 7 ++++--- .../src/derive_extractor/extract_field_impls.rs | 2 +- .../src/derive_extractor/extractor_enum.rs | 2 +- .../src/derive_extractor/finalize_extract_impl.rs | 3 +-- .../src/derive_extractor/has_extractor_impl.rs | 3 +-- .../cgp-macro-lib/src/derive_extractor/partial_data.rs | 3 +-- .../macros/cgp-macro-lib/src/entrypoints/cgp_record.rs | 4 ++-- .../src/entrypoints/derive_build_field.rs | 9 ++++----- .../cgp-macro-lib/src/entrypoints/derive_has_fields.rs | 10 ++++++---- crates/macros/cgp-macro-lib/src/lib.rs | 1 - 20 files changed, 32 insertions(+), 31 deletions(-) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/builder_struct.rs (94%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/finalize_build_impl.rs (94%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/has_builder_impl.rs (93%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/has_field_impls.rs (98%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/into_builder_impl.rs (94%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/mod.rs (100%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/partial_data.rs (94%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/update_field_impls.rs (99%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_builder/utils.rs (95%) diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/builder_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs similarity index 94% rename from crates/macros/cgp-macro-lib/src/derive_builder/builder_struct.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs index c260a799..675712fb 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/builder_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{GenericParam, Ident, ItemStruct, Type, TypeParam, parse2}; -use crate::derive_builder::index_to_generic_ident; +use crate::types::cgp_data::index_to_generic_ident; pub fn derive_builder_struct( context_struct: &ItemStruct, diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/finalize_build_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs similarity index 94% rename from crates/macros/cgp-macro-lib/src/derive_builder/finalize_build_impl.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs index feb50e86..3204d869 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/finalize_build_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs @@ -3,7 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, Type, parse2}; -use crate::derive_builder::{field_to_member, field_value_expr, to_generic_args}; +use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_finalize_build_impl( context_struct: &ItemStruct, diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/has_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs similarity index 93% rename from crates/macros/cgp-macro-lib/src/derive_builder/has_builder_impl.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs index 07e92ccd..4029b283 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/has_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs @@ -3,7 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, parse2}; -use crate::derive_builder::{field_to_member, field_value_expr, to_generic_args}; +use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_has_builder_impl( context_struct: &ItemStruct, diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs similarity index 98% rename from crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs index c186cea0..b2bea077 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/has_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{Ident, ItemImpl, ItemStruct, parse2}; -use crate::derive_builder::{ +use crate::types::cgp_data::{ field_to_member, field_to_tag, index_to_generic_ident, to_generic_args, }; diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/into_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs similarity index 94% rename from crates/macros/cgp-macro-lib/src/derive_builder/into_builder_impl.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs index dbc9b139..159c9200 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/into_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs @@ -3,7 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, parse2}; -use crate::derive_builder::{field_to_member, field_value_expr, to_generic_args}; +use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_into_builder_impl( context_struct: &ItemStruct, diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/mod.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/derive_builder/mod.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/mod.rs diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs similarity index 94% rename from crates/macros/cgp-macro-lib/src/derive_builder/partial_data.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs index 41be3349..abd3aeae 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{Ident, ItemImpl, ItemStruct, parse2}; -use crate::derive_builder::index_to_generic_ident; +use crate::types::cgp_data::index_to_generic_ident; pub fn derive_partial_data_impl( context_struct: &ItemStruct, diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs similarity index 99% rename from crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs index 58344779..1d4ae9c4 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/update_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs @@ -3,7 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, GenericArgument, Ident, ItemImpl, ItemStruct, Type, parse2}; -use crate::derive_builder::{ +use crate::types::cgp_data::{ field_to_member, field_to_tag, field_value_expr, index_to_generic_ident, to_generic_args, }; diff --git a/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs similarity index 95% rename from crates/macros/cgp-macro-lib/src/derive_builder/utils.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs index 200b3135..45d19841 100644 --- a/crates/macros/cgp-macro-lib/src/derive_builder/utils.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/utils.rs @@ -1,10 +1,11 @@ -use cgp_macro_core::types::field::{FieldName, Index, Symbol}; use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, quote}; use syn::spanned::Spanned; use syn::token::Colon; use syn::{AngleBracketedGenericArguments, Field, FieldValue, Generics, Ident, Member, parse2}; +use crate::types::field::{FieldName, Index, Symbol}; + pub fn to_generic_args(generics: &Generics) -> syn::Result { if generics.params.is_empty() { parse2(quote! { < > }) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index 7f5aaad2..06c6efa3 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -1,5 +1,7 @@ +mod derive_builder; mod derive_has_fields; mod record; +pub use derive_builder::*; pub use derive_has_fields::*; pub use record::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index e1c4c4a7..36e044dd 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -1,6 +1,7 @@ use syn::spanned::Spanned; use syn::{Fields, ItemImpl, ItemStruct, LitInt, parse_quote}; +use crate::types::cgp_data::derive_has_fields_impls_from_struct; use crate::types::field::{Index, Symbol}; pub struct ItemCgpRecord { @@ -115,7 +116,7 @@ impl ItemCgpRecord { Ok(item_impls) } - // pub fn to_has_fields_impls(&self) -> syn::Result> { - - // } + pub fn to_has_fields_impls(&self) -> syn::Result> { + derive_has_fields_impls_from_struct(&self.item_struct) + } } diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs index a22de9c8..1ea81ddb 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs @@ -1,8 +1,8 @@ +use cgp_macro_core::types::cgp_data::{index_to_generic_ident, to_generic_args}; use cgp_macro_core::types::field::Symbol; use quote::quote; use syn::{Arm, GenericArgument, Ident, ItemEnum, ItemImpl, Type, parse2}; -use crate::derive_builder::{index_to_generic_ident, to_generic_args}; use crate::derive_extractor::get_variant_type; pub fn derive_extract_field_impls( diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs index 2e44c92c..6e712fd8 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs @@ -1,8 +1,8 @@ +use cgp_macro_core::types::cgp_data::index_to_generic_ident; use proc_macro2::Span; use quote::quote; use syn::{GenericParam, Ident, ItemEnum, Lifetime, LifetimeParam, Type, TypeParam, parse2}; -use crate::derive_builder::index_to_generic_ident; use crate::derive_extractor::{get_variant_type, type_to_variant_fields}; pub fn derive_extractor_enum( diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs index ff72b386..45fcd01a 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs @@ -1,8 +1,7 @@ +use cgp_macro_core::types::cgp_data::to_generic_args; use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, Type, parse2}; -use crate::derive_builder::to_generic_args; - pub fn derive_finalize_extract_impl( context_enum: &ItemEnum, extractor_ident: &Ident, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs index 97417ed5..f9e8b511 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs @@ -1,8 +1,7 @@ +use cgp_macro_core::types::cgp_data::to_generic_args; use quote::quote; use syn::{Arm, Ident, ItemEnum, ItemImpl, parse2}; -use crate::derive_builder::to_generic_args; - pub fn derive_has_extractor_impl( context_enum: &ItemEnum, extractor_ident: &Ident, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs b/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs index f5140b7b..cb15cda0 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs +++ b/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs @@ -1,8 +1,7 @@ +use cgp_macro_core::types::cgp_data::index_to_generic_ident; use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, parse2}; -use crate::derive_builder::index_to_generic_ident; - pub fn derive_partial_data_impl( context_struct: &ItemEnum, builder_ident: &Ident, diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs index 99a2c02b..a5ffaeeb 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs @@ -1,4 +1,4 @@ -use cgp_macro_core::types::cgp_data::{ItemCgpRecord, derive_has_fields_impls_from_struct}; +use cgp_macro_core::types::cgp_data::ItemCgpRecord; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemStruct, parse2}; @@ -14,7 +14,7 @@ pub fn derive_cgp_record_from_struct(item_struct: ItemStruct) -> syn::Result syn::Result { let context_struct: ItemStruct = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs index d910d3d9..46f62186 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs @@ -1,6 +1,4 @@ -use cgp_macro_core::types::cgp_data::{ - derive_has_fields_impls_from_enum, derive_has_fields_impls_from_struct, -}; +use cgp_macro_core::types::cgp_data::{ItemCgpRecord, derive_has_fields_impls_from_enum}; use proc_macro2::TokenStream; use quote::quote; use syn::{Error, Item, parse2}; @@ -9,7 +7,11 @@ pub fn derive_has_fields(body: TokenStream) -> syn::Result { let item: Item = parse2(body)?; let impls = match item { - Item::Struct(item_struct) => derive_has_fields_impls_from_struct(&item_struct)?, + Item::Struct(item_struct) => { + let record = ItemCgpRecord { item_struct }; + + record.to_has_fields_impls()? + } Item::Enum(item_enum) => derive_has_fields_impls_from_enum(&item_enum)?, _ => { return Err(Error::new_spanned( diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index 6815b9df..8ad49883 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -7,7 +7,6 @@ extern crate alloc; -pub(crate) mod derive_builder; pub(crate) mod derive_extractor; mod entrypoints; From dc09bcb573ebaaf25d19e0cc702c8b39bad12259 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 21:52:33 +0200 Subject: [PATCH 13/29] Move derive_extractor --- .../cgp_data/derive_builder/partial_data.rs | 2 +- .../derive_extractor/extract_field_impls.rs | 5 ++--- .../derive_extractor/extractor_enum.rs | 3 +-- .../derive_extractor/finalize_extract_impl.rs | 3 ++- .../derive_extractor/has_extractor_impl.rs | 3 ++- .../src/types/cgp_data}/derive_extractor/mod.rs | 0 .../cgp_data}/derive_extractor/partial_data.rs | 5 +++-- .../types/cgp_data}/derive_extractor/utils.rs | 0 .../cgp-macro-core/src/types/cgp_data/mod.rs | 2 ++ .../src/entrypoints/derive_build_field.rs | 4 ++-- .../src/entrypoints/derive_extract_field.rs | 17 +++++++++-------- .../src/entrypoints/derive_from_variant.rs | 3 +-- crates/macros/cgp-macro-lib/src/lib.rs | 2 -- 13 files changed, 25 insertions(+), 24 deletions(-) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/extract_field_impls.rs (95%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/extractor_enum.rs (95%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/finalize_extract_impl.rs (95%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/has_extractor_impl.rs (98%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/mod.rs (100%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/partial_data.rs (92%) rename crates/macros/{cgp-macro-lib/src => cgp-macro-core/src/types/cgp_data}/derive_extractor/utils.rs (100%) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs index abd3aeae..05b343c2 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs @@ -3,7 +3,7 @@ use syn::{Ident, ItemImpl, ItemStruct, parse2}; use crate::types::cgp_data::index_to_generic_ident; -pub fn derive_partial_data_impl( +pub fn derive_partial_data_impl_from_struct( context_struct: &ItemStruct, builder_ident: &Ident, ) -> syn::Result { diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs similarity index 95% rename from crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs index 1ea81ddb..5bc04f99 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/extract_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs @@ -1,9 +1,8 @@ -use cgp_macro_core::types::cgp_data::{index_to_generic_ident, to_generic_args}; -use cgp_macro_core::types::field::Symbol; use quote::quote; use syn::{Arm, GenericArgument, Ident, ItemEnum, ItemImpl, Type, parse2}; -use crate::derive_extractor::get_variant_type; +use crate::types::cgp_data::{get_variant_type, index_to_generic_ident, to_generic_args}; +use crate::types::field::Symbol; pub fn derive_extract_field_impls( context_enum: &ItemEnum, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs similarity index 95% rename from crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs index 6e712fd8..8bc1ed0c 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/extractor_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs @@ -1,9 +1,8 @@ -use cgp_macro_core::types::cgp_data::index_to_generic_ident; use proc_macro2::Span; use quote::quote; use syn::{GenericParam, Ident, ItemEnum, Lifetime, LifetimeParam, Type, TypeParam, parse2}; -use crate::derive_extractor::{get_variant_type, type_to_variant_fields}; +use crate::types::cgp_data::{get_variant_type, index_to_generic_ident, type_to_variant_fields}; pub fn derive_extractor_enum( context_enum: &ItemEnum, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs similarity index 95% rename from crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs index 45fcd01a..5ac08857 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/finalize_extract_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs @@ -1,7 +1,8 @@ -use cgp_macro_core::types::cgp_data::to_generic_args; use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, Type, parse2}; +use crate::types::cgp_data::to_generic_args; + pub fn derive_finalize_extract_impl( context_enum: &ItemEnum, extractor_ident: &Ident, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs similarity index 98% rename from crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs index f9e8b511..9f609403 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/has_extractor_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs @@ -1,7 +1,8 @@ -use cgp_macro_core::types::cgp_data::to_generic_args; use quote::quote; use syn::{Arm, Ident, ItemEnum, ItemImpl, parse2}; +use crate::types::cgp_data::to_generic_args; + pub fn derive_has_extractor_impl( context_enum: &ItemEnum, extractor_ident: &Ident, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/mod.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/derive_extractor/mod.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/mod.rs diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs similarity index 92% rename from crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs index cb15cda0..5234c034 100644 --- a/crates/macros/cgp-macro-lib/src/derive_extractor/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs @@ -1,8 +1,9 @@ -use cgp_macro_core::types::cgp_data::index_to_generic_ident; use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, parse2}; -pub fn derive_partial_data_impl( +use crate::types::cgp_data::index_to_generic_ident; + +pub fn derive_partial_data_impl_from_enum( context_struct: &ItemEnum, builder_ident: &Ident, is_ref: bool, diff --git a/crates/macros/cgp-macro-lib/src/derive_extractor/utils.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/utils.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/derive_extractor/utils.rs rename to crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/utils.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index 06c6efa3..e775f82e 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -1,7 +1,9 @@ mod derive_builder; +mod derive_extractor; mod derive_has_fields; mod record; pub use derive_builder::*; +pub use derive_extractor::*; pub use derive_has_fields::*; pub use record::*; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs index a1d1d0ca..b231f219 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs @@ -1,6 +1,6 @@ use cgp_macro_core::types::cgp_data::{ derive_builder_struct, derive_finalize_build_impl, derive_has_builder_impl, - derive_has_field_impls, derive_into_builder_impl, derive_partial_data_impl, + derive_has_field_impls, derive_into_builder_impl, derive_partial_data_impl_from_struct, derive_update_field_impls, }; use proc_macro2::TokenStream; @@ -22,7 +22,7 @@ pub fn derive_build_field_from_struct(context_struct: &ItemStruct) -> syn::Resul let into_builder_impl = derive_into_builder_impl(context_struct, &builder_ident)?; - let partial_data_impl = derive_partial_data_impl(context_struct, &builder_ident)?; + let partial_data_impl = derive_partial_data_impl_from_struct(context_struct, &builder_ident)?; let update_field_impls = derive_update_field_impls(context_struct, &builder_ident)?; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs index 18fdf711..2e27bb01 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs @@ -1,12 +1,11 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Ident, ItemEnum, parse2}; - -use crate::derive_extractor::{ +use cgp_macro_core::types::cgp_data::{ derive_extract_field_impls, derive_extractor_enum, derive_extractor_enum_ref, derive_finalize_extract_impl, derive_has_extractor_impl, derive_has_extractor_mut_impl, - derive_has_extractor_ref_impl, derive_partial_data_impl, + derive_has_extractor_ref_impl, derive_partial_data_impl_from_enum, }; +use proc_macro2::TokenStream; +use quote::quote; +use syn::{Ident, ItemEnum, parse2}; pub fn derive_extract_field(body: TokenStream) -> syn::Result { let context_enum: ItemEnum = parse2(body)?; @@ -37,8 +36,10 @@ pub fn derive_extract_field_from_enum(context_enum: &ItemEnum) -> syn::Result syn::Result { let item_enum: ItemEnum = parse2(body)?; diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index 8ad49883..b4275ced 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -7,8 +7,6 @@ extern crate alloc; -pub(crate) mod derive_extractor; - mod entrypoints; pub use crate::entrypoints::*; From 02dcc3aa23b518e9672eb5f0cabcf93feafad75f Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 21:59:13 +0200 Subject: [PATCH 14/29] Implement to_build_field_items --- .../src/types/cgp_data/record.rs | 42 +++++++++++++++- .../src/entrypoints/cgp_record.rs | 6 +-- .../src/entrypoints/derive_build_field.rs | 50 +++---------------- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index 36e044dd..6cdf98da 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -1,7 +1,11 @@ use syn::spanned::Spanned; -use syn::{Fields, ItemImpl, ItemStruct, LitInt, parse_quote}; +use syn::{Fields, Ident, Item, ItemImpl, ItemStruct, LitInt, parse_quote}; -use crate::types::cgp_data::derive_has_fields_impls_from_struct; +use crate::types::cgp_data::{ + derive_builder_struct, derive_finalize_build_impl, derive_has_builder_impl, + derive_has_field_impls, derive_has_fields_impls_from_struct, derive_into_builder_impl, + derive_partial_data_impl_from_struct, derive_update_field_impls, +}; use crate::types::field::{Index, Symbol}; pub struct ItemCgpRecord { @@ -119,4 +123,38 @@ impl ItemCgpRecord { pub fn to_has_fields_impls(&self) -> syn::Result> { derive_has_fields_impls_from_struct(&self.item_struct) } + + pub fn to_build_field_items(&self) -> syn::Result> { + let item_struct = &self.item_struct; + + let context_ident = &item_struct.ident; + let builder_ident = Ident::new(&format!("__Partial{context_ident}"), context_ident.span()); + + let builder_struct = derive_builder_struct(item_struct, &builder_ident)?; + + let has_builder_impl = derive_has_builder_impl(item_struct, &builder_ident)?; + + let into_builder_impl = derive_into_builder_impl(item_struct, &builder_ident)?; + + let partial_data_impl = derive_partial_data_impl_from_struct(item_struct, &builder_ident)?; + + let finalize_build_impl = derive_finalize_build_impl(item_struct, &builder_ident)?; + + let update_field_impls = derive_update_field_impls(item_struct, &builder_ident)?; + + let has_field_impls = derive_has_field_impls(item_struct, &builder_ident)?; + + let mut out = vec![ + builder_struct.into(), + has_builder_impl.into(), + into_builder_impl.into(), + partial_data_impl.into(), + finalize_build_impl.into(), + ]; + + out.extend(update_field_impls.into_iter().map(Item::from)); + out.extend(has_field_impls.into_iter().map(Item::from)); + + Ok(out) + } } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs index a5ffaeeb..72577eda 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs @@ -3,8 +3,6 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemStruct, parse2}; -use crate::derive_build_field_from_struct; - pub fn derive_cgp_record(body: TokenStream) -> syn::Result { let item_struct = parse2(body)?; derive_cgp_record_from_struct(item_struct) @@ -15,11 +13,11 @@ pub fn derive_cgp_record_from_struct(item_struct: ItemStruct) -> syn::Result syn::Result { - let context_struct: ItemStruct = parse2(body)?; - derive_build_field_from_struct(&context_struct) -} - -pub fn derive_build_field_from_struct(context_struct: &ItemStruct) -> syn::Result { - let context_ident = &context_struct.ident; - let builder_ident = Ident::new(&format!("__Partial{context_ident}"), context_ident.span()); - - let builder_struct = derive_builder_struct(context_struct, &builder_ident)?; - - let has_builder_impl = derive_has_builder_impl(context_struct, &builder_ident)?; - - let into_builder_impl = derive_into_builder_impl(context_struct, &builder_ident)?; - - let partial_data_impl = derive_partial_data_impl_from_struct(context_struct, &builder_ident)?; - - let update_field_impls = derive_update_field_impls(context_struct, &builder_ident)?; - - let has_field_impls = derive_has_field_impls(context_struct, &builder_ident)?; - - let finalize_build_impl = derive_finalize_build_impl(context_struct, &builder_ident)?; - - let out = quote! { - #builder_struct - - #has_builder_impl - - #into_builder_impl - - #partial_data_impl - - #(#update_field_impls)* + let item_struct: ItemStruct = parse2(body)?; - #(#has_field_impls)* + let record = ItemCgpRecord { item_struct }; - #finalize_build_impl - }; + let items = record.to_build_field_items()?; - Ok(out) + Ok(quote! { + #( #items )* + }) } From c99377ba8d2339e084fd21dadda48f60ba21e784 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:01:39 +0200 Subject: [PATCH 15/29] Add back derive_has_field_impls_from_struct --- .../src/types/cgp_data/derive_has_field.rs | 110 +++++++++++++++++ .../cgp-macro-core/src/types/cgp_data/mod.rs | 2 + .../src/types/cgp_data/record.rs | 112 +----------------- 3 files changed, 116 insertions(+), 108 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs new file mode 100644 index 00000000..f1348474 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs @@ -0,0 +1,110 @@ +use syn::spanned::Spanned; +use syn::{Fields, ItemImpl, ItemStruct, LitInt}; + +use crate::parse_internal; +use crate::types::field::{Index, Symbol}; + +pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Result> { + let struct_ident = &item_struct.ident; + + let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl(); + + let mut item_impls = Vec::new(); + + match &item_struct.fields { + Fields::Named(fields) => { + for field in fields.named.iter() { + let field_ident = field.ident.as_ref().unwrap(); + + let field_symbol = Symbol::from_ident(field_ident.clone()); + + let field_type = &field.ty; + + let has_field_impl: ItemImpl = parse_internal! { + impl #impl_generics HasField< #field_symbol > + for #struct_ident #ty_generics + #where_clause + { + type Value = #field_type; + + fn get_field( + &self, + key: ::core::marker::PhantomData< #field_symbol >, + ) -> &Self::Value + { + &self. #field_ident + } + } + }; + + let has_field_mut_impl: ItemImpl = parse_internal! { + impl #impl_generics HasFieldMut< #field_symbol > + for #struct_ident #ty_generics + #where_clause + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< #field_symbol >, + ) -> &mut Self::Value + { + &mut self. #field_ident + } + } + }; + + item_impls.push(has_field_impl); + item_impls.push(has_field_mut_impl); + } + } + Fields::Unnamed(fields) => { + for (i, field) in fields.unnamed.iter().enumerate() { + let field_tag = Index { + index: i, + span: field.span(), + }; + + let field_ident = LitInt::new(&format!("{i}"), field.span()); + + let field_type = &field.ty; + + let has_field_impl: ItemImpl = parse_internal! { + impl #impl_generics HasField< #field_tag > + for #struct_ident #ty_generics + #where_clause + { + type Value = #field_type; + + fn get_field( + &self, + key: ::core::marker::PhantomData< #field_tag >, + ) -> &Self::Value + { + &self. #field_ident + } + } + }; + + let has_field_mut_impl: ItemImpl = parse_internal! { + impl #impl_generics HasFieldMut< #field_tag > + for #struct_ident #ty_generics + #where_clause + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< #field_tag >, + ) -> &mut Self::Value + { + &mut self. #field_ident + } + } + }; + + item_impls.push(has_field_impl); + item_impls.push(has_field_mut_impl); + } + } + _ => {} + } + + Ok(item_impls) +} diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index e775f82e..fd05cc51 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -1,9 +1,11 @@ mod derive_builder; mod derive_extractor; +mod derive_has_field; mod derive_has_fields; mod record; pub use derive_builder::*; pub use derive_extractor::*; +pub use derive_has_field::*; pub use derive_has_fields::*; pub use record::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index 6cdf98da..0661d062 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -1,12 +1,11 @@ -use syn::spanned::Spanned; -use syn::{Fields, Ident, Item, ItemImpl, ItemStruct, LitInt, parse_quote}; +use syn::{Ident, Item, ItemImpl, ItemStruct}; use crate::types::cgp_data::{ derive_builder_struct, derive_finalize_build_impl, derive_has_builder_impl, - derive_has_field_impls, derive_has_fields_impls_from_struct, derive_into_builder_impl, + derive_has_field_impls, derive_has_field_impls_from_struct, + derive_has_fields_impls_from_struct, derive_into_builder_impl, derive_partial_data_impl_from_struct, derive_update_field_impls, }; -use crate::types::field::{Index, Symbol}; pub struct ItemCgpRecord { pub item_struct: ItemStruct, @@ -14,110 +13,7 @@ pub struct ItemCgpRecord { impl ItemCgpRecord { pub fn to_has_field_impls(&self) -> syn::Result> { - let item_struct = &self.item_struct; - - let struct_ident = &item_struct.ident; - - let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl(); - - let mut item_impls = Vec::new(); - - match &item_struct.fields { - Fields::Named(fields) => { - for field in fields.named.iter() { - let field_ident = field.ident.as_ref().unwrap(); - - let field_symbol = Symbol::from_ident(field_ident.clone()); - - let field_type = &field.ty; - - let has_field_impl: ItemImpl = parse_quote! { - impl #impl_generics HasField< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - type Value = #field_type; - - fn get_field( - &self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &Self::Value - { - &self. #field_ident - } - } - }; - - let has_field_mut_impl: ItemImpl = parse_quote! { - impl #impl_generics HasFieldMut< #field_symbol > - for #struct_ident #ty_generics - #where_clause - { - fn get_field_mut( - &mut self, - key: ::core::marker::PhantomData< #field_symbol >, - ) -> &mut Self::Value - { - &mut self. #field_ident - } - } - }; - - item_impls.push(has_field_impl); - item_impls.push(has_field_mut_impl); - } - } - Fields::Unnamed(fields) => { - for (i, field) in fields.unnamed.iter().enumerate() { - let field_tag = Index { - index: i, - span: field.span(), - }; - - let field_ident = LitInt::new(&format!("{i}"), field.span()); - - let field_type = &field.ty; - - let has_field_impl: ItemImpl = parse_quote! { - impl #impl_generics HasField< #field_tag > - for #struct_ident #ty_generics - #where_clause - { - type Value = #field_type; - - fn get_field( - &self, - key: ::core::marker::PhantomData< #field_tag >, - ) -> &Self::Value - { - &self. #field_ident - } - } - }; - - let has_field_mut_impl: ItemImpl = parse_quote! { - impl #impl_generics HasFieldMut< #field_tag > - for #struct_ident #ty_generics - #where_clause - { - fn get_field_mut( - &mut self, - key: ::core::marker::PhantomData< #field_tag >, - ) -> &mut Self::Value - { - &mut self. #field_ident - } - } - }; - - item_impls.push(has_field_impl); - item_impls.push(has_field_mut_impl); - } - } - _ => {} - } - - Ok(item_impls) + derive_has_field_impls_from_struct(&self.item_struct) } pub fn to_has_fields_impls(&self) -> syn::Result> { From a31f21f845eaef3932dabe2651222dad0ccfad1f Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:07:58 +0200 Subject: [PATCH 16/29] Implement to_from_variant_impls --- .../src/types/cgp_data/derive_from_variant.rs | 35 +++++++++++++++ .../cgp-macro-core/src/types/cgp_data/mod.rs | 4 ++ .../src/types/cgp_data/variant.rs | 13 ++++++ .../cgp-macro-lib/src/entrypoints/cgp_data.rs | 2 +- .../src/entrypoints/cgp_variant.rs | 18 ++++---- .../src/entrypoints/derive_from_variant.rs | 43 +++---------------- 6 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs new file mode 100644 index 00000000..80d8aba8 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs @@ -0,0 +1,35 @@ +use syn::{ItemEnum, ItemImpl}; + +use crate::parse_internal; +use crate::types::cgp_data::get_variant_type; +use crate::types::field::Symbol; + +pub fn derive_from_variant_from_enum(item_enum: &ItemEnum) -> syn::Result> { + let enum_ident = &item_enum.ident; + + let (impl_generics, ty_generics, where_clause) = item_enum.generics.split_for_impl(); + + let mut item_impls: Vec = Vec::new(); + + for variant in item_enum.variants.iter() { + let variant_ident = &variant.ident; + let variant_tag = Symbol::from_ident(variant_ident.clone()); + let variant_type = get_variant_type(variant)?; + + let item_impl: ItemImpl = parse_internal! { + impl #impl_generics FromVariant<#variant_tag> for #enum_ident #ty_generics + #where_clause + { + type Value = #variant_type; + + fn from_variant(_tag: ::core::marker::PhantomData<#variant_tag>, value: Self::Value) -> Self { + Self::#variant_ident(value) + } + } + }; + + item_impls.push(item_impl); + } + + Ok(item_impls) +} diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index fd05cc51..237b1f6d 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -1,11 +1,15 @@ mod derive_builder; mod derive_extractor; +mod derive_from_variant; mod derive_has_field; mod derive_has_fields; mod record; +mod variant; pub use derive_builder::*; pub use derive_extractor::*; +pub use derive_from_variant::*; pub use derive_has_field::*; pub use derive_has_fields::*; pub use record::*; +pub use variant::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs new file mode 100644 index 00000000..55d885fe --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs @@ -0,0 +1,13 @@ +use syn::{ItemEnum, ItemImpl}; + +use crate::types::cgp_data::derive_from_variant_from_enum; + +pub struct ItemCgpVariant { + pub item_enum: ItemEnum, +} + +impl ItemCgpVariant { + pub fn to_from_variant_impls(&self) -> syn::Result> { + derive_from_variant_from_enum(&self.item_enum) + } +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs index bf7d0a28..fec6fe73 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs @@ -8,7 +8,7 @@ pub fn derive_cgp_data(body: TokenStream) -> syn::Result { match item { Item::Struct(item_struct) => derive_cgp_record_from_struct(item_struct), - Item::Enum(item_enum) => derive_cgp_variant_from_enum(&item_enum), + Item::Enum(item_enum) => derive_cgp_variant_from_enum(item_enum), _ => Err(Error::new_spanned( item, "expect body to be either a struct or enum", diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs index 43c084de..b19c3a6b 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs @@ -1,23 +1,25 @@ -use cgp_macro_core::types::cgp_data::derive_has_fields_impls_from_enum; +use cgp_macro_core::types::cgp_data::{ItemCgpVariant, derive_has_fields_impls_from_enum}; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, parse2}; -use crate::{derive_extract_field_from_enum, derive_from_variant_from_enum}; +use crate::derive_extract_field_from_enum; pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { let item_enum = parse2(body)?; - derive_cgp_variant_from_enum(&item_enum) + derive_cgp_variant_from_enum(item_enum) } -pub fn derive_cgp_variant_from_enum(item_enum: &ItemEnum) -> syn::Result { - let has_fields = derive_has_fields_impls_from_enum(item_enum)?; - let extract_field = derive_extract_field_from_enum(item_enum)?; - let from_variant = derive_from_variant_from_enum(item_enum)?; +pub fn derive_cgp_variant_from_enum(item_enum: ItemEnum) -> syn::Result { + let variant = ItemCgpVariant { item_enum }; + + let has_fields = derive_has_fields_impls_from_enum(&variant.item_enum)?; + let extract_field = derive_extract_field_from_enum(&variant.item_enum)?; + let from_variant_impls = variant.to_from_variant_impls()?; Ok(quote! { #( #has_fields )* #extract_field - #from_variant + #( #from_variant_impls )* }) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs index d2813deb..46ac7d48 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs @@ -1,45 +1,16 @@ -use cgp_macro_core::types::cgp_data::get_variant_type; -use cgp_macro_core::types::field::Symbol; +use cgp_macro_core::types::cgp_data::ItemCgpVariant; use proc_macro2::TokenStream; use quote::quote; -use syn::{ItemEnum, ItemImpl, parse2}; +use syn::{ItemEnum, parse2}; pub fn derive_from_variant(body: TokenStream) -> syn::Result { let item_enum: ItemEnum = parse2(body)?; - derive_from_variant_from_enum(&item_enum) -} - -pub fn derive_from_variant_from_enum(item_enum: &ItemEnum) -> syn::Result { - let enum_ident = &item_enum.ident; - - let (impl_generics, ty_generics, where_clause) = item_enum.generics.split_for_impl(); - - let mut item_impls: Vec = Vec::new(); - - for variant in item_enum.variants.iter() { - let variant_ident = &variant.ident; - let variant_tag = Symbol::from_ident(variant_ident.clone()); - let variant_type = get_variant_type(variant)?; - - let item_impl: ItemImpl = parse2(quote! { - impl #impl_generics FromVariant<#variant_tag> for #enum_ident #ty_generics - #where_clause - { - type Value = #variant_type; - - fn from_variant(_tag: ::core::marker::PhantomData<#variant_tag>, value: Self::Value) -> Self { - Self::#variant_ident(value) - } - } - })?; - - item_impls.push(item_impl); - } + let variant = ItemCgpVariant { item_enum }; - let out = quote! { - #(#item_impls)* - }; + let item_impls = variant.to_from_variant_impls()?; - Ok(out) + Ok(quote! { + #( #item_impls )* + }) } From e51c6f067430ea91e91d4d508f2ce2a052597e5c Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:14:41 +0200 Subject: [PATCH 17/29] Implement to_extract_field_items --- .../src/types/cgp_data/record.rs | 8 +-- .../src/types/cgp_data/variant.rs | 71 ++++++++++++++++++- .../src/entrypoints/cgp_variant.rs | 12 ++-- .../src/entrypoints/derive_extract_field.rs | 66 +++-------------- 4 files changed, 86 insertions(+), 71 deletions(-) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index 0661d062..34697e43 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -40,7 +40,7 @@ impl ItemCgpRecord { let has_field_impls = derive_has_field_impls(item_struct, &builder_ident)?; - let mut out = vec![ + let mut items = vec![ builder_struct.into(), has_builder_impl.into(), into_builder_impl.into(), @@ -48,9 +48,9 @@ impl ItemCgpRecord { finalize_build_impl.into(), ]; - out.extend(update_field_impls.into_iter().map(Item::from)); - out.extend(has_field_impls.into_iter().map(Item::from)); + items.extend(update_field_impls.into_iter().map(Item::from)); + items.extend(has_field_impls.into_iter().map(Item::from)); - Ok(out) + Ok(items) } } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs index 55d885fe..1a0f4ecc 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs @@ -1,6 +1,11 @@ -use syn::{ItemEnum, ItemImpl}; +use syn::{Ident, Item, ItemEnum, ItemImpl}; -use crate::types::cgp_data::derive_from_variant_from_enum; +use crate::types::cgp_data::{ + derive_extract_field_impls, derive_extractor_enum, derive_extractor_enum_ref, + derive_finalize_extract_impl, derive_from_variant_from_enum, derive_has_extractor_impl, + derive_has_extractor_mut_impl, derive_has_extractor_ref_impl, + derive_has_fields_impls_from_enum, derive_partial_data_impl_from_enum, +}; pub struct ItemCgpVariant { pub item_enum: ItemEnum, @@ -10,4 +15,66 @@ impl ItemCgpVariant { pub fn to_from_variant_impls(&self) -> syn::Result> { derive_from_variant_from_enum(&self.item_enum) } + + pub fn to_has_fields_impls(&self) -> syn::Result> { + derive_has_fields_impls_from_enum(&self.item_enum) + } + + pub fn to_extract_field_items(&self) -> syn::Result> { + let item_enum = &self.item_enum; + + let context_ident = &item_enum.ident; + + let extractor_ident = + Ident::new(&format!("__Partial{context_ident}"), context_ident.span()); + let extractor_enum = derive_extractor_enum(item_enum, &extractor_ident)?; + + let extractor_ref_ident = Ident::new( + &format!("__PartialRef{context_ident}"), + context_ident.span(), + ); + let extractor_ref_enum = derive_extractor_enum_ref(item_enum, &extractor_ref_ident)?; + + let has_extractor_impl = derive_has_extractor_impl(item_enum, &extractor_ident)?; + + let has_extractor_ref_impl = + derive_has_extractor_ref_impl(item_enum, &extractor_ref_ident)?; + + let has_extractor_mut_impl = + derive_has_extractor_mut_impl(item_enum, &extractor_ref_ident)?; + + let finalize_extract_impl = + derive_finalize_extract_impl(item_enum, &extractor_ident, false)?; + + let finalize_extract_ref_impl = + derive_finalize_extract_impl(item_enum, &extractor_ref_ident, true)?; + + let partial_data_impl = + derive_partial_data_impl_from_enum(item_enum, &extractor_ident, false)?; + + let partial_ref_data_impl = + derive_partial_data_impl_from_enum(item_enum, &extractor_ref_ident, true)?; + + let extractor_impls = derive_extract_field_impls(item_enum, &extractor_ident, false)?; + + let extractor_ref_impls = + derive_extract_field_impls(item_enum, &extractor_ref_ident, true)?; + + let mut items = vec![ + extractor_enum.into(), + extractor_ref_enum.into(), + partial_data_impl.into(), + partial_ref_data_impl.into(), + has_extractor_impl.into(), + has_extractor_ref_impl.into(), + has_extractor_mut_impl.into(), + finalize_extract_impl.into(), + finalize_extract_ref_impl.into(), + ]; + + items.extend(extractor_impls.into_iter().map(Item::from)); + items.extend(extractor_ref_impls.into_iter().map(Item::from)); + + Ok(items) + } } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs index b19c3a6b..30ea0633 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs @@ -1,10 +1,8 @@ -use cgp_macro_core::types::cgp_data::{ItemCgpVariant, derive_has_fields_impls_from_enum}; +use cgp_macro_core::types::cgp_data::ItemCgpVariant; use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, parse2}; -use crate::derive_extract_field_from_enum; - pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { let item_enum = parse2(body)?; derive_cgp_variant_from_enum(item_enum) @@ -13,13 +11,13 @@ pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { pub fn derive_cgp_variant_from_enum(item_enum: ItemEnum) -> syn::Result { let variant = ItemCgpVariant { item_enum }; - let has_fields = derive_has_fields_impls_from_enum(&variant.item_enum)?; - let extract_field = derive_extract_field_from_enum(&variant.item_enum)?; + let has_fields = variant.to_has_fields_impls()?; let from_variant_impls = variant.to_from_variant_impls()?; + let extract_field = variant.to_extract_field_items()?; Ok(quote! { - #( #has_fields )* - #extract_field #( #from_variant_impls )* + #( #has_fields )* + #( #extract_field )* }) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs b/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs index 2e27bb01..fc74fe9c 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs @@ -1,66 +1,16 @@ -use cgp_macro_core::types::cgp_data::{ - derive_extract_field_impls, derive_extractor_enum, derive_extractor_enum_ref, - derive_finalize_extract_impl, derive_has_extractor_impl, derive_has_extractor_mut_impl, - derive_has_extractor_ref_impl, derive_partial_data_impl_from_enum, -}; +use cgp_macro_core::types::cgp_data::ItemCgpVariant; use proc_macro2::TokenStream; use quote::quote; -use syn::{Ident, ItemEnum, parse2}; +use syn::{ItemEnum, parse2}; pub fn derive_extract_field(body: TokenStream) -> syn::Result { - let context_enum: ItemEnum = parse2(body)?; - derive_extract_field_from_enum(&context_enum) -} - -pub fn derive_extract_field_from_enum(context_enum: &ItemEnum) -> syn::Result { - let context_ident = &context_enum.ident; - - let extractor_ident = Ident::new(&format!("__Partial{context_ident}"), context_ident.span()); - let extractor_enum = derive_extractor_enum(context_enum, &extractor_ident)?; - - let extractor_ref_ident = Ident::new( - &format!("__PartialRef{context_ident}"), - context_ident.span(), - ); - let extractor_ref_enum = derive_extractor_enum_ref(context_enum, &extractor_ref_ident)?; - - let has_extractor_impl = derive_has_extractor_impl(context_enum, &extractor_ident)?; - - let has_extractor_ref_impl = derive_has_extractor_ref_impl(context_enum, &extractor_ref_ident)?; - - let has_extractor_mut_impl = derive_has_extractor_mut_impl(context_enum, &extractor_ref_ident)?; - - let finalize_extract_impl = - derive_finalize_extract_impl(context_enum, &extractor_ident, false)?; - - let finalize_extract_ref_impl = - derive_finalize_extract_impl(context_enum, &extractor_ref_ident, true)?; - - let partial_data_impl = - derive_partial_data_impl_from_enum(context_enum, &extractor_ident, false)?; - let partial_ref_data_impl = - derive_partial_data_impl_from_enum(context_enum, &extractor_ref_ident, true)?; - - let extractor_impls = derive_extract_field_impls(context_enum, &extractor_ident, false)?; - let extractor_ref_impls = derive_extract_field_impls(context_enum, &extractor_ref_ident, true)?; - - let out = quote! { - #extractor_enum - #extractor_ref_enum - - #partial_data_impl - #partial_ref_data_impl - - #has_extractor_impl - #has_extractor_ref_impl - #has_extractor_mut_impl + let item_enum: ItemEnum = parse2(body)?; - #finalize_extract_impl - #finalize_extract_ref_impl + let variant = ItemCgpVariant { item_enum }; - #(#extractor_impls)* - #(#extractor_ref_impls)* - }; + let items = variant.to_extract_field_items()?; - Ok(out) + Ok(quote! { + #( #items )* + }) } From 3225680d11cd5b1d69199ba9e2a9cead5b135001 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:24:38 +0200 Subject: [PATCH 18/29] Use items in entrypoints --- .../cgp-macro-core/src/types/cgp_data/item.rs | 33 +++++++++++++++++++ .../cgp-macro-core/src/types/cgp_data/mod.rs | 2 ++ .../src/types/cgp_data/record.rs | 23 +++++++++++++ .../src/types/cgp_data/variant.rs | 23 +++++++++++++ .../cgp-macro-lib/src/entrypoints/cgp_data.rs | 21 +++++------- .../src/entrypoints/cgp_record.rs | 17 +++------- .../src/entrypoints/cgp_variant.rs | 17 +++------- 7 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/types/cgp_data/item.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs new file mode 100644 index 00000000..1cb7658e --- /dev/null +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/item.rs @@ -0,0 +1,33 @@ +use syn::parse::{Parse, ParseStream}; +use syn::{Error, Item}; + +use crate::types::cgp_data::{ItemCgpRecord, ItemCgpVariant}; + +pub enum ItemCgpData { + Record(ItemCgpRecord), + Variant(ItemCgpVariant), +} + +impl ItemCgpData { + pub fn to_items(&self) -> syn::Result> { + match self { + ItemCgpData::Record(record) => record.to_items(), + ItemCgpData::Variant(variant) => variant.to_items(), + } + } +} + +impl Parse for ItemCgpData { + fn parse(input: ParseStream) -> syn::Result { + let item: Item = input.parse()?; + + match item { + Item::Struct(item_struct) => Ok(Self::Record(ItemCgpRecord { item_struct })), + Item::Enum(item_enum) => Ok(Self::Variant(ItemCgpVariant { item_enum })), + _ => Err(Error::new_spanned( + item, + "expect body to be either a struct or enum", + )), + } + } +} diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs index 237b1f6d..e5eb3941 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/mod.rs @@ -3,6 +3,7 @@ mod derive_extractor; mod derive_from_variant; mod derive_has_field; mod derive_has_fields; +mod item; mod record; mod variant; @@ -11,5 +12,6 @@ pub use derive_extractor::*; pub use derive_from_variant::*; pub use derive_has_field::*; pub use derive_has_fields::*; +pub use item::*; pub use record::*; pub use variant::*; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs index 34697e43..c4219bdf 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/record.rs @@ -1,3 +1,4 @@ +use syn::parse::{Parse, ParseStream}; use syn::{Ident, Item, ItemImpl, ItemStruct}; use crate::types::cgp_data::{ @@ -12,6 +13,20 @@ pub struct ItemCgpRecord { } impl ItemCgpRecord { + pub fn to_items(&self) -> syn::Result> { + let has_field_impls = self.to_has_field_impls()?; + let has_fields_impls = self.to_has_fields_impls()?; + let build_field_impls = self.to_build_field_items()?; + + let mut items = Vec::new(); + + items.extend(has_field_impls.into_iter().map(Item::from)); + items.extend(has_fields_impls.into_iter().map(Item::from)); + items.extend(build_field_impls); + + Ok(items) + } + pub fn to_has_field_impls(&self) -> syn::Result> { derive_has_field_impls_from_struct(&self.item_struct) } @@ -54,3 +69,11 @@ impl ItemCgpRecord { Ok(items) } } + +impl Parse for ItemCgpRecord { + fn parse(input: ParseStream) -> syn::Result { + let item_struct = input.parse()?; + + Ok(Self { item_struct }) + } +} diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs index 1a0f4ecc..ef6713e7 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs @@ -1,3 +1,4 @@ +use syn::parse::{Parse, ParseStream}; use syn::{Ident, Item, ItemEnum, ItemImpl}; use crate::types::cgp_data::{ @@ -12,6 +13,20 @@ pub struct ItemCgpVariant { } impl ItemCgpVariant { + pub fn to_items(&self) -> syn::Result> { + let has_fields = self.to_has_fields_impls()?; + let from_variant_impls = self.to_from_variant_impls()?; + let extract_field = self.to_extract_field_items()?; + + let mut items = Vec::new(); + + items.extend(has_fields.into_iter().map(Item::from)); + items.extend(from_variant_impls.into_iter().map(Item::from)); + items.extend(extract_field); + + Ok(items) + } + pub fn to_from_variant_impls(&self) -> syn::Result> { derive_from_variant_from_enum(&self.item_enum) } @@ -78,3 +93,11 @@ impl ItemCgpVariant { Ok(items) } } + +impl Parse for ItemCgpVariant { + fn parse(input: ParseStream) -> syn::Result { + let item_enum = input.parse()?; + + Ok(Self { item_enum }) + } +} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs index fec6fe73..47a31d44 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs @@ -1,17 +1,14 @@ +use cgp_macro_core::types::cgp_data::ItemCgpData; use proc_macro2::TokenStream; -use syn::{Error, Item, parse2}; - -use crate::{derive_cgp_record_from_struct, derive_cgp_variant_from_enum}; +use quote::quote; +use syn::parse2; pub fn derive_cgp_data(body: TokenStream) -> syn::Result { - let item: Item = parse2(body)?; + let data: ItemCgpData = parse2(body)?; + + let items = data.to_items()?; - match item { - Item::Struct(item_struct) => derive_cgp_record_from_struct(item_struct), - Item::Enum(item_enum) => derive_cgp_variant_from_enum(item_enum), - _ => Err(Error::new_spanned( - item, - "expect body to be either a struct or enum", - )), - } + Ok(quote! { + #( #items )* + }) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs index 72577eda..a1969b36 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs @@ -1,23 +1,14 @@ use cgp_macro_core::types::cgp_data::ItemCgpRecord; use proc_macro2::TokenStream; use quote::quote; -use syn::{ItemStruct, parse2}; +use syn::parse2; pub fn derive_cgp_record(body: TokenStream) -> syn::Result { - let item_struct = parse2(body)?; - derive_cgp_record_from_struct(item_struct) -} - -pub fn derive_cgp_record_from_struct(item_struct: ItemStruct) -> syn::Result { - let record = ItemCgpRecord { item_struct }; + let record: ItemCgpRecord = parse2(body)?; - let has_field_impls = record.to_has_field_impls()?; - let has_fields_impls = record.to_has_fields_impls()?; - let build_field_impls = record.to_build_field_items()?; + let items = record.to_items()?; Ok(quote! { - #( #has_field_impls )* - #( #has_fields_impls )* - #( #build_field_impls )* + #( #items )* }) } diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs index 30ea0633..802d2447 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs +++ b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs @@ -1,23 +1,14 @@ use cgp_macro_core::types::cgp_data::ItemCgpVariant; use proc_macro2::TokenStream; use quote::quote; -use syn::{ItemEnum, parse2}; +use syn::parse2; pub fn derive_cgp_variant(body: TokenStream) -> syn::Result { - let item_enum = parse2(body)?; - derive_cgp_variant_from_enum(item_enum) -} - -pub fn derive_cgp_variant_from_enum(item_enum: ItemEnum) -> syn::Result { - let variant = ItemCgpVariant { item_enum }; + let variant: ItemCgpVariant = parse2(body)?; - let has_fields = variant.to_has_fields_impls()?; - let from_variant_impls = variant.to_from_variant_impls()?; - let extract_field = variant.to_extract_field_items()?; + let items = variant.to_items()?; Ok(quote! { - #( #from_variant_impls )* - #( #has_fields )* - #( #extract_field )* + #( #items )* }) } From 470bd9d086214f68ffe36135f240682a5a0d64b8 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:27:13 +0200 Subject: [PATCH 19/29] Flatten macro lib --- .../src/{entrypoints => }/blanket_trait.rs | 0 .../src/{entrypoints => }/cgp_auto_getter.rs | 0 .../src/{entrypoints => }/cgp_component.rs | 0 .../src/{entrypoints => }/cgp_data.rs | 0 .../src/{entrypoints => }/cgp_fn.rs | 0 .../src/{entrypoints => }/cgp_getter.rs | 0 .../src/{entrypoints => }/cgp_impl.rs | 0 .../src/{entrypoints => }/cgp_namespace.rs | 0 .../src/{entrypoints => }/cgp_new_provider.rs | 0 .../src/{entrypoints => }/cgp_provider.rs | 0 .../src/{entrypoints => }/cgp_record.rs | 0 .../src/{entrypoints => }/cgp_type.rs | 2 - .../src/{entrypoints => }/cgp_variant.rs | 0 .../src/{entrypoints => }/check_components.rs | 0 .../delegate_and_check_components.rs | 0 .../{entrypoints => }/delegate_components.rs | 0 .../{entrypoints => }/derive_build_field.rs | 0 .../{entrypoints => }/derive_extract_field.rs | 0 .../{entrypoints => }/derive_from_variant.rs | 0 .../src/{entrypoints => }/derive_has_field.rs | 0 .../{entrypoints => }/derive_has_fields.rs | 0 .../src/entrypoints/cgp_inherit.rs | 76 ------------------- .../cgp-macro-lib/src/entrypoints/mod.rs | 51 ------------- crates/macros/cgp-macro-lib/src/lib.rs | 61 ++++++++++++--- .../src/{entrypoints => }/path.rs | 0 .../src/{entrypoints => }/product.rs | 0 .../src/{entrypoints => }/sum.rs | 0 .../src/{entrypoints => }/symbol.rs | 0 28 files changed, 50 insertions(+), 140 deletions(-) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/blanket_trait.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_auto_getter.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_component.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_data.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_fn.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_getter.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_impl.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_namespace.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_new_provider.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_provider.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_record.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_type.rs (98%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/cgp_variant.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/check_components.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/delegate_and_check_components.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/delegate_components.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/derive_build_field.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/derive_extract_field.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/derive_from_variant.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/derive_has_field.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/derive_has_fields.rs (100%) delete mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/cgp_inherit.rs delete mode 100644 crates/macros/cgp-macro-lib/src/entrypoints/mod.rs rename crates/macros/cgp-macro-lib/src/{entrypoints => }/path.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/product.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/sum.rs (100%) rename crates/macros/cgp-macro-lib/src/{entrypoints => }/symbol.rs (100%) diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/blanket_trait.rs b/crates/macros/cgp-macro-lib/src/blanket_trait.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/blanket_trait.rs rename to crates/macros/cgp-macro-lib/src/blanket_trait.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_auto_getter.rs b/crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_auto_getter.rs rename to crates/macros/cgp-macro-lib/src/cgp_auto_getter.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_component.rs b/crates/macros/cgp-macro-lib/src/cgp_component.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_component.rs rename to crates/macros/cgp-macro-lib/src/cgp_component.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs b/crates/macros/cgp-macro-lib/src/cgp_data.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_data.rs rename to crates/macros/cgp-macro-lib/src/cgp_data.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_fn.rs b/crates/macros/cgp-macro-lib/src/cgp_fn.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_fn.rs rename to crates/macros/cgp-macro-lib/src/cgp_fn.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_getter.rs b/crates/macros/cgp-macro-lib/src/cgp_getter.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_getter.rs rename to crates/macros/cgp-macro-lib/src/cgp_getter.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_impl.rs b/crates/macros/cgp-macro-lib/src/cgp_impl.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_impl.rs rename to crates/macros/cgp-macro-lib/src/cgp_impl.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_namespace.rs b/crates/macros/cgp-macro-lib/src/cgp_namespace.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_namespace.rs rename to crates/macros/cgp-macro-lib/src/cgp_namespace.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_new_provider.rs b/crates/macros/cgp-macro-lib/src/cgp_new_provider.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_new_provider.rs rename to crates/macros/cgp-macro-lib/src/cgp_new_provider.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_provider.rs b/crates/macros/cgp-macro-lib/src/cgp_provider.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_provider.rs rename to crates/macros/cgp-macro-lib/src/cgp_provider.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs b/crates/macros/cgp-macro-lib/src/cgp_record.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_record.rs rename to crates/macros/cgp-macro-lib/src/cgp_record.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs b/crates/macros/cgp-macro-lib/src/cgp_type.rs similarity index 98% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs rename to crates/macros/cgp-macro-lib/src/cgp_type.rs index d36e8a82..cef60003 100644 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_type.rs +++ b/crates/macros/cgp-macro-lib/src/cgp_type.rs @@ -1,5 +1,3 @@ -use alloc::format; - use cgp_macro_core::types::cgp_component::{CgpComponentRawArgs, ItemCgpComponent}; use cgp_macro_core::types::cgp_type::{ItemCgpType, extract_item_type_from_trait}; use proc_macro2::TokenStream; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs b/crates/macros/cgp-macro-lib/src/cgp_variant.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/cgp_variant.rs rename to crates/macros/cgp-macro-lib/src/cgp_variant.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/check_components.rs b/crates/macros/cgp-macro-lib/src/check_components.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/check_components.rs rename to crates/macros/cgp-macro-lib/src/check_components.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/delegate_and_check_components.rs b/crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/delegate_and_check_components.rs rename to crates/macros/cgp-macro-lib/src/delegate_and_check_components.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/delegate_components.rs b/crates/macros/cgp-macro-lib/src/delegate_components.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/delegate_components.rs rename to crates/macros/cgp-macro-lib/src/delegate_components.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs b/crates/macros/cgp-macro-lib/src/derive_build_field.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/derive_build_field.rs rename to crates/macros/cgp-macro-lib/src/derive_build_field.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs b/crates/macros/cgp-macro-lib/src/derive_extract_field.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/derive_extract_field.rs rename to crates/macros/cgp-macro-lib/src/derive_extract_field.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs b/crates/macros/cgp-macro-lib/src/derive_from_variant.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/derive_from_variant.rs rename to crates/macros/cgp-macro-lib/src/derive_from_variant.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs b/crates/macros/cgp-macro-lib/src/derive_has_field.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/derive_has_field.rs rename to crates/macros/cgp-macro-lib/src/derive_has_field.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs b/crates/macros/cgp-macro-lib/src/derive_has_fields.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/derive_has_fields.rs rename to crates/macros/cgp-macro-lib/src/derive_has_fields.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_inherit.rs b/crates/macros/cgp-macro-lib/src/entrypoints/cgp_inherit.rs deleted file mode 100644 index 4d375d6f..00000000 --- a/crates/macros/cgp-macro-lib/src/entrypoints/cgp_inherit.rs +++ /dev/null @@ -1,76 +0,0 @@ -use cgp_macro_core::types::generics::TypeGenerics; -use cgp_macro_core::types::ident::IdentWithTypeArgs; -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Ident, ItemImpl, ItemStruct, parse_quote, parse2}; - -pub fn cgp_inherit(attr: TokenStream, body: TokenStream) -> syn::Result { - let context_struct: ItemStruct = parse2(body)?; - - let preset: IdentWithTypeArgs = 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 - }) -} - -pub fn derive_delegate_preset( - provider_name: &Ident, - provider_generics: &Option, - preset: &IdentWithTypeArgs, -) -> syn::Result<(ItemImpl, ItemImpl)> { - let preset_name = &preset.ident; - let preset_generics = &preset.type_args; - - let provider_params = match provider_generics { - Some(generics) => { - let params = &generics.generics.params; - quote! { - , #params - } - } - None => quote! {}, - }; - - let preset_trait_name = quote! { - #preset_name :: IsPreset - }; - - let preset_provider_name = quote! { - #preset_name :: Components #preset_generics - }; - - let delegate_impl: ItemImpl = parse_quote! { - impl< __Name__ #provider_params > - DelegateComponent<__Name__> - for #provider_name #provider_generics - where - Self: #preset_trait_name < __Name__ >, - #preset_provider_name: DelegateComponent<__Name__>, - { - type Delegate = <#preset_provider_name as DelegateComponent<__Name__>>::Delegate; - } - }; - - let is_provider_impl: ItemImpl = parse_quote! { - impl<__Name__, __Context__, __Params__ #provider_params > - IsProviderFor<__Name__, __Context__, __Params__> - for #provider_name #provider_generics - where - Self: #preset_trait_name < __Name__ >, - #preset_provider_name: IsProviderFor<__Name__, __Context__, __Params__>, - { - } - }; - - Ok((delegate_impl, is_provider_impl)) -} diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs deleted file mode 100644 index c627dc19..00000000 --- a/crates/macros/cgp-macro-lib/src/entrypoints/mod.rs +++ /dev/null @@ -1,51 +0,0 @@ -mod blanket_trait; -mod cgp_auto_getter; -mod cgp_component; -mod cgp_data; -mod cgp_fn; -mod cgp_getter; -mod cgp_impl; -mod cgp_namespace; -mod cgp_new_provider; -mod cgp_provider; -mod cgp_record; -mod cgp_type; -mod cgp_variant; -mod check_components; -mod delegate_and_check_components; -mod delegate_components; -mod derive_build_field; -mod derive_extract_field; -mod derive_from_variant; -mod derive_has_field; -mod derive_has_fields; -mod path; -mod product; -mod sum; -mod symbol; - -pub use blanket_trait::*; -pub use cgp_auto_getter::*; -pub use cgp_component::*; -pub use cgp_data::*; -pub use cgp_fn::*; -pub use cgp_getter::*; -pub use cgp_impl::*; -pub use cgp_namespace::*; -pub use cgp_new_provider::*; -pub use cgp_provider::*; -pub use cgp_record::*; -pub use cgp_type::*; -pub use cgp_variant::*; -pub use check_components::*; -pub use delegate_and_check_components::*; -pub use delegate_components::*; -pub use derive_build_field::*; -pub use derive_extract_field::*; -pub use derive_from_variant::*; -pub use derive_has_field::*; -pub use derive_has_fields::*; -pub use path::*; -pub use product::*; -pub use sum::*; -pub use symbol::*; diff --git a/crates/macros/cgp-macro-lib/src/lib.rs b/crates/macros/cgp-macro-lib/src/lib.rs index b4275ced..c627dc19 100644 --- a/crates/macros/cgp-macro-lib/src/lib.rs +++ b/crates/macros/cgp-macro-lib/src/lib.rs @@ -1,12 +1,51 @@ -/*! - This is an internal crate used by the `cgp-macro` crate. We implement the - proc macros for `cgp-component` as a library, so that it can be more easily tested. - The constructs are then re-exported as proc macros in the `cgp-macro` crate, - which is defined as a proc macro crate. -*/ +mod blanket_trait; +mod cgp_auto_getter; +mod cgp_component; +mod cgp_data; +mod cgp_fn; +mod cgp_getter; +mod cgp_impl; +mod cgp_namespace; +mod cgp_new_provider; +mod cgp_provider; +mod cgp_record; +mod cgp_type; +mod cgp_variant; +mod check_components; +mod delegate_and_check_components; +mod delegate_components; +mod derive_build_field; +mod derive_extract_field; +mod derive_from_variant; +mod derive_has_field; +mod derive_has_fields; +mod path; +mod product; +mod sum; +mod symbol; -extern crate alloc; - -mod entrypoints; - -pub use crate::entrypoints::*; +pub use blanket_trait::*; +pub use cgp_auto_getter::*; +pub use cgp_component::*; +pub use cgp_data::*; +pub use cgp_fn::*; +pub use cgp_getter::*; +pub use cgp_impl::*; +pub use cgp_namespace::*; +pub use cgp_new_provider::*; +pub use cgp_provider::*; +pub use cgp_record::*; +pub use cgp_type::*; +pub use cgp_variant::*; +pub use check_components::*; +pub use delegate_and_check_components::*; +pub use delegate_components::*; +pub use derive_build_field::*; +pub use derive_extract_field::*; +pub use derive_from_variant::*; +pub use derive_has_field::*; +pub use derive_has_fields::*; +pub use path::*; +pub use product::*; +pub use sum::*; +pub use symbol::*; diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/path.rs b/crates/macros/cgp-macro-lib/src/path.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/path.rs rename to crates/macros/cgp-macro-lib/src/path.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/product.rs b/crates/macros/cgp-macro-lib/src/product.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/product.rs rename to crates/macros/cgp-macro-lib/src/product.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/sum.rs b/crates/macros/cgp-macro-lib/src/sum.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/sum.rs rename to crates/macros/cgp-macro-lib/src/sum.rs diff --git a/crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs b/crates/macros/cgp-macro-lib/src/symbol.rs similarity index 100% rename from crates/macros/cgp-macro-lib/src/entrypoints/symbol.rs rename to crates/macros/cgp-macro-lib/src/symbol.rs From ddc5b4daeb4faef83bd2a4b1738f6644e9810231 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:48:23 +0200 Subject: [PATCH 20/29] Implement snapshot_derive_has_field --- .../src/entrypoints/mod.rs | 2 + .../entrypoints/snapshot_derive_has_field.rs | 19 ++++++++++ .../cgp-macro-test-util-lib/src/keywords.rs | 4 ++ .../src/types/derive_snapshot.rs | 37 +++++++++++++++++++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + 5 files changed, 64 insertions(+) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 3ca8cda5..9536ad44 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -11,6 +11,7 @@ mod snapshot_cgp_type; mod snapshot_check_components; mod snapshot_delegate_and_check_components; mod snapshot_delegate_components; +mod snapshot_derive_has_field; pub use snapshot_blanket_trait::*; pub use snapshot_cgp_auto_getter::*; @@ -25,3 +26,4 @@ pub use snapshot_cgp_type::*; pub use snapshot_check_components::*; pub use snapshot_delegate_and_check_components::*; pub use snapshot_delegate_components::*; +pub use snapshot_derive_has_field::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs new file mode 100644 index 00000000..cd2177d5 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs @@ -0,0 +1,19 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{ItemStruct, parse2}; + +use crate::keywords::HasField; +use crate::types::DeriveMacroSnapshot; + +pub fn snapshot_derive_has_field(body: TokenStream) -> syn::Result { + let item: DeriveMacroSnapshot = parse2(body)?; + + let body = &item.body; + + let output = cgp_macro_lib::derive_has_field(quote! { + #[derive(HasField)] + #body + })?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index 54e1b3ef..934da777 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -1,5 +1,7 @@ use cgp_macro_core::define_keyword; +define_keyword!(Derive, "derive"); + define_keyword!(CgpComponent, "cgp_component"); define_keyword!(CgpAutoGetter, "cgp_auto_getter"); @@ -25,3 +27,5 @@ define_keyword!(CheckComponents, "check_components"); define_keyword!(DelegateAndCheckComponents, "delegate_and_check_components"); define_keyword!(BlanketTrait, "blanket_trait"); + +define_keyword!(HasField, "HasField"); diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs new file mode 100644 index 00000000..0d190b9b --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/derive_snapshot.rs @@ -0,0 +1,37 @@ +use core::marker::PhantomData; + +use cgp_macro_core::traits::IsKeyword; +use cgp_macro_core::types::keyword::Keyword; +use syn::parse::{Parse, ParseStream}; +use syn::parse2; +use syn::token::Pound; + +use crate::functions::parse_attribute_with_keyword; +use crate::keywords::Derive; +use crate::types::MacroSnapshot; + +pub struct DeriveMacroSnapshot { + pub body: Item, + pub snapshot: MacroSnapshot, + pub phantom: PhantomData, +} + +impl Parse for DeriveMacroSnapshot { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute_with_keyword::(input)?; + + let _keyword: Keyword = parse2(attr)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + body, + snapshot, + phantom: PhantomData, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index ffef9d53..ecdc00c4 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,7 +1,9 @@ mod attribute_snapshot; +mod derive_snapshot; mod macro_snapshot; mod statement_snapshot; pub use attribute_snapshot::*; +pub use derive_snapshot::*; pub use macro_snapshot::*; pub use statement_snapshot::*; From d6f290ceec35f4d991c1f44e1a2e1a366c065dfc Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:54:28 +0200 Subject: [PATCH 21/29] Use snapshot_derive_has_field --- .../entrypoints/snapshot_derive_has_field.rs | 8 +- crates/macros/cgp-macro-test-util/src/lib.rs | 7 ++ .../tests/cgp-tests/src/tests/async/spawn.rs | 8 +- .../cgp-tests/src/tests/check_components.rs | 16 +-- .../tests/delegate_and_check_components.rs | 8 +- .../cgp-tests/src/tests/has_field/chain.rs | 102 +++++++++++++++--- .../src/tests/use_delegate/getter.rs | 4 +- .../cgp-tests/tests/cgp_fn_tests/extend.rs | 4 +- .../tests/cgp_fn_tests/foreign_type.rs | 4 +- .../cgp_fn_tests/foreign_type_equality.rs | 8 +- .../tests/cgp_fn_tests/nested_foreign_type.rs | 8 +- .../tests/cgp_fn_tests/type_equality.rs | 4 +- .../cgp-tests/tests/cgp_fn_tests/use_type.rs | 4 +- .../tests/cgp_fn_tests/use_type_alias.rs | 4 +- .../component_tests/abstract_types/basic.rs | 4 +- .../component_tests/abstract_types/extend.rs | 4 +- .../component_tests/abstract_types/foreign.rs | 4 +- .../abstract_types/self_referential.rs | 4 +- .../component_tests/cgp_component/constant.rs | 4 +- .../component_tests/cgp_component/sized.rs | 4 +- .../getter_tests/abstract_type/explicit.rs | 4 +- .../getter_tests/abstract_type/import.rs | 4 +- .../getter_tests/abstract_type/use_type.rs | 4 +- .../cgp-tests/tests/getter_tests/clone.rs | 8 +- .../cgp-tests/tests/getter_tests/non_self.rs | 8 +- .../tests/getter_tests/non_self_auto.rs | 8 +- 26 files changed, 165 insertions(+), 84 deletions(-) diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs index cd2177d5..6b7938f9 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_field.rs @@ -15,5 +15,11 @@ pub fn snapshot_derive_has_field(body: TokenStream) -> syn::Result #body })?; - item.snapshot.wrap_output(output) + let wrapped = item.snapshot.wrap_output(output)?; + + Ok(quote! { + #body + + #wrapped + }) } diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 1fa6ca61..f6106737 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -91,3 +91,10 @@ pub fn snapshot_blanket_trait(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_derive_has_field(body: TokenStream) -> TokenStream { + entrypoints::snapshot_derive_has_field(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index 5490700f..2eadf8f6 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -118,8 +118,8 @@ snapshot_cgp_type! { impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; } @@ -129,8 +129,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") } @@ -220,8 +220,8 @@ snapshot_cgp_type! { impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; } @@ -231,8 +231,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") } diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index d4841431..6d224947 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -93,8 +93,8 @@ mod basic_check_components { impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; } @@ -104,8 +104,8 @@ mod basic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") } @@ -195,8 +195,8 @@ mod basic_check_components { impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; } @@ -206,8 +206,8 @@ mod basic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") } @@ -886,8 +886,8 @@ mod generic_check_components { impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; } @@ -897,8 +897,8 @@ mod generic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") } @@ -988,8 +988,8 @@ mod generic_check_components { impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; } @@ -999,8 +999,8 @@ mod generic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") } diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index 956e1967..1af59a03 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -91,8 +91,8 @@ mod basic_delegate_and_check_components { impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; } @@ -103,8 +103,8 @@ mod basic_delegate_and_check_components { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") } @@ -399,8 +399,8 @@ mod generic_delegate_and_check_components { impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; } @@ -411,8 +411,8 @@ mod generic_delegate_and_check_components { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") } diff --git a/crates/tests/cgp-tests/src/tests/has_field/chain.rs b/crates/tests/cgp-tests/src/tests/has_field/chain.rs index c606a256..583d3715 100644 --- a/crates/tests/cgp-tests/src/tests/has_field/chain.rs +++ b/crates/tests/cgp-tests/src/tests/has_field/chain.rs @@ -3,28 +3,96 @@ use core::marker::PhantomData; use cgp::core::field::impls::ChainGetters; use cgp::prelude::*; -#[test] -fn test_chained_getter() { - #[derive(HasField)] - pub struct Outer { - pub inner: Inner, +pub mod chained_getter { + use core::marker::PhantomData; + + use cgp::core::field::impls::ChainGetters; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_field; + + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Inner { + pub name: String, + } + + expand_inner(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>>> for Inner { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &Self::Value { + &self.name + } + } + impl HasFieldMut>>>>> + for Inner { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &mut Self::Value { + &mut self.name + } + } + ") + } } - #[derive(HasField)] - pub struct Inner { - pub name: String, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Outer { + pub inner: Inner, + } + + expand_outer(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>>>> + for Outer { + type Value = Inner; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &Self::Value { + &self.inner + } + } + impl HasFieldMut< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + > for Outer { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &mut Self::Value { + &mut self.inner + } + } + ") + } } - let context = Outer { - inner: Inner { - name: "test".to_owned(), - }, - }; + #[test] + fn test_chained_getter() { + let context = Outer { + inner: Inner { + name: "test".to_owned(), + }, + }; - let name: &String = , UseField], - >>::get_field(&context, PhantomData::<()>); - assert_eq!(name, "test"); + let name: &String = , UseField], + >>::get_field(&context, PhantomData::<()>); + assert_eq!(name, "test"); + } } #[test] diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 9a67e143..89103ba2 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -159,8 +159,8 @@ snapshot_cgp_type! { impl<__Provider__, Foo, __Context__, I, J> FooTypeProviderAt<__Context__, I, J> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, { type Foo = Foo; } @@ -173,8 +173,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs index 531546c6..0e0e0085 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs index 91d804fa..dc352848 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index bf76eb08..f2fcc157 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -86,8 +86,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -98,8 +98,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } @@ -190,8 +190,8 @@ snapshot_cgp_type! { impl<__Provider__, Types, __Context__> TypesTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, Types: HasScalarType, + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, { type Types = Types; } @@ -202,8 +202,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, Types: HasScalarType, + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs index f9669016..f72ba648 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } @@ -192,8 +192,8 @@ snapshot_cgp_type! { impl<__Provider__, Types, __Context__> TypesTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, Types:, + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, { type Types = Types; } @@ -204,8 +204,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, Types:, + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 96cbf81b..134af782 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs index 04b4abee..307f7f6b 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs @@ -89,8 +89,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Mul + Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -101,8 +101,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Mul + Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index 8e85f7c5..662ad72c 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs index 3be3ab9c..1ce36f3b 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs @@ -90,8 +90,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -102,8 +102,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs index ecd29bd3..c000aba7 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs @@ -90,8 +90,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -102,8 +102,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs index 94c983d1..2d865ff4 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs @@ -90,8 +90,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -102,8 +102,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar:, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs index 8c0dba27..a99144ac 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs @@ -88,8 +88,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Mul + Clone, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -100,8 +100,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Mul + Clone, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 85d6117a..fef211ed 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -154,8 +154,8 @@ mod generic_const { impl<__Provider__, Unit, __Context__> UnitTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, Unit:, + __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, { type Unit = Unit; } @@ -166,8 +166,8 @@ mod generic_const { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, Unit:, + __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, {} ") } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs index 7db71c9a..d2e4e9b1 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs @@ -98,8 +98,8 @@ snapshot_cgp_type! { impl<__Provider__, Foo, __Context__, T: ?Sized> ProvideFooType<__Context__, T> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, { type Foo = Foo; } @@ -110,8 +110,8 @@ snapshot_cgp_type! { T: ?Sized, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs index 5d5d5dc4..655556c5 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs @@ -86,8 +86,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -98,8 +98,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs index ecbf733a..7feed36d 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs @@ -86,8 +86,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -98,8 +98,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs index ecbf733a..7feed36d 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs @@ -86,8 +86,8 @@ snapshot_cgp_type! { impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; } @@ -98,8 +98,8 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, Scalar: Copy, + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/clone.rs b/crates/tests/cgp-tests/tests/getter_tests/clone.rs index 4355a627..3412d754 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/clone.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/clone.rs @@ -89,8 +89,8 @@ mod clone_getter { impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; } @@ -101,8 +101,8 @@ mod clone_getter { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") } @@ -401,8 +401,8 @@ mod clone_auto_getter { impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; } @@ -413,8 +413,8 @@ mod clone_auto_getter { > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, Name:, + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs index 0af7397b..e04b4f66 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs @@ -85,8 +85,8 @@ snapshot_cgp_type! { impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; } @@ -96,8 +96,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") } @@ -187,8 +187,8 @@ snapshot_cgp_type! { impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; } @@ -198,8 +198,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs index f1bdeda6..0b83ed9a 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs @@ -87,8 +87,8 @@ snapshot_cgp_type! { impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; } @@ -98,8 +98,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, Foo:, + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") } @@ -189,8 +189,8 @@ snapshot_cgp_type! { impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; } @@ -200,8 +200,8 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, Bar:, + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") } From b3b683da135e71458d93a025cf5365b7d0babb79 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 22:56:00 +0200 Subject: [PATCH 22/29] Omit empty type bounds in cgp_type --- .../cgp-macro-core/src/types/cgp_type/item.rs | 15 +++--- .../tests/cgp-tests/src/tests/async/spawn.rs | 24 ++-------- .../cgp-tests/src/tests/check_components.rs | 48 ++++--------------- .../tests/delegate_and_check_components.rs | 24 ++-------- .../src/tests/use_delegate/getter.rs | 12 +---- .../cgp-tests/tests/cgp_fn_tests/extend.rs | 12 +---- .../tests/cgp_fn_tests/foreign_type.rs | 12 +---- .../cgp_fn_tests/foreign_type_equality.rs | 12 +---- .../tests/cgp_fn_tests/nested_foreign_type.rs | 24 ++-------- .../tests/cgp_fn_tests/type_equality.rs | 12 +---- .../tests/cgp_fn_tests/use_type_alias.rs | 12 +---- .../component_tests/abstract_types/basic.rs | 12 +---- .../component_tests/abstract_types/extend.rs | 12 +---- .../component_tests/abstract_types/foreign.rs | 12 +---- .../component_tests/cgp_component/constant.rs | 12 +---- .../component_tests/cgp_component/sized.rs | 12 +---- .../cgp-tests/tests/getter_tests/clone.rs | 24 ++-------- .../cgp-tests/tests/getter_tests/non_self.rs | 24 ++-------- .../tests/getter_tests/non_self_auto.rs | 24 ++-------- 19 files changed, 63 insertions(+), 276 deletions(-) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs index 55ac1991..c6c2cd39 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -40,12 +40,15 @@ impl ItemCgpType { let mut generics = provider_trait.generics.clone(); generics.params.insert(0, parse_internal!(#type_name)); - generics - .make_where_clause() - .predicates - .push(parse_internal! { - #type_name: #type_bounds - }); + + if !type_bounds.is_empty() { + generics + .make_where_clause() + .predicates + .push(parse_internal! { + #type_name: #type_bounds + }); + } let (_, type_generics, _) = provider_trait.generics.split_for_impl(); let (impl_generics, _, where_clause) = generics.split_for_impl(); diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index 2eadf8f6..9921b3ba 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -104,21 +104,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + FooTypeProvider<__Context__>, {} - impl FooTypeProvider<__Context__> for UseType - where - Foo:, - { + impl FooTypeProvider<__Context__> for UseType { type Foo = Foo; } impl IsProviderFor - for UseType - where - Foo:, - {} + for UseType {} impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; @@ -129,7 +122,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") @@ -206,21 +198,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + BarTypeProvider<__Context__>, {} - impl BarTypeProvider<__Context__> for UseType - where - Bar:, - { + impl BarTypeProvider<__Context__> for UseType { type Bar = Bar; } impl IsProviderFor - for UseType - where - Bar:, - {} + for UseType {} impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; @@ -231,7 +216,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index 6d224947..ca8a84d6 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -79,21 +79,14 @@ mod basic_check_components { >>::Delegate: IsProviderFor + FooTypeProvider<__Context__>, {} - impl FooTypeProvider<__Context__> for UseType - where - Foo:, - { + impl FooTypeProvider<__Context__> for UseType { type Foo = Foo; } impl IsProviderFor - for UseType - where - Foo:, - {} + for UseType {} impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; @@ -104,7 +97,6 @@ mod basic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") @@ -181,21 +173,14 @@ mod basic_check_components { >>::Delegate: IsProviderFor + BarTypeProvider<__Context__>, {} - impl BarTypeProvider<__Context__> for UseType - where - Bar:, - { + impl BarTypeProvider<__Context__> for UseType { type Bar = Bar; } impl IsProviderFor - for UseType - where - Bar:, - {} + for UseType {} impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; @@ -206,7 +191,6 @@ mod basic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") @@ -872,21 +856,14 @@ mod generic_check_components { >>::Delegate: IsProviderFor + FooTypeProvider<__Context__>, {} - impl FooTypeProvider<__Context__> for UseType - where - Foo:, - { + impl FooTypeProvider<__Context__> for UseType { type Foo = Foo; } impl IsProviderFor - for UseType - where - Foo:, - {} + for UseType {} impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; @@ -897,7 +874,6 @@ mod generic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") @@ -974,21 +950,14 @@ mod generic_check_components { >>::Delegate: IsProviderFor + BarTypeProvider<__Context__>, {} - impl BarTypeProvider<__Context__> for UseType - where - Bar:, - { + impl BarTypeProvider<__Context__> for UseType { type Bar = Bar; } impl IsProviderFor - for UseType - where - Bar:, - {} + for UseType {} impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; @@ -999,7 +968,6 @@ mod generic_check_components { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index 1af59a03..30cb57f3 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -77,21 +77,14 @@ mod basic_delegate_and_check_components { >>::Delegate: IsProviderFor + NameTypeProvider<__Context__>, {} - impl NameTypeProvider<__Context__> for UseType - where - Name:, - { + impl NameTypeProvider<__Context__> for UseType { type Name = Name; } impl IsProviderFor - for UseType - where - Name:, - {} + for UseType {} impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; @@ -103,7 +96,6 @@ mod basic_delegate_and_check_components { > IsProviderFor for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") @@ -385,21 +377,14 @@ mod generic_delegate_and_check_components { >>::Delegate: IsProviderFor + NameTypeProvider<__Context__>, {} - impl NameTypeProvider<__Context__> for UseType - where - Name:, - { + impl NameTypeProvider<__Context__> for UseType { type Name = Name; } impl IsProviderFor - for UseType - where - Name:, - {} + for UseType {} impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; @@ -411,7 +396,6 @@ mod generic_delegate_and_check_components { > IsProviderFor for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 89103ba2..22568798 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -141,10 +141,7 @@ snapshot_cgp_type! { __Delegate__: IsProviderFor + FooTypeProviderAt<__Context__, I, J>, {} - impl FooTypeProviderAt<__Context__, I, J> for UseType - where - Foo:, - { + impl FooTypeProviderAt<__Context__, I, J> for UseType { type Foo = Foo; } impl< @@ -152,14 +149,10 @@ snapshot_cgp_type! { __Context__, I, J, - > IsProviderFor for UseType - where - Foo:, - {} + > IsProviderFor for UseType {} impl<__Provider__, Foo, __Context__, I, J> FooTypeProviderAt<__Context__, I, J> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, { type Foo = Foo; @@ -173,7 +166,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs index 0e0e0085..abbb729e 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs @@ -74,21 +74,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -100,7 +93,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs index dc352848..0fa7e5d8 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs @@ -74,21 +74,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -100,7 +93,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index f2fcc157..e400657c 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -72,21 +72,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -98,7 +91,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs index f72ba648..0fc3bb9c 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs @@ -74,21 +74,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -100,7 +93,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") @@ -178,21 +170,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + TypesTypeProvider<__Context__>, {} - impl TypesTypeProvider<__Context__> for UseType - where - Types:, - { + impl TypesTypeProvider<__Context__> for UseType { type Types = Types; } impl IsProviderFor - for UseType - where - Types:, - {} + for UseType {} impl<__Provider__, Types, __Context__> TypesTypeProvider<__Context__> for WithProvider<__Provider__> where - Types:, __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, { type Types = Types; @@ -204,7 +189,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Types:, __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 134af782..32deee46 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -74,21 +74,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -100,7 +93,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index 662ad72c..f74ec61e 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -74,21 +74,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -100,7 +93,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs index 1ce36f3b..240c0c73 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs @@ -76,21 +76,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -102,7 +95,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs index c000aba7..d3a65396 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs @@ -76,21 +76,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -102,7 +95,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs index 2d865ff4..eb97e401 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs @@ -76,21 +76,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ScalarTypeProvider<__Context__>, {} - impl ScalarTypeProvider<__Context__> for UseType - where - Scalar:, - { + impl ScalarTypeProvider<__Context__> for UseType { type Scalar = Scalar; } impl IsProviderFor - for UseType - where - Scalar:, - {} + for UseType {} impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, { type Scalar = Scalar; @@ -102,7 +95,6 @@ snapshot_cgp_type! { > IsProviderFor for WithProvider<__Provider__> where - Scalar:, __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, {} ") diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index fef211ed..8e5a3319 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -140,21 +140,14 @@ mod generic_const { >>::Delegate: IsProviderFor + UnitTypeProvider<__Context__>, {} - impl UnitTypeProvider<__Context__> for UseType - where - Unit:, - { + impl UnitTypeProvider<__Context__> for UseType { type Unit = Unit; } impl IsProviderFor - for UseType - where - Unit:, - {} + for UseType {} impl<__Provider__, Unit, __Context__> UnitTypeProvider<__Context__> for WithProvider<__Provider__> where - Unit:, __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, { type Unit = Unit; @@ -166,7 +159,6 @@ mod generic_const { > IsProviderFor for WithProvider<__Provider__> where - Unit:, __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, {} ") diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs index d2e4e9b1..746e1189 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs @@ -81,24 +81,17 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + ProvideFooType<__Context__, T>, {} - impl ProvideFooType<__Context__, T> for UseType - where - Foo:, - { + impl ProvideFooType<__Context__, T> for UseType { type Foo = Foo; } impl< Foo, __Context__, T: ?Sized, - > IsProviderFor for UseType - where - Foo:, - {} + > IsProviderFor for UseType {} impl<__Provider__, Foo, __Context__, T: ?Sized> ProvideFooType<__Context__, T> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, { type Foo = Foo; @@ -110,7 +103,6 @@ snapshot_cgp_type! { T: ?Sized, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, {} ") diff --git a/crates/tests/cgp-tests/tests/getter_tests/clone.rs b/crates/tests/cgp-tests/tests/getter_tests/clone.rs index 3412d754..25599ccc 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/clone.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/clone.rs @@ -75,21 +75,14 @@ mod clone_getter { >>::Delegate: IsProviderFor + NameTypeProvider<__Context__>, {} - impl NameTypeProvider<__Context__> for UseType - where - Name:, - { + impl NameTypeProvider<__Context__> for UseType { type Name = Name; } impl IsProviderFor - for UseType - where - Name:, - {} + for UseType {} impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; @@ -101,7 +94,6 @@ mod clone_getter { > IsProviderFor for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") @@ -387,21 +379,14 @@ mod clone_auto_getter { >>::Delegate: IsProviderFor + NameTypeProvider<__Context__>, {} - impl NameTypeProvider<__Context__> for UseType - where - Name:, - { + impl NameTypeProvider<__Context__> for UseType { type Name = Name; } impl IsProviderFor - for UseType - where - Name:, - {} + for UseType {} impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, { type Name = Name; @@ -413,7 +398,6 @@ mod clone_auto_getter { > IsProviderFor for WithProvider<__Provider__> where - Name:, __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, {} ") diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs index e04b4f66..3aade009 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs @@ -71,21 +71,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + FooTypeProvider<__Context__>, {} - impl FooTypeProvider<__Context__> for UseType - where - Foo:, - { + impl FooTypeProvider<__Context__> for UseType { type Foo = Foo; } impl IsProviderFor - for UseType - where - Foo:, - {} + for UseType {} impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; @@ -96,7 +89,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") @@ -173,21 +165,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + BarTypeProvider<__Context__>, {} - impl BarTypeProvider<__Context__> for UseType - where - Bar:, - { + impl BarTypeProvider<__Context__> for UseType { type Bar = Bar; } impl IsProviderFor - for UseType - where - Bar:, - {} + for UseType {} impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; @@ -198,7 +183,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs index 0b83ed9a..0fc47e79 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs @@ -73,21 +73,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + FooTypeProvider<__Context__>, {} - impl FooTypeProvider<__Context__> for UseType - where - Foo:, - { + impl FooTypeProvider<__Context__> for UseType { type Foo = Foo; } impl IsProviderFor - for UseType - where - Foo:, - {} + for UseType {} impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, { type Foo = Foo; @@ -98,7 +91,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Foo:, __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, {} ") @@ -175,21 +167,14 @@ snapshot_cgp_type! { >>::Delegate: IsProviderFor + BarTypeProvider<__Context__>, {} - impl BarTypeProvider<__Context__> for UseType - where - Bar:, - { + impl BarTypeProvider<__Context__> for UseType { type Bar = Bar; } impl IsProviderFor - for UseType - where - Bar:, - {} + for UseType {} impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, { type Bar = Bar; @@ -200,7 +185,6 @@ snapshot_cgp_type! { __Context__, > IsProviderFor for WithProvider<__Provider__> where - Bar:, __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, {} ") From 65a20d3b6c637e4a284559437bf4dc72cb9142f7 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 23:22:24 +0200 Subject: [PATCH 23/29] Move HasField tests --- crates/tests/cgp-tests/src/tests/mod.rs | 2 -- .../tests => tests/extensible_data_tests}/has_field/chain.rs | 0 .../tests => tests/extensible_data_tests}/has_field/index.rs | 0 .../tests => tests/extensible_data_tests}/has_field/life.rs | 0 .../{src/tests => tests/extensible_data_tests}/has_field/mod.rs | 0 .../extensible_data_tests}/has_fields/enum_fields.rs | 0 .../tests => tests/extensible_data_tests}/has_fields/mod.rs | 0 .../extensible_data_tests}/has_fields/struct_fields.rs | 0 crates/tests/cgp-tests/tests/extensible_data_tests/mod.rs | 2 ++ 9 files changed, 2 insertions(+), 2 deletions(-) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_field/chain.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_field/index.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_field/life.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_field/mod.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_fields/enum_fields.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_fields/mod.rs (100%) rename crates/tests/cgp-tests/{src/tests => tests/extensible_data_tests}/has_fields/struct_fields.rs (100%) diff --git a/crates/tests/cgp-tests/src/tests/mod.rs b/crates/tests/cgp-tests/src/tests/mod.rs index cfb6745f..e9213554 100644 --- a/crates/tests/cgp-tests/src/tests/mod.rs +++ b/crates/tests/cgp-tests/src/tests/mod.rs @@ -3,8 +3,6 @@ pub mod blanket_trait; pub mod check_components; pub mod compose; pub mod delegate_and_check_components; -pub mod has_field; -pub mod has_fields; pub mod monad; pub mod symbol; pub mod use_delegate; diff --git a/crates/tests/cgp-tests/src/tests/has_field/chain.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_field/chain.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs diff --git a/crates/tests/cgp-tests/src/tests/has_field/index.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_field/index.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs diff --git a/crates/tests/cgp-tests/src/tests/has_field/life.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_field/life.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs diff --git a/crates/tests/cgp-tests/src/tests/has_field/mod.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/mod.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_field/mod.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_field/mod.rs diff --git a/crates/tests/cgp-tests/src/tests/has_fields/enum_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_fields/enum_fields.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs diff --git a/crates/tests/cgp-tests/src/tests/has_fields/mod.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/mod.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_fields/mod.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/mod.rs diff --git a/crates/tests/cgp-tests/src/tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs similarity index 100% rename from crates/tests/cgp-tests/src/tests/has_fields/struct_fields.rs rename to crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/mod.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/mod.rs index 268448a9..f955c1f3 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/mod.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/mod.rs @@ -1,2 +1,4 @@ +pub mod has_field; +pub mod has_fields; pub mod records; pub mod variants; From 9c196589f14f50f3f3c0a05a4d96a937c6a92598 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 23:29:46 +0200 Subject: [PATCH 24/29] AI-migrate HasField snapshot tests --- crates/macros/cgp-macro-test-util/README.md | 53 ++- .../extensible_data_tests/has_field/chain.rs | 374 +++++++++++++++--- .../extensible_data_tests/has_field/index.rs | 40 +- .../extensible_data_tests/has_field/life.rs | 51 ++- 4 files changed, 446 insertions(+), 72 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index d007527a..92f9caee 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -5,7 +5,8 @@ Snapshot-testing macros for the CGP procedural macros. This crate exposes a family of `snapshot_*!` procedural macros that make it easy to write **golden / snapshot tests** for the code generated by the core CGP macros such as `#[cgp_component]`, `#[cgp_impl]`, `#[cgp_auto_getter]`, -`#[cgp_getter]`, `#[cgp_fn]`, and `delegate_components!`. +`#[cgp_getter]`, `#[cgp_fn]`, `#[derive(HasField)]`, and +`delegate_components!`. The snapshots are asserted using the [`insta`](https://insta.rs) crate. @@ -65,6 +66,7 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_getter!` | `#[cgp_getter]` | | `snapshot_cgp_fn!` | `#[cgp_fn]` | | `snapshot_cgp_type!` | `#[cgp_type]` | +| `snapshot_derive_has_field!`| `#[derive(HasField)]` | | `snapshot_delegate_components!` | `delegate_components!` | | `snapshot_check_components!` | `check_components!` | | `snapshot_delegate_and_check_components!` | `delegate_and_check_components!` | @@ -290,6 +292,46 @@ real macro. In addition to the usual `#[cgp_component]` output, the snapshot captures the extra `UseType` / `WithProvider` providers that `#[cgp_type]` generates. +### `snapshot_derive_has_field!` + +Wraps the `#[derive(HasField)]` derive macro. The item under test is the +`struct` definition written exactly as you would normally write it under +`#[derive(HasField)]`: + +```rust +snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Inner { + pub name: String, + } + + expand_inner(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Unlike the attribute-based snapshot macros, the derive is re-emitted verbatim +above the struct (so the real `HasField` / `HasFieldMut` impls are still +generated by the compiler), while the snapshot captures the *derived* impls, +i.e. the `HasField` and `HasFieldMut` impls that `#[derive(HasField)]` produces +for each field. + +All struct shapes accepted by `#[derive(HasField)]` are accepted, since the body +is forwarded to the real derive verbatim: + +- **named-field structs**, keyed by `Symbol!("...")` field-name tags; +- **tuple structs**, keyed by `Index` positional tags; +- **structs with lifetime parameters**, whose lifetimes are propagated to the + generated impls. + +Because the snapshot macro emits a `#[test]` function, a `#[derive(HasField)]` +struct that currently lives *inside* a test function must be lifted out before it +can be wrapped — see [Migrating existing tests](#migrating-existing-tests). The +usual pattern is to move the struct into an inner `mod` alongside the snapshot +macro, and keep the original `#[test]` in that same module so its runtime +assertions are preserved. + ### `snapshot_delegate_components!` Here the *whole* `delegate_components! { ... }` invocation is written verbatim, @@ -424,9 +466,10 @@ showing a diff you can re-accept once you've confirmed the change is intended. When migrating an existing macro test, two situations come up: - **Module-level macro use** — wrap the existing `#[cgp_component]` / `#[cgp_impl]` - / `#[cgp_getter]` / `#[cgp_auto_getter]` / `delegate_components!` in the matching - `snapshot_*!` macro and append a test block. Nothing else needs to change, - since the snapshot macro re-emits the same code. + / `#[cgp_getter]` / `#[cgp_auto_getter]` / `#[derive(HasField)]` / + `delegate_components!` in the matching `snapshot_*!` macro and append a test + block. Nothing else needs to change, since the snapshot macro re-emits the same + code. - **CGP components defined *inside* a test function** — the snapshot macro generates a `#[test]` function, which cannot be nested inside another function. @@ -442,8 +485,6 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the macros listed above. Other CGP macros - (`#[cgp_preset]`, …) are not (yet) snapshot-wrapped and are left as-is. - The pretty-printing is done with [`prettyplease`](https://crates.io/crates/prettyplease), and any macro-prelude noise is stripped beforehand diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs index 583d3715..ad150600 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/chain.rs @@ -1,8 +1,3 @@ -use core::marker::PhantomData; - -use cgp::core::field::impls::ChainGetters; -use cgp::prelude::*; - pub mod chained_getter { use core::marker::PhantomData; @@ -95,83 +90,352 @@ pub mod chained_getter { } } -#[test] -fn test_chained_getter_with_outer_life() { - #[derive(HasField)] - pub struct Outer<'a> { - pub inner: &'a Inner, +mod chained_getter_with_outer_life { + use core::marker::PhantomData; + + use cgp::core::field::impls::ChainGetters; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_field; + + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Outer<'a> { + pub inner: &'a Inner, + } + + expand_outer(output) { + insta::assert_snapshot!(output, @" + impl< + 'a, + > HasField>>>>>> + for Outer<'a> { + type Value = &'a Inner; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &Self::Value { + &self.inner + } + } + impl< + 'a, + > HasFieldMut>>>>>> + for Outer<'a> { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &mut Self::Value { + &mut self.inner + } + } + ") + } } - #[derive(HasField)] - pub struct Inner { - pub name: String, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Inner { + pub name: String, + } + + expand_inner(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>>> for Inner { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &Self::Value { + &self.name + } + } + impl HasFieldMut>>>>> + for Inner { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &mut Self::Value { + &mut self.name + } + } + ") + } } - let context = Outer { - inner: &Inner { - name: "test".to_owned(), - }, - }; + #[test] + fn test_chained_getter_with_outer_life() { + let context = Outer { + inner: &Inner { + name: "test".to_owned(), + }, + }; - let name: &String = , UseField], - >>::get_field(&context, PhantomData::<()>); - assert_eq!(name, "test"); + let name: &String = , UseField], + >>::get_field(&context, PhantomData::<()>); + assert_eq!(name, "test"); + } } -#[test] -fn test_chained_getter_with_inner_life() { - #[derive(HasField)] - pub struct Outer<'a> { - pub inner: Inner<'a>, +mod chained_getter_with_inner_life { + use core::marker::PhantomData; + + use cgp::core::field::impls::ChainGetters; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_field; + + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Outer<'a> { + pub inner: Inner<'a>, + } + + expand_outer(output) { + insta::assert_snapshot!(output, @" + impl< + 'a, + > HasField>>>>>> + for Outer<'a> { + type Value = Inner<'a>; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &Self::Value { + &self.inner + } + } + impl< + 'a, + > HasFieldMut>>>>>> + for Outer<'a> { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<5, Chars<'i', Chars<'n', Chars<'n', Chars<'e', Chars<'r', Nil>>>>>>, + >, + ) -> &mut Self::Value { + &mut self.inner + } + } + ") + } } - #[derive(HasField)] - pub struct Inner<'a> { - pub name: &'a String, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Inner<'a> { + pub name: &'a String, + } + + expand_inner(output) { + insta::assert_snapshot!(output, @" + impl<'a> HasField>>>>> + for Inner<'a> { + type Value = &'a String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &Self::Value { + &self.name + } + } + impl<'a> HasFieldMut>>>>> + for Inner<'a> { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &mut Self::Value { + &mut self.name + } + } + ") + } } - let context = Outer { - inner: Inner { - name: &"test".to_owned(), - }, - }; + #[test] + fn test_chained_getter_with_inner_life() { + let context = Outer { + inner: Inner { + name: &"test".to_owned(), + }, + }; - let name: &String = , UseField], - >>::get_field(&context, PhantomData::<()>); + let name: &String = , UseField], + >>::get_field(&context, PhantomData::<()>); - assert_eq!(name, "test"); + assert_eq!(name, "test"); + } } mod deeply_nested_getter { use cgp::core::field::impls::ChainGetters; use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_and_check_components}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_delegate_and_check_components, snapshot_derive_has_field, + }; + + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct A { + pub b: B, + } - #[derive(HasField)] - pub struct A { - pub b: B, + expand_a(output) { + insta::assert_snapshot!(output, @" + impl HasField>> for A { + type Value = B; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.b + } + } + impl HasFieldMut>> for A { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.b + } + } + ") + } } - #[derive(HasField)] - pub struct B { - pub c: C, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct B { + pub c: C, + } + + expand_b(output) { + insta::assert_snapshot!(output, @" + impl HasField>> for B { + type Value = C; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.c + } + } + impl HasFieldMut>> for B { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.c + } + } + ") + } } - #[derive(HasField)] - pub struct C { - pub d: D, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct C { + pub d: D, + } + + expand_c(output) { + insta::assert_snapshot!(output, @" + impl HasField>> for C { + type Value = D; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.d + } + } + impl HasFieldMut>> for C { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.d + } + } + ") + } } - #[derive(HasField)] - pub struct D { - pub name: String, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct D { + pub name: String, + } + + expand_d(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>>> for D { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &Self::Value { + &self.name + } + } + impl HasFieldMut>>>>> for D { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &mut Self::Value { + &mut self.name + } + } + ") + } } - #[derive(HasField)] - pub struct MyContext { - pub a: A, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct MyContext { + pub a: A, + } + + expand_my_context_struct(output) { + insta::assert_snapshot!(output, @" + impl HasField>> for MyContext { + type Value = A; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.a + } + } + impl HasFieldMut>> for MyContext { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.a + } + } + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs index 9c5d58e9..396dbf71 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/index.rs @@ -1,7 +1,43 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_has_field; -#[derive(HasField)] -pub struct Context(pub String, pub u64); +snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Context(pub String, pub u64); + + expand_context(output) { + insta::assert_snapshot!(output, @" + impl HasField> for Context { + type Value = String; + fn get_field(&self, key: ::core::marker::PhantomData>) -> &Self::Value { + &self.0 + } + } + impl HasFieldMut> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>, + ) -> &mut Self::Value { + &mut self.0 + } + } + impl HasField> for Context { + type Value = u64; + fn get_field(&self, key: ::core::marker::PhantomData>) -> &Self::Value { + &self.1 + } + } + impl HasFieldMut> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>, + ) -> &mut Self::Value { + &mut self.1 + } + } + ") + } +} pub trait CheckHasFieldImpls: HasField, Value = String> + HasField, Value = u64> diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs index 80bb2657..3dbf25f4 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_field/life.rs @@ -1,15 +1,48 @@ -use core::marker::PhantomData; +mod context_with_lifetime_field { + use core::marker::PhantomData; -use cgp::prelude::*; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_field; -#[test] -fn test_context_with_lifetime_field() { - #[derive(HasField)] - pub struct Context<'a> { - pub name: &'a str, + snapshot_derive_has_field! { + #[derive(HasField)] + pub struct Context<'a> { + pub name: &'a str, + } + + expand_context(output) { + insta::assert_snapshot!(output, @" + impl<'a> HasField>>>>> + for Context<'a> { + type Value = &'a str; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &Self::Value { + &self.name + } + } + impl<'a> HasFieldMut>>>>> + for Context<'a> { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) -> &mut Self::Value { + &mut self.name + } + } + ") + } } - let context = Context { name: "test" }; + #[test] + fn test_context_with_lifetime_field() { + let context = Context { name: "test" }; - assert_eq!(context.get_field(PhantomData), &"test"); + assert_eq!(context.get_field(PhantomData), &"test"); + } } From 44505d325872a252aa4d0340379f8c45aa131442 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 23:34:18 +0200 Subject: [PATCH 25/29] Add `snapshot_derive_has_fields!` --- .../src/entrypoints/mod.rs | 2 + .../entrypoints/snapshot_derive_has_fields.rs | 25 +++++++ .../cgp-macro-test-util-lib/src/keywords.rs | 2 + crates/macros/cgp-macro-test-util/src/lib.rs | 7 ++ .../has_fields/struct_fields.rs | 72 +++++++++++++++---- 5 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 9536ad44..cb3ee456 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -12,6 +12,7 @@ mod snapshot_check_components; mod snapshot_delegate_and_check_components; mod snapshot_delegate_components; mod snapshot_derive_has_field; +mod snapshot_derive_has_fields; pub use snapshot_blanket_trait::*; pub use snapshot_cgp_auto_getter::*; @@ -27,3 +28,4 @@ pub use snapshot_check_components::*; pub use snapshot_delegate_and_check_components::*; pub use snapshot_delegate_components::*; pub use snapshot_derive_has_field::*; +pub use snapshot_derive_has_fields::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs new file mode 100644 index 00000000..471f606e --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs @@ -0,0 +1,25 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{ItemStruct, parse2}; + +use crate::keywords::HasFields; +use crate::types::DeriveMacroSnapshot; + +pub fn snapshot_derive_has_fields(body: TokenStream) -> syn::Result { + let item: DeriveMacroSnapshot = parse2(body)?; + + let body = &item.body; + + let output = cgp_macro_lib::derive_has_fields(quote! { + #[derive(HasFields)] + #body + })?; + + let wrapped = item.snapshot.wrap_output(output)?; + + Ok(quote! { + #body + + #wrapped + }) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index 934da777..f3e1e9bb 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -29,3 +29,5 @@ define_keyword!(DelegateAndCheckComponents, "delegate_and_check_components"); define_keyword!(BlanketTrait, "blanket_trait"); define_keyword!(HasField, "HasField"); + +define_keyword!(HasFields, "HasFields"); diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index f6106737..dec5d2b8 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -98,3 +98,10 @@ pub fn snapshot_derive_has_field(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_derive_has_fields(body: TokenStream) -> TokenStream { + entrypoints::snapshot_derive_has_fields(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs index 14663aac..15df14f6 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs @@ -2,26 +2,72 @@ use core::fmt::Display; use cgp::prelude::*; -#[test] -fn test_single_named_field() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person { - pub name: String, +pub mod single_name_field { + use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person { + pub name: String, + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person { + type Fields = π< + ω>>>>, String>, + ε, + >; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = π< + ω>>>>, &'__a String>, + ε, + > + where + Self: '__a; + } + impl FromFields for Person { + fn from_fields(π(name, ε): Self::Fields) -> Self { + Self { name: name.value } + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + π(self.name.into(), ε) + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.name).into(), ε) + } + } + ") + } } - let name = "Alice".to_owned(); + #[test] + fn test_single_named_field() { - let person1 = Person { name: name.clone() }; + let name = "Alice".to_owned(); - let product = person1.clone().to_fields(); - assert_eq!(product, Cons(name.clone().into(), Nil)); + let person1 = Person { name: name.clone() }; - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, Cons((&name).into(), Nil)); + let product = person1.clone().to_fields(); + assert_eq!(product, Cons(name.clone().into(), Nil)); - let person2 = Person::from_fields(product); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, Cons((&name).into(), Nil)); - assert_eq!(person1, person2); + let person2 = Person::from_fields(product); + + assert_eq!(person1, person2); + } } #[test] From 3fd620292ac9787ddedf6601dd1e55e2f95f5f11 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Sun, 28 Jun 2026 23:50:43 +0200 Subject: [PATCH 26/29] Use fully qualified constructs --- crates/macros/cgp-macro-core/src/exports.rs | 27 +++++++++++++++++-- .../cgp_data/derive_builder/builder_struct.rs | 5 ++-- .../derive_builder/finalize_build_impl.rs | 5 ++-- .../derive_builder/has_builder_impl.rs | 5 ++-- .../derive_builder/has_field_impls.rs | 7 ++--- .../derive_builder/into_builder_impl.rs | 5 ++-- .../cgp_data/derive_builder/partial_data.rs | 5 ++-- .../derive_builder/update_field_impls.rs | 9 ++++--- .../derive_extractor/extract_field_impls.rs | 3 ++- .../derive_extractor/extractor_enum.rs | 9 ++++--- .../derive_extractor/finalize_extract_impl.rs | 7 ++--- .../derive_extractor/has_extractor_impl.rs | 17 ++++++------ .../cgp_data/derive_extractor/partial_data.rs | 7 ++--- .../cgp_data/derive_has_fields/derive_enum.rs | 5 ++-- .../derive_has_fields/derive_struct.rs | 5 ++-- .../derive_has_fields/from_fields_enum.rs | 5 ++-- .../derive_has_fields/from_fields_struct.rs | 8 +++--- .../cgp_data/derive_has_fields/product.rs | 7 ++--- .../types/cgp_data/derive_has_fields/sum.rs | 5 ++-- .../derive_has_fields/to_fields_enum.rs | 7 ++--- .../derive_has_fields/to_fields_ref_enum.rs | 3 ++- .../derive_has_fields/to_fields_ref_struct.rs | 3 ++- .../derive_has_fields/to_fields_struct.rs | 9 +++---- .../has_fields/struct_fields.rs | 3 +-- 24 files changed, 107 insertions(+), 64 deletions(-) diff --git a/crates/macros/cgp-macro-core/src/exports.rs b/crates/macros/cgp-macro-core/src/exports.rs index 7e625a52..840f31a4 100644 --- a/crates/macros/cgp-macro-core/src/exports.rs +++ b/crates/macros/cgp-macro-core/src/exports.rs @@ -8,14 +8,37 @@ export_constructs! { Chars, Symbol, Index, + Field, PathCons, ConcatPath, RedirectLookup, DelegateComponent, IsProviderFor, CanUseComponent, - HasField, - HasFieldMut, UseContext, Life, + + HasField, + HasFields, + HasFieldsRef, + HasFieldMut, + HasBuilder, + HasExtractor, + HasExtractorRef, + HasExtractorMut, + ExtractField, + IntoBuilder, + UpdateField, + ToFields, + ToFieldsRef, + FinalizeBuild, + FinalizeExtract, + PartialData, + IsPresent, + IsNothing, + IsVoid, + IsRef, + IsMut, + MapType, + MapTypeRef, } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs index 675712fb..e0b1a6ad 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{GenericParam, Ident, ItemStruct, Type, TypeParam, parse2}; +use crate::exports::MapType; use crate::types::cgp_data::index_to_generic_ident; pub fn derive_builder_struct( @@ -16,7 +17,7 @@ pub fn derive_builder_struct( let generic_param_name = index_to_generic_ident(i); let generic_param: TypeParam = parse2(quote! { - #generic_param_name : MapType + #generic_param_name : #MapType })?; generics.params.push(GenericParam::Type(generic_param)); @@ -24,7 +25,7 @@ pub fn derive_builder_struct( let field_type = &field.ty; let mapped_type: Type = parse2(quote! { - <#generic_param_name as MapType>::Map<#field_type> + <#generic_param_name as #MapType>::Map<#field_type> })?; field.ty = mapped_type; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs index 3204d869..9b01e6d6 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/finalize_build_impl.rs @@ -3,6 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, Type, parse2}; +use crate::exports::{FinalizeBuild, IsPresent}; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_finalize_build_impl( @@ -18,7 +19,7 @@ pub fn derive_finalize_build_impl( for (i, field) in context_struct.fields.iter().enumerate() { generic_args.args.push(parse2(quote! { - IsPresent + #IsPresent })?); let field_member = field_to_member(i, field); @@ -36,7 +37,7 @@ pub fn derive_finalize_build_impl( })?; let item_impl = parse2(quote! { - impl #impl_generics FinalizeBuild for #builder_type + impl #impl_generics #FinalizeBuild for #builder_type #where_clause { fn finalize_build(self) -> Self::Target { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs index 4029b283..c0476d36 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_builder_impl.rs @@ -3,6 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, parse2}; +use crate::exports::{HasBuilder, IsNothing}; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_has_builder_impl( @@ -19,7 +20,7 @@ pub fn derive_has_builder_impl( for (i, field) in context_struct.fields.iter().enumerate() { builder_generics.args.push(parse2(quote! { - IsNothing + #IsNothing })?); let field_member = field_to_member(i, field); @@ -28,7 +29,7 @@ pub fn derive_has_builder_impl( } let item_impl = parse2(quote! { - impl #impl_generics HasBuilder + impl #impl_generics #HasBuilder for #context_ident #ty_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs index b2bea077..38f4a1f2 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/has_field_impls.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Ident, ItemImpl, ItemStruct, parse2}; +use crate::exports::{HasField, IsPresent, MapType}; use crate::types::cgp_data::{ field_to_member, field_to_tag, index_to_generic_ident, to_generic_args, }; @@ -26,7 +27,7 @@ pub fn derive_has_field_impls( let generic_param_name = index_to_generic_ident(other_index); generics.params.push(parse2(quote! { - #generic_param_name: MapType + #generic_param_name: #MapType })?); source_generic_args.push(parse2(quote! { @@ -34,7 +35,7 @@ pub fn derive_has_field_impls( })?); } else { source_generic_args.push(parse2(quote! { - IsPresent + #IsPresent })?); } } @@ -42,7 +43,7 @@ pub fn derive_has_field_impls( let (impl_generics, _, where_clause) = generics.split_for_impl(); let item_impl = parse2(quote! { - impl #impl_generics HasField< #tag_type > + impl #impl_generics #HasField< #tag_type > for #builder_ident < #source_generic_args > #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs index 159c9200..1aa7d6a7 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/into_builder_impl.rs @@ -3,6 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, Ident, ItemImpl, ItemStruct, parse2}; +use crate::exports::{IntoBuilder, IsPresent}; use crate::types::cgp_data::{field_to_member, field_value_expr, to_generic_args}; pub fn derive_into_builder_impl( @@ -19,7 +20,7 @@ pub fn derive_into_builder_impl( for (i, field) in context_struct.fields.iter().enumerate() { builder_generics.args.push(parse2(quote! { - IsPresent + #IsPresent })?); let field_member = field_to_member(i, field); @@ -31,7 +32,7 @@ pub fn derive_into_builder_impl( } let item_impl = parse2(quote! { - impl #impl_generics IntoBuilder + impl #impl_generics #IntoBuilder for #context_ident #ty_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs index 05b343c2..a1b85f99 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/partial_data.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Ident, ItemImpl, ItemStruct, parse2}; +use crate::exports::{MapType, PartialData}; use crate::types::cgp_data::index_to_generic_ident; pub fn derive_partial_data_impl_from_struct( @@ -13,7 +14,7 @@ pub fn derive_partial_data_impl_from_struct( let generic_param_name = index_to_generic_ident(index); generics.params.push(parse2(quote! { - #generic_param_name: MapType + #generic_param_name: #MapType })?); } @@ -23,7 +24,7 @@ pub fn derive_partial_data_impl_from_struct( let context_generics = context_struct.generics.split_for_impl().1; let item_impl = parse2(quote! { - impl #impl_generics PartialData + impl #impl_generics #PartialData for #builder_ident #type_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs index 1d4ae9c4..778c93c9 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/update_field_impls.rs @@ -3,6 +3,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{FieldValue, GenericArgument, Ident, ItemImpl, ItemStruct, Type, parse2}; +use crate::exports::{MapType, UpdateField}; use crate::types::cgp_data::{ field_to_member, field_to_tag, field_value_expr, index_to_generic_ident, to_generic_args, }; @@ -30,7 +31,7 @@ pub fn derive_update_field_impls( let generic_param_name = index_to_generic_ident(other_index); generics.params.push(parse2(quote! { - #generic_param_name: MapType + #generic_param_name: #MapType })?); let generic_arg: GenericArgument = parse2(quote! { #generic_param_name })?; @@ -46,11 +47,11 @@ pub fn derive_update_field_impls( output_generic_args.push(parse2(quote! { __M2__ })?); generics.params.push(parse2(quote! { - __M1__: MapType + __M1__: #MapType })?); generics.params.push(parse2(quote! { - __M2__: MapType + __M2__: #MapType })?); builder_fields.push(field_value_expr(field_member, quote! { value })?); @@ -72,7 +73,7 @@ pub fn derive_update_field_impls( let member = field_to_member(current_index, current_field); let item_impl = parse2(quote! { - impl #impl_generics UpdateField< #tag_type, __M2__ > + impl #impl_generics #UpdateField< #tag_type, __M2__ > for #source_type #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs index 5bc04f99..bc514c0f 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Arm, GenericArgument, Ident, ItemEnum, ItemImpl, Type, parse2}; +use crate::exports::ExtractField; use crate::types::cgp_data::{get_variant_type, index_to_generic_ident, to_generic_args}; use crate::types::field::Symbol; @@ -95,7 +96,7 @@ pub fn derive_extract_field_impls( let (impl_generics, _, where_clause) = generics.split_for_impl(); let item_impl = parse2(quote! { - impl #impl_generics ExtractField< #tag_type > + impl #impl_generics #ExtractField< #tag_type > for #source_type #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs index 8bc1ed0c..3fa0590c 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs @@ -2,6 +2,7 @@ use proc_macro2::Span; use quote::quote; use syn::{GenericParam, Ident, ItemEnum, Lifetime, LifetimeParam, Type, TypeParam, parse2}; +use crate::exports::{MapType, MapTypeRef}; use crate::types::cgp_data::{get_variant_type, index_to_generic_ident, type_to_variant_fields}; pub fn derive_extractor_enum( @@ -74,7 +75,7 @@ pub fn derive_extractor_enum_ref( generics.params.insert( 1, parse2(quote! { - __R__: MapTypeRef + __R__: #MapTypeRef })?, ); @@ -82,7 +83,7 @@ pub fn derive_extractor_enum_ref( let generic_param_name = index_to_generic_ident(i); let generic_param: TypeParam = parse2(quote! { - #generic_param_name : MapType + #generic_param_name : #MapType })?; generics.params.push(GenericParam::Type(generic_param)); @@ -90,8 +91,8 @@ pub fn derive_extractor_enum_ref( let field_type = get_variant_type(variant)?; let mapped_type: Type = parse2(quote! { - <#generic_param_name as MapType>::Map< - <__R__ as MapTypeRef>::Map<'__a__ , #field_type > + <#generic_param_name as #MapType>::Map< + <__R__ as #MapTypeRef>::Map<'__a__ , #field_type > > })?; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs index 5ac08857..968bc69f 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/finalize_extract_impl.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, Type, parse2}; +use crate::exports::{FinalizeExtract, IsVoid, MapTypeRef}; use crate::types::cgp_data::to_generic_args; pub fn derive_finalize_extract_impl( @@ -22,7 +23,7 @@ pub fn derive_finalize_extract_impl( generics.params.insert( 0, parse2(quote! { - __R__: MapTypeRef + __R__: #MapTypeRef })?, ); } @@ -34,7 +35,7 @@ pub fn derive_finalize_extract_impl( for _variant in context_enum.variants.iter() { generic_args.args.push(parse2(quote! { - IsVoid + #IsVoid })?); } @@ -45,7 +46,7 @@ pub fn derive_finalize_extract_impl( })?; let item_impl = parse2(quote! { - impl #impl_generics FinalizeExtract for #extractor_type + impl #impl_generics #FinalizeExtract for #extractor_type #where_clause { fn finalize_extract<__T__>(self) -> __T__ { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs index 9f609403..a53300bf 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/has_extractor_impl.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Arm, Ident, ItemEnum, ItemImpl, parse2}; +use crate::exports::{HasExtractor, HasExtractorMut, HasExtractorRef, IsMut, IsPresent, IsRef}; use crate::types::cgp_data::to_generic_args; pub fn derive_has_extractor_impl( @@ -19,7 +20,7 @@ pub fn derive_has_extractor_impl( for variant in context_enum.variants.iter() { extractor_generics.args.push(parse2(quote! { - IsPresent + #IsPresent })?); let variant_ident = &variant.ident; @@ -38,7 +39,7 @@ pub fn derive_has_extractor_impl( } let item_impl = parse2(quote! { - impl #impl_generics HasExtractor + impl #impl_generics #HasExtractor for #context_ident #ty_generics #where_clause { @@ -80,7 +81,7 @@ pub fn derive_has_extractor_ref_impl( extractor_generics.args.insert( 1, parse2(quote! { - IsRef + #IsRef })?, ); @@ -88,7 +89,7 @@ pub fn derive_has_extractor_ref_impl( for variant in context_enum.variants.iter() { extractor_generics.args.push(parse2(quote! { - IsPresent + #IsPresent })?); let variant_ident = &variant.ident; @@ -101,7 +102,7 @@ pub fn derive_has_extractor_ref_impl( } let item_impl = parse2(quote! { - impl #impl_generics HasExtractorRef + impl #impl_generics #HasExtractorRef for #context_ident #ty_generics #where_clause { @@ -139,7 +140,7 @@ pub fn derive_has_extractor_mut_impl( extractor_generics.args.insert( 1, parse2(quote! { - IsMut + #IsMut })?, ); @@ -147,7 +148,7 @@ pub fn derive_has_extractor_mut_impl( for variant in context_enum.variants.iter() { extractor_generics.args.push(parse2(quote! { - IsPresent + #IsPresent })?); let variant_ident = &variant.ident; @@ -160,7 +161,7 @@ pub fn derive_has_extractor_mut_impl( } let item_impl = parse2(quote! { - impl #impl_generics HasExtractorMut + impl #impl_generics #HasExtractorMut for #context_ident #ty_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs index 5234c034..1db83a25 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/partial_data.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{Ident, ItemEnum, ItemImpl, parse2}; +use crate::exports::{MapType, MapTypeRef, PartialData}; use crate::types::cgp_data::index_to_generic_ident; pub fn derive_partial_data_impl_from_enum( @@ -21,7 +22,7 @@ pub fn derive_partial_data_impl_from_enum( generics.params.insert( 0, parse2(quote! { - __R__: MapTypeRef + __R__: #MapTypeRef })?, ); } @@ -30,7 +31,7 @@ pub fn derive_partial_data_impl_from_enum( let generic_param_name = index_to_generic_ident(index); generics.params.push(parse2(quote! { - #generic_param_name: MapType + #generic_param_name: #MapType })?); } @@ -40,7 +41,7 @@ pub fn derive_partial_data_impl_from_enum( let context_generics = context_struct.generics.split_for_impl().1; let item_impl = parse2(quote! { - impl #impl_generics PartialData + impl #impl_generics #PartialData for #builder_ident #type_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs index cf3a467a..3d495b81 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_enum.rs @@ -2,6 +2,7 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; +use crate::exports::{HasFields, HasFieldsRef}; use crate::types::cgp_data::{ derive_from_fields_for_enum, derive_to_fields_for_enum, derive_to_fields_ref_for_enum, variants_to_sum_type, @@ -18,7 +19,7 @@ pub fn derive_has_fields_impls_from_enum(item_enum: &ItemEnum) -> syn::Result syn::Result = #sum_type_ref diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs index a1fe3309..cd4c125a 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/derive_struct.rs @@ -2,6 +2,7 @@ use proc_macro2::TokenStream; use quote::quote; use syn::{ItemImpl, ItemStruct, parse2}; +use crate::exports::{HasFields, HasFieldsRef}; use crate::types::cgp_data::{ derive_from_fields_for_struct, derive_to_fields_for_struct, derive_to_fields_ref_for_struct, item_fields_to_product_type, @@ -19,7 +20,7 @@ pub fn derive_has_fields_impls_from_struct(item_struct: &ItemStruct) -> syn::Res let has_fields_impl: ItemImpl = parse2(quote! { impl #impl_generics - HasFields for #struct_name #type_generics + #HasFields for #struct_name #type_generics #where_clause { type Fields = #fields_type ; @@ -28,7 +29,7 @@ pub fn derive_has_fields_impls_from_struct(item_struct: &ItemStruct) -> syn::Res let has_fields_ref_impl: ItemImpl = parse2(quote! { impl #impl_generics - HasFieldsRef for #struct_name #type_generics + #HasFieldsRef for #struct_name #type_generics #where_clause { type FieldsRef< #life > = #fields_ref_type diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs index 566ee892..a605b145 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; +use crate::exports::Either; use crate::types::cgp_data::derive_from_field_params; pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { @@ -18,11 +19,11 @@ pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { + #Either::Left( field ) => { let #product_arg = field.value; Self:: #variant_ident #product_constructor_args } - σ::Right(rest) => { + #Either::Right(rest) => { #match_expr } } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs index d6f76257..51593ec5 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_struct.rs @@ -3,6 +3,8 @@ use quote::quote; use syn::spanned::Spanned; use syn::{Error, Fields, Ident, ItemImpl, ItemStruct, parse2}; +use crate::exports::{Cons, Nil}; + pub fn derive_from_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); @@ -28,7 +30,7 @@ pub fn derive_from_fields_for_struct(item_struct: &ItemStruct) -> syn::Result syn::Result<(TokenStream, TokenStream)> { match fields { Fields::Named(fields) => { - let mut fields_arg = quote! { ε }; + let mut fields_arg = quote! { #Nil }; let mut constructor_args = quote! {}; for field in fields.named.iter().rev() { @@ -67,7 +69,7 @@ pub fn derive_from_field_params(fields: &Fields) -> syn::Result<(TokenStream, To let field_name: Ident = Ident::new(&format!("field_{i}"), field.span()); fields_arg = quote! { - π( #field_name, #fields_arg ) + #Cons( #field_name, #fields_arg ) }; constructor_args = quote! { @@ -84,6 +86,6 @@ pub fn derive_from_field_params(fields: &Fields) -> syn::Result<(TokenStream, To )) } } - Fields::Unit => Ok((quote! { ε }, TokenStream::new())), + Fields::Unit => Ok((quote! { #Nil }, TokenStream::new())), } } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs index 6d92987e..bed3d33b 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs @@ -3,6 +3,7 @@ use quote::quote; use syn::spanned::Spanned; use syn::{Error, Fields, LitInt, Type, parse2}; +use crate::exports::{Cons, Field, Index}; use crate::types::field::Symbol; pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> syn::Result { @@ -19,7 +20,7 @@ pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> let field_type = &field.ty; fields_type = parse2(quote! { - π< ω< #field_tag, #reference #field_type >, #fields_type > + #Cons< #Field< #field_tag, #reference #field_type >, #fields_type > })?; } } @@ -33,11 +34,11 @@ pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> for (i, field) in fields.unnamed.iter().enumerate().rev() { let index = LitInt::new(&format!("{i}"), field.span()); - let field_tag = quote! { δ< #index > }; + let field_tag = quote! { #Index< #index > }; let field_type = &field.ty; fields_type = parse2(quote! { - π< ω< #field_tag, #reference #field_type >, #fields_type > + #Cons< #Field< #field_tag, #reference #field_type >, #fields_type > })?; } } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs index 2c97d9c7..22ff32ed 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs @@ -4,6 +4,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{Type, Variant, parse2}; +use crate::exports::{Either, Field}; use crate::types::cgp_data::item_fields_to_product_type; use crate::types::field::Symbol; @@ -20,8 +21,8 @@ pub fn variants_to_sum_type( let variant_fields = item_fields_to_product_type(&variant.fields, reference)?; out = quote! { - σ< - ω< #variant_symbol, #variant_fields >, + #Either< + #Field< #variant_symbol, #variant_fields >, #out, > }; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs index d2fba0f8..5c9bc335 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_enum.rs @@ -5,6 +5,7 @@ use syn::spanned::Spanned; use syn::token::Comma; use syn::{Error, Fields, Ident, ItemEnum, ItemImpl, Variant, parse2}; +use crate::exports::{Either, ToFields}; use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; pub fn derive_to_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { @@ -15,7 +16,7 @@ pub fn derive_to_fields_for_enum(item_enum: &ItemEnum) -> syn::Result let item_impl = quote! { impl #impl_generics - ToFields for #enum_name #type_generics + #ToFields for #enum_name #type_generics #where_clause { fn to_fields( @@ -58,14 +59,14 @@ pub fn derive_to_fields_match_arms( let variant_args = extract_variant_args(&variant.fields)?; let inject_variant = inject_prefix(quote! { - σ::Left( #constructor .into() ) + #Either::Left( #constructor .into() ) }); inject_prefix = Box::new(move |inner| { let outer = inject_prefix(inner); quote! { - σ::Right( #outer ) + #Either::Right( #outer ) } }); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs index 3663f9c5..2350b6c9 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_enum.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; +use crate::exports::ToFieldsRef; use crate::types::cgp_data::derive_to_fields_match_arms; pub fn derive_to_fields_ref_for_enum(item_enum: &ItemEnum) -> syn::Result { @@ -13,7 +14,7 @@ pub fn derive_to_fields_ref_for_enum(item_enum: &ItemEnum) -> syn::Result( diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs index d55d4ae8..b5f20353 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_ref_struct.rs @@ -1,6 +1,7 @@ use quote::quote; use syn::{ItemImpl, ItemStruct, Lifetime, parse_quote, parse2}; +use crate::exports::ToFieldsRef; use crate::types::cgp_data::{FieldLabel, derive_to_fields_constructor}; pub fn derive_to_fields_ref_for_struct(item_struct: &ItemStruct) -> syn::Result { @@ -21,7 +22,7 @@ pub fn derive_to_fields_ref_for_struct(item_struct: &ItemStruct) -> syn::Result< let item_impl = parse2(quote! { impl #impl_generics - ToFieldsRef for #struct_name #type_generics + #ToFieldsRef for #struct_name #type_generics #where_clause { fn to_fields_ref< #life >( diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs index 14b90ccb..34c75114 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs @@ -3,6 +3,8 @@ use quote::{ToTokens, quote}; use syn::spanned::Spanned; use syn::{Error, Fields, Ident, ItemImpl, ItemStruct, LitInt, parse2}; +use crate::exports::{Cons, ToFields}; + pub fn derive_to_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); @@ -19,7 +21,7 @@ pub fn derive_to_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { if fields.unnamed.len() == 1 { - // constructors = quote! { - // field - // } constructors = construct_field(FieldLabel::None); } else { for (i, field) in fields.unnamed.iter().enumerate().rev() { @@ -85,7 +84,7 @@ pub fn derive_to_fields_constructor( let constructor = construct_field(FieldLabel::Unnamed(field_name)); constructors = quote! { - π( + #Cons( #constructor, #constructors ) diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs index 15df14f6..368dff6e 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs @@ -4,7 +4,7 @@ use cgp::prelude::*; pub mod single_name_field { use cgp::prelude::*; -use cgp_macro_test_util::snapshot_derive_has_fields; + use cgp_macro_test_util::snapshot_derive_has_fields; snapshot_derive_has_fields! { #[derive(HasFields)] @@ -53,7 +53,6 @@ use cgp_macro_test_util::snapshot_derive_has_fields; #[test] fn test_single_named_field() { - let name = "Alice".to_owned(); let person1 = Person { name: name.clone() }; From c8add2610d56f1d131fca1b1d066485a34dfae40 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Mon, 29 Jun 2026 00:03:58 +0200 Subject: [PATCH 27/29] Implement snapshot_derive_cgp_data --- .../cgp_data/derive_builder/builder_struct.rs | 2 + .../derive_extractor/extractor_enum.rs | 4 + .../src/types/cgp_data/variant.rs | 1 + .../src/entrypoints/mod.rs | 2 + .../entrypoints/snapshot_derive_cgp_data.rs | 25 ++ .../cgp-macro-test-util-lib/src/keywords.rs | 2 + crates/macros/cgp-macro-test-util/src/lib.rs | 7 + .../has_fields/struct_fields.rs | 13 +- .../extensible_data_tests/records/basic.rs | 292 ++++++++++++++- .../extensible_data_tests/variants/basic.rs | 345 +++++++++++++++++- 10 files changed, 676 insertions(+), 17 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs index e0b1a6ad..e6bb01c9 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_builder/builder_struct.rs @@ -9,6 +9,8 @@ pub fn derive_builder_struct( builder_ident: &Ident, ) -> syn::Result { let mut builder_struct = context_struct.clone(); + + builder_struct.attrs.clear(); builder_struct.ident = builder_ident.clone(); let generics = &mut builder_struct.generics; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs index 3fa0590c..ce6e5f73 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs @@ -11,6 +11,8 @@ pub fn derive_extractor_enum( ) -> syn::Result { let mut extractor_enum = context_enum.clone(); + extractor_enum.attrs.clear(); + extractor_enum.ident = extractor_ident.clone(); let generics = &mut extractor_enum.generics; @@ -42,6 +44,8 @@ pub fn derive_extractor_enum_ref( ) -> syn::Result { let mut extractor_enum = context_enum.clone(); + extractor_enum.attrs.clear(); + extractor_enum.ident = extractor_ident.clone(); let generics = &mut extractor_enum.generics; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs index ef6713e7..0de415f0 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/variant.rs @@ -42,6 +42,7 @@ impl ItemCgpVariant { let extractor_ident = Ident::new(&format!("__Partial{context_ident}"), context_ident.span()); + let extractor_enum = derive_extractor_enum(item_enum, &extractor_ident)?; let extractor_ref_ident = Ident::new( diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index cb3ee456..ac64fa9b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -11,6 +11,7 @@ mod snapshot_cgp_type; mod snapshot_check_components; mod snapshot_delegate_and_check_components; mod snapshot_delegate_components; +mod snapshot_derive_cgp_data; mod snapshot_derive_has_field; mod snapshot_derive_has_fields; @@ -27,5 +28,6 @@ pub use snapshot_cgp_type::*; pub use snapshot_check_components::*; pub use snapshot_delegate_and_check_components::*; pub use snapshot_delegate_components::*; +pub use snapshot_derive_cgp_data::*; pub use snapshot_derive_has_field::*; pub use snapshot_derive_has_fields::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs new file mode 100644 index 00000000..71f2881c --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_cgp_data.rs @@ -0,0 +1,25 @@ +use proc_macro2::TokenStream; +use quote::quote; +use syn::{Item, parse2}; + +use crate::keywords::CgpData; +use crate::types::DeriveMacroSnapshot; + +pub fn snapshot_derive_cgp_data(body: TokenStream) -> syn::Result { + let item: DeriveMacroSnapshot = parse2(body)?; + + let body = &item.body; + + let output = cgp_macro_lib::derive_cgp_data(quote! { + #[derive(CgpData)] + #body + })?; + + let wrapped = item.snapshot.wrap_output(output)?; + + Ok(quote! { + #body + + #wrapped + }) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index f3e1e9bb..6ae0ed20 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -31,3 +31,5 @@ define_keyword!(BlanketTrait, "blanket_trait"); define_keyword!(HasField, "HasField"); define_keyword!(HasFields, "HasFields"); + +define_keyword!(CgpData, "CgpData"); diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index dec5d2b8..99dc5b79 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -105,3 +105,10 @@ pub fn snapshot_derive_has_fields(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_derive_cgp_data(body: TokenStream) -> TokenStream { + entrypoints::snapshot_derive_cgp_data(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs index 368dff6e..be95ced9 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs @@ -16,21 +16,24 @@ pub mod single_name_field { expand_person(output) { insta::assert_snapshot!(output, @" impl HasFields for Person { - type Fields = π< - ω>>>>, String>, + type Fields = Cons< + Field>>>>, String>, ε, >; } impl HasFieldsRef for Person { - type FieldsRef<'__a> = π< - ω>>>>, &'__a String>, + type FieldsRef<'__a> = Cons< + Field< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + &'__a String, + >, ε, > where Self: '__a; } impl FromFields for Person { - fn from_fields(π(name, ε): Self::Fields) -> Self { + fn from_fields(π(name, Nil): Self::Fields) -> Self { Self { name: name.value } } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs index fa93bbcc..257cac39 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs @@ -6,13 +6,293 @@ use cgp::core::field::impls::CanBuildFrom; use cgp::extra::dispatch::{BuildAndMerge, BuildAndSetField, BuildWithHandlers}; use cgp::extra::handler::{Computer, Producer, ProducerComponent}; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_delegate_components, snapshot_derive_cgp_data}; -#[derive(Debug, Eq, PartialEq, CgpData)] -pub struct FooBarBaz { - pub foo: u64, - pub bar: String, - pub baz: bool, +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, Eq, PartialEq)] + pub struct FooBarBaz { + pub foo: u64, + pub bar: String, + pub baz: bool, + } + + expand_foo_bar_baz(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>> for FooBarBaz { + type Value = u64; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl HasFieldMut>>>> for FooBarBaz { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.foo + } + } + impl HasField>>>> for FooBarBaz { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + impl HasFieldMut>>>> for FooBarBaz { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.bar + } + } + impl HasField>>>> for FooBarBaz { + type Value = bool; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &Self::Value { + &self.baz + } + } + impl HasFieldMut>>>> for FooBarBaz { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.baz + } + } + impl HasFields for FooBarBaz { + type Fields = Cons< + Field>>>, u64>, + Cons< + Field>>>, String>, + Cons>>>, bool>, ε>, + >, + >; + } + impl HasFieldsRef for FooBarBaz { + type FieldsRef<'__a> = Cons< + Field>>>, &'__a u64>, + Cons< + Field>>>, &'__a String>, + Cons< + Field>>>, &'__a bool>, + ε, + >, + >, + > + where + Self: '__a; + } + impl FromFields for FooBarBaz { + fn from_fields(π(foo, π(bar, π(baz, Nil))): Self::Fields) -> Self { + Self { + foo: foo.value, + bar: bar.value, + baz: baz.value, + } + } + } + impl ToFields for FooBarBaz { + fn to_fields(self) -> Self::Fields { + π(self.foo.into(), π(self.bar.into(), π(self.baz.into(), ε))) + } + } + impl ToFieldsRef for FooBarBaz { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.foo).into(), π((&self.bar).into(), π((&self.baz).into(), ε))) + } + } + pub struct __PartialFooBarBaz<__F0__: MapType, __F1__: MapType, __F2__: MapType> { + pub foo: <__F0__ as MapType>::Map, + pub bar: <__F1__ as MapType>::Map, + pub baz: <__F2__ as MapType>::Map, + } + impl HasBuilder for FooBarBaz { + type Builder = __PartialFooBarBaz; + fn builder() -> Self::Builder { + __PartialFooBarBaz { + foo: (), + bar: (), + baz: (), + } + } + } + impl IntoBuilder for FooBarBaz { + type Builder = __PartialFooBarBaz; + fn into_builder(self) -> Self::Builder { + __PartialFooBarBaz { + foo: self.foo, + bar: self.bar, + baz: self.baz, + } + } + } + impl<__F0__: MapType, __F1__: MapType, __F2__: MapType> PartialData + for __PartialFooBarBaz<__F0__, __F1__, __F2__> { + type Target = FooBarBaz; + } + impl FinalizeBuild for __PartialFooBarBaz { + fn finalize_build(self) -> Self::Target { + FooBarBaz { + foo: self.foo, + bar: self.bar, + baz: self.baz, + } + } + } + impl< + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + __F2__: MapType, + > UpdateField>>>, __M2__> + for __PartialFooBarBaz<__M1__, __F1__, __F2__> { + type Value = u64; + type Mapper = __M1__; + type Output = __PartialFooBarBaz<__M2__, __F1__, __F2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.foo, + __PartialFooBarBaz { + foo: value, + bar: self.bar, + baz: self.baz, + }, + ) + } + } + impl< + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + __F2__: MapType, + > UpdateField>>>, __M2__> + for __PartialFooBarBaz<__F0__, __M1__, __F2__> { + type Value = String; + type Mapper = __M1__; + type Output = __PartialFooBarBaz<__F0__, __M2__, __F2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.bar, + __PartialFooBarBaz { + foo: self.foo, + bar: value, + baz: self.baz, + }, + ) + } + } + impl< + __F0__: MapType, + __F1__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField>>>, __M2__> + for __PartialFooBarBaz<__F0__, __F1__, __M1__> { + type Value = bool; + type Mapper = __M1__; + type Output = __PartialFooBarBaz<__F0__, __F1__, __M2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.baz, + __PartialFooBarBaz { + foo: self.foo, + bar: self.bar, + baz: value, + }, + ) + } + } + impl< + __F1__: MapType, + __F2__: MapType, + > HasField>>>> + for __PartialFooBarBaz { + type Value = u64; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl< + __F0__: MapType, + __F2__: MapType, + > HasField>>>> + for __PartialFooBarBaz<__F0__, IsPresent, __F2__> { + type Value = String; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + impl< + __F0__: MapType, + __F1__: MapType, + > HasField>>>> + for __PartialFooBarBaz<__F0__, __F1__, IsPresent> { + type Value = bool; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &Self::Value { + &self.baz + } + } + ") + } } #[derive(Debug, Eq, PartialEq, CgpData)] diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs index e15fe018..25fcb5b1 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs @@ -12,14 +12,347 @@ use cgp::extra::handler::{ Computer, ComputerComponent, ComputerRef, ComputerRefComponent, PromoteAsync, }; use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_new_provider, snapshot_delegate_components}; +use cgp_macro_test_util::{ + snapshot_cgp_new_provider, snapshot_delegate_components, snapshot_derive_cgp_data, +}; use futures::executor::block_on; -#[derive(Debug, Eq, PartialEq, CgpData)] -pub enum FooBarBaz { - Foo(u64), - Bar(String), - Baz(bool), +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, Eq, PartialEq)] + pub enum FooBarBaz { + Foo(u64), + Bar(String), + Baz(bool), + } + + expand_foo_bar_baz(output) { + insta::assert_snapshot!(output, @" + impl HasFields for FooBarBaz { + type Fields = Either< + Field>>>, u64>, + Either< + Field>>>, String>, + Either>>>, bool>, θ>, + >, + >; + } + impl HasFieldsRef for FooBarBaz { + type FieldsRef<'__a> = Either< + Field>>>, &'__a u64>, + Either< + Field>>>, &'__a String>, + Either< + Field>>>, &'__a bool>, + θ, + >, + >, + > + where + Self: '__a; + } + impl FromFields for FooBarBaz { + fn from_fields(rest: Self::Fields) -> Self { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Foo(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Bar(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Baz(field) + } + Either::Right(rest) => match rest {} + } + } + } + } + } + } + } + impl ToFields for FooBarBaz { + fn to_fields(self) -> Self::Fields { + match self { + Self::Foo(field) => Either::Left(field.into()), + Self::Bar(field) => Either::Right(Either::Left(field.into())), + Self::Baz(field) => Either::Right(Either::Right(Either::Left(field.into()))), + } + } + } + impl ToFieldsRef for FooBarBaz { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + match self { + Self::Foo(field) => Either::Left(field.into()), + Self::Bar(field) => Either::Right(Either::Left(field.into())), + Self::Baz(field) => Either::Right(Either::Right(Either::Left(field.into()))), + } + } + } + impl FromVariant>>>> for FooBarBaz { + type Value = u64; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Foo(value) + } + } + impl FromVariant>>>> for FooBarBaz { + type Value = String; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Bar(value) + } + } + impl FromVariant>>>> for FooBarBaz { + type Value = bool; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Baz(value) + } + } + pub enum __PartialFooBarBaz<__F0__: MapType, __F1__: MapType, __F2__: MapType> { + Foo(<__F0__ as MapType>::Map), + Bar(<__F1__ as MapType>::Map), + Baz(<__F2__ as MapType>::Map), + } + pub enum __PartialRefFooBarBaz< + '__a__, + __R__: MapTypeRef, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > { + Foo(<__F0__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, u64>>), + Bar(<__F1__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, String>>), + Baz(<__F2__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, bool>>), + } + impl<__F0__: MapType, __F1__: MapType, __F2__: MapType> PartialData + for __PartialFooBarBaz<__F0__, __F1__, __F2__> { + type Target = FooBarBaz; + } + impl< + '__a__, + __R__: MapTypeRef, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > PartialData for __PartialRefFooBarBaz<'__a__, __R__, __F0__, __F1__, __F2__> { + type Target = FooBarBaz; + } + impl HasExtractor for FooBarBaz { + type Extractor = __PartialFooBarBaz; + fn to_extractor(self) -> Self::Extractor { + match self { + Self::Foo(value) => __PartialFooBarBaz::Foo(value), + Self::Bar(value) => __PartialFooBarBaz::Bar(value), + Self::Baz(value) => __PartialFooBarBaz::Baz(value), + } + } + fn from_extractor(extractor: Self::Extractor) -> Self { + match extractor { + __PartialFooBarBaz::Foo(value) => Self::Foo(value), + __PartialFooBarBaz::Bar(value) => Self::Bar(value), + __PartialFooBarBaz::Baz(value) => Self::Baz(value), + } + } + } + impl HasExtractorRef for FooBarBaz { + type ExtractorRef<'a> = __PartialRefFooBarBaz< + 'a, + IsRef, + IsPresent, + IsPresent, + IsPresent, + > + where + Self: 'a; + fn extractor_ref<'a>(&'a self) -> Self::ExtractorRef<'a> { + match self { + Self::Foo(value) => __PartialRefFooBarBaz::Foo(value), + Self::Bar(value) => __PartialRefFooBarBaz::Bar(value), + Self::Baz(value) => __PartialRefFooBarBaz::Baz(value), + } + } + } + impl HasExtractorMut for FooBarBaz { + type ExtractorMut<'a> = __PartialRefFooBarBaz< + 'a, + IsMut, + IsPresent, + IsPresent, + IsPresent, + > + where + Self: 'a; + fn extractor_mut<'a>(&'a mut self) -> Self::ExtractorMut<'a> { + match self { + Self::Foo(value) => __PartialRefFooBarBaz::Foo(value), + Self::Bar(value) => __PartialRefFooBarBaz::Bar(value), + Self::Baz(value) => __PartialRefFooBarBaz::Baz(value), + } + } + } + impl FinalizeExtract for __PartialFooBarBaz { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl<'a, __R__: MapTypeRef> FinalizeExtract + for __PartialRefFooBarBaz<'a, __R__, IsVoid, IsVoid, IsVoid> { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl< + __F1__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialFooBarBaz { + type Value = u64; + type Remainder = __PartialFooBarBaz; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBaz::Foo(value) => Ok(value), + __PartialFooBarBaz::Bar(value) => Err(__PartialFooBarBaz::Bar(value)), + __PartialFooBarBaz::Baz(value) => Err(__PartialFooBarBaz::Baz(value)), + } + } + } + impl< + __F0__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialFooBarBaz<__F0__, IsPresent, __F2__> { + type Value = String; + type Remainder = __PartialFooBarBaz<__F0__, IsVoid, __F2__>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBaz::Foo(value) => Err(__PartialFooBarBaz::Foo(value)), + __PartialFooBarBaz::Bar(value) => Ok(value), + __PartialFooBarBaz::Baz(value) => Err(__PartialFooBarBaz::Baz(value)), + } + } + } + impl< + __F0__: MapType, + __F1__: MapType, + > ExtractField>>>> + for __PartialFooBarBaz<__F0__, __F1__, IsPresent> { + type Value = bool; + type Remainder = __PartialFooBarBaz<__F0__, __F1__, IsVoid>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBaz::Foo(value) => Err(__PartialFooBarBaz::Foo(value)), + __PartialFooBarBaz::Bar(value) => Err(__PartialFooBarBaz::Bar(value)), + __PartialFooBarBaz::Baz(value) => Ok(value), + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + __F1__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBaz<'__a__, __R__, IsPresent, __F1__, __F2__> { + type Value = <__R__ as MapTypeRef>::Map<'__a__, u64>; + type Remainder = __PartialRefFooBarBaz<'__a__, __R__, IsVoid, __F1__, __F2__>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBaz::Foo(value) => Ok(value), + __PartialRefFooBarBaz::Bar(value) => Err(__PartialRefFooBarBaz::Bar(value)), + __PartialRefFooBarBaz::Baz(value) => Err(__PartialRefFooBarBaz::Baz(value)), + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + __F0__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBaz<'__a__, __R__, __F0__, IsPresent, __F2__> { + type Value = <__R__ as MapTypeRef>::Map<'__a__, String>; + type Remainder = __PartialRefFooBarBaz<'__a__, __R__, __F0__, IsVoid, __F2__>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBaz::Foo(value) => Err(__PartialRefFooBarBaz::Foo(value)), + __PartialRefFooBarBaz::Bar(value) => Ok(value), + __PartialRefFooBarBaz::Baz(value) => Err(__PartialRefFooBarBaz::Baz(value)), + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + __F0__: MapType, + __F1__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBaz<'__a__, __R__, __F0__, __F1__, IsPresent> { + type Value = <__R__ as MapTypeRef>::Map<'__a__, bool>; + type Remainder = __PartialRefFooBarBaz<'__a__, __R__, __F0__, __F1__, IsVoid>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBaz::Foo(value) => Err(__PartialRefFooBarBaz::Foo(value)), + __PartialRefFooBarBaz::Bar(value) => Err(__PartialRefFooBarBaz::Bar(value)), + __PartialRefFooBarBaz::Baz(value) => Ok(value), + } + } + } + ") + } } #[derive(Debug, Eq, PartialEq, CgpData)] From b5f0ca80f254825580d8763b04d8dc90ce2c7c29 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Mon, 29 Jun 2026 00:14:54 +0200 Subject: [PATCH 28/29] AI adopt `snapshot_derive_cgp_data!` in tests --- .../entrypoints/snapshot_derive_has_fields.rs | 4 +- crates/macros/cgp-macro-test-util/README.md | 97 +++ .../has_fields/enum_fields.rs | 348 ++++++++-- .../has_fields/struct_fields.rs | 432 +++++++++--- .../extensible_data_tests/records/generics.rs | 394 ++++++++++- .../extensible_data_tests/records/index.rs | 219 ++++++- .../extensible_data_tests/records/optional.rs | 200 +++++- .../extensible_data_tests/records/person.rs | 614 +++++++++++++++++- .../extensible_data_tests/records/point.rs | 174 ++++- .../extensible_data_tests/variants/generic.rs | 469 ++++++++++++- .../extensible_data_tests/variants/shape.rs | 435 ++++++++++++- 11 files changed, 3217 insertions(+), 169 deletions(-) diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs index 471f606e..388a6290 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_derive_has_fields.rs @@ -1,12 +1,12 @@ use proc_macro2::TokenStream; use quote::quote; -use syn::{ItemStruct, parse2}; +use syn::{Item, parse2}; use crate::keywords::HasFields; use crate::types::DeriveMacroSnapshot; pub fn snapshot_derive_has_fields(body: TokenStream) -> syn::Result { - let item: DeriveMacroSnapshot = parse2(body)?; + let item: DeriveMacroSnapshot = parse2(body)?; let body = &item.body; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index 92f9caee..3ecbf08f 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -67,6 +67,8 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_fn!` | `#[cgp_fn]` | | `snapshot_cgp_type!` | `#[cgp_type]` | | `snapshot_derive_has_field!`| `#[derive(HasField)]` | +| `snapshot_derive_has_fields!`| `#[derive(HasFields)]` | +| `snapshot_derive_cgp_data!` | `#[derive(CgpData)]` | | `snapshot_delegate_components!` | `delegate_components!` | | `snapshot_check_components!` | `check_components!` | | `snapshot_delegate_and_check_components!` | `delegate_and_check_components!` | @@ -332,6 +334,101 @@ usual pattern is to move the struct into an inner `mod` alongside the snapshot macro, and keep the original `#[test]` in that same module so its runtime assertions are preserved. +### `snapshot_derive_has_fields!` + +Wraps the `#[derive(HasFields)]` derive macro. The item under test is the type +definition written exactly as you would normally write it under +`#[derive(HasFields)]`, with any other derives kept alongside it: + +```rust +snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person { + pub name: String, + } + + expand_person(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Like the other derive snapshot macros, the type is re-emitted verbatim with its +derives (so the compiler still generates the real impls), while the snapshot +captures the `HasFields` / `HasFieldsRef` / `FromFields` / `ToFields` / +`ToFieldsRef` impls that `#[derive(HasFields)]` produces. + +Both **`struct`s** and **`enum`s** are accepted: + +- For a **`struct`** (a *record*), the field list is a product type + (`Cons` / `Nil`), and the conversions destructure/build the struct fields. +- For an **`enum`** (a *variant*), the field list is a sum type + (`Either` / `Void`), and the conversions `match` over the variants. + +Generic type parameters and lifetimes are propagated to the generated impls. +As with the other derive snapshot macros, a `#[derive(HasFields)]` type that +currently lives *inside* a test function must be lifted out before it can be +wrapped — see [Migrating existing tests](#migrating-existing-tests). The usual +pattern is to move each type into its own inner `mod` alongside the snapshot +macro, and keep the original `#[test]` in that same module so its runtime +assertions are preserved. + +### `snapshot_derive_cgp_data!` + +Wraps the `#[derive(CgpData)]` derive macro. `CgpData` is the umbrella derive for +extensible data types: rather than a single trait, it generates the *entire* +field/variant toolkit for a `struct` or `enum`. The item under test is the type +definition written exactly as you would normally write it under +`#[derive(CgpData)]`, with any other derives kept alongside it: + +```rust +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, Eq, PartialEq)] + pub struct FooBarBaz { + pub foo: u64, + pub bar: String, + pub baz: bool, + } + + expand_foo_bar_baz(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Like `snapshot_derive_has_field!`, the type is re-emitted verbatim with its +derives (so the compiler still generates the real impls), while the snapshot +captures the *derived* impls that `#[derive(CgpData)]` produces. Because +`CgpData` generates a large amount of code, these snapshots are correspondingly +large — but that is precisely what makes them valuable as golden tests. + +What gets captured depends on whether the item is a `struct` (a *record*) or an +`enum` (a *variant*): + +- For a **record `struct`**, the snapshot covers the per-field `HasField` / + `HasFieldMut` impls, the `HasFields` / `HasFieldsRef` field-list impls, the + `FromFields` / `ToFields` / `ToFieldsRef` conversions, and the generated + `__Partial*` builder struct together with its `HasBuilder` / `IntoBuilder` / + `PartialData` / `FinalizeBuild` / `UpdateField` impls. +- For a **variant `enum`**, the snapshot covers the `HasFields` / + `HasFieldsRef` impls, the `FromFields` / `ToFields` / `ToFieldsRef` + conversions, the per-variant `FromVariant` impls, the generated `__Partial*` + / `__PartialRef*` enums, and the `HasExtractor` / `HasExtractorRef` / + `HasExtractorMut` / `FinalizeExtract` / `ExtractField` extractor impls. + +All shapes accepted by `#[derive(CgpData)]` are accepted, since the body is +forwarded to the real derive verbatim — including generic type parameters (with +`where` clauses), tuple structs keyed by `Index`, and generic enums. + +As with the other derive snapshot macros, a `#[derive(CgpData)]` type that +currently lives *inside* a test function must be lifted out before it can be +wrapped — see [Migrating existing tests](#migrating-existing-tests). When several +auxiliary types share a file, the usual convention is to wrap only the primary +type under test in `snapshot_derive_cgp_data!`, and leave the auxiliary fixture +types as plain `#[derive(CgpData)]` definitions. + ### `snapshot_delegate_components!` Here the *whole* `delegate_components! { ... }` invocation is written verbatim, diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs index acf01ca0..1db917c9 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs @@ -1,75 +1,323 @@ -use cgp::prelude::*; - -#[test] -fn test_simple_enum() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub enum Person { - Anonymous(u32), - Named(String), +pub mod simple_enum { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub enum Person { + Anonymous(u32), + Named(String), + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person { + type Fields = Either< + Field< + Symbol< + 9, + Chars< + 'A', + Chars< + 'n', + Chars< + 'o', + Chars< + 'n', + Chars< + 'y', + Chars<'m', Chars<'o', Chars<'u', Chars<'s', Nil>>>>, + >, + >, + >, + >, + >, + >, + u32, + >, + Either< + Field< + Symbol< + 5, + Chars<'N', Chars<'a', Chars<'m', Chars<'e', Chars<'d', Nil>>>>>, + >, + String, + >, + θ, + >, + >; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = Either< + Field< + Symbol< + 9, + Chars< + 'A', + Chars< + 'n', + Chars< + 'o', + Chars< + 'n', + Chars< + 'y', + Chars<'m', Chars<'o', Chars<'u', Chars<'s', Nil>>>>, + >, + >, + >, + >, + >, + >, + &'__a u32, + >, + Either< + Field< + Symbol< + 5, + Chars<'N', Chars<'a', Chars<'m', Chars<'e', Chars<'d', Nil>>>>>, + >, + &'__a String, + >, + θ, + >, + > + where + Self: '__a; + } + impl FromFields for Person { + fn from_fields(rest: Self::Fields) -> Self { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Anonymous(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Named(field) + } + Either::Right(rest) => match rest {} + } + } + } + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + match self { + Self::Anonymous(field) => Either::Left(field.into()), + Self::Named(field) => Either::Right(Either::Left(field.into())), + } + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + match self { + Self::Anonymous(field) => Either::Left(field.into()), + Self::Named(field) => Either::Right(Either::Left(field.into())), + } + } + } + ") + } } - { - let person_a1 = Person::Anonymous(42); + #[test] + fn test_simple_enum() { + { + let person_a1 = Person::Anonymous(42); - let person_a2 = person_a1.clone().to_fields(); - assert_eq!(person_a2, Either::Left(42.into())); + let person_a2 = person_a1.clone().to_fields(); + assert_eq!(person_a2, Either::Left(42.into())); - let person_a3 = Person::from_fields(person_a2); - assert_eq!(person_a3, person_a1); + let person_a3 = Person::from_fields(person_a2); + assert_eq!(person_a3, person_a1); - let person_a4 = person_a1.to_fields_ref(); - assert_eq!(person_a4, Either::Left((&42).into())); - } + let person_a4 = person_a1.to_fields_ref(); + assert_eq!(person_a4, Either::Left((&42).into())); + } - { - let name = "Alice".to_owned(); + { + let name = "Alice".to_owned(); - let person_b1 = Person::Named(name.clone()); + let person_b1 = Person::Named(name.clone()); - let person_b2 = person_b1.clone().to_fields(); - assert_eq!(person_b2, Either::Right(Either::Left(name.clone().into()))); + let person_b2 = person_b1.clone().to_fields(); + assert_eq!(person_b2, Either::Right(Either::Left(name.clone().into()))); - let person_b3 = Person::from_fields(person_b2); - assert_eq!(person_b3, person_b1); + let person_b3 = Person::from_fields(person_b2); + assert_eq!(person_b3, person_b1); - let person_b4 = person_b1.to_fields_ref(); - assert_eq!(person_b4, Either::Right(Either::Left((&name).into()))); + let person_b4 = person_b1.to_fields_ref(); + assert_eq!(person_b4, Either::Right(Either::Left((&name).into()))); + } } } -#[test] -fn test_generic_enum() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub enum Person<'a, Name> { - Anonymous(u32), - Named(&'a Name), +pub mod generic_enum { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub enum Person<'a, Name> { + Anonymous(u32), + Named(&'a Name), + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl<'a, Name> HasFields for Person<'a, Name> { + type Fields = Either< + Field< + Symbol< + 9, + Chars< + 'A', + Chars< + 'n', + Chars< + 'o', + Chars< + 'n', + Chars< + 'y', + Chars<'m', Chars<'o', Chars<'u', Chars<'s', Nil>>>>, + >, + >, + >, + >, + >, + >, + u32, + >, + Either< + Field< + Symbol< + 5, + Chars<'N', Chars<'a', Chars<'m', Chars<'e', Chars<'d', Nil>>>>>, + >, + &'a Name, + >, + θ, + >, + >; + } + impl<'a, Name> HasFieldsRef for Person<'a, Name> { + type FieldsRef<'__a> = Either< + Field< + Symbol< + 9, + Chars< + 'A', + Chars< + 'n', + Chars< + 'o', + Chars< + 'n', + Chars< + 'y', + Chars<'m', Chars<'o', Chars<'u', Chars<'s', Nil>>>>, + >, + >, + >, + >, + >, + >, + &'__a u32, + >, + Either< + Field< + Symbol< + 5, + Chars<'N', Chars<'a', Chars<'m', Chars<'e', Chars<'d', Nil>>>>>, + >, + &'__a &'a Name, + >, + θ, + >, + > + where + Self: '__a; + } + impl<'a, Name> FromFields for Person<'a, Name> { + fn from_fields(rest: Self::Fields) -> Self { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Anonymous(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Named(field) + } + Either::Right(rest) => match rest {} + } + } + } + } + } + impl<'a, Name> ToFields for Person<'a, Name> { + fn to_fields(self) -> Self::Fields { + match self { + Self::Anonymous(field) => Either::Left(field.into()), + Self::Named(field) => Either::Right(Either::Left(field.into())), + } + } + } + impl<'a, Name> ToFieldsRef for Person<'a, Name> { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + match self { + Self::Anonymous(field) => Either::Left(field.into()), + Self::Named(field) => Either::Right(Either::Left(field.into())), + } + } + } + ") + } } - { - let person_a1: Person = Person::Anonymous(42); + #[test] + fn test_generic_enum() { + { + let person_a1: Person = Person::Anonymous(42); - let person_a2 = person_a1.clone().to_fields(); - assert_eq!(person_a2, Either::Left(42.into())); + let person_a2 = person_a1.clone().to_fields(); + assert_eq!(person_a2, Either::Left(42.into())); - let person_a3 = Person::from_fields(person_a2); - assert_eq!(person_a3, person_a1); + let person_a3 = Person::from_fields(person_a2); + assert_eq!(person_a3, person_a1); - let person_a4 = person_a1.to_fields_ref(); - assert_eq!(person_a4, Either::Left((&42).into())); - } + let person_a4 = person_a1.to_fields_ref(); + assert_eq!(person_a4, Either::Left((&42).into())); + } - { - let name = "Alice".to_owned(); + { + let name = "Alice".to_owned(); - let person_b1 = Person::Named(&name); + let person_b1 = Person::Named(&name); - let person_b2 = person_b1.clone().to_fields(); - assert_eq!(person_b2, Either::Right(Either::Left((&name).into()))); + let person_b2 = person_b1.clone().to_fields(); + assert_eq!(person_b2, Either::Right(Either::Left((&name).into()))); - let person_b3 = Person::from_fields(person_b2); - assert_eq!(person_b3, person_b1); + let person_b3 = Person::from_fields(person_b2); + assert_eq!(person_b3, person_b1); - let person_b4 = person_b1.to_fields_ref(); - assert_eq!(person_b4, Either::Right(Either::Left((&&name).into()))); + let person_b4 = person_b1.to_fields_ref(); + assert_eq!(person_b4, Either::Right(Either::Left((&&name).into()))); + } } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs index be95ced9..6038af45 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs @@ -1,7 +1,3 @@ -use core::fmt::Display; - -use cgp::prelude::*; - pub mod single_name_field { use cgp::prelude::*; use cgp_macro_test_util::snapshot_derive_has_fields; @@ -72,126 +68,392 @@ pub mod single_name_field { } } -#[test] -fn test_two_named_field() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person { - pub name: String, - pub age: u8, +pub mod two_named_field { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person { + pub name: String, + pub age: u8, + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person { + type Fields = Cons< + Field>>>>, String>, + Cons>>>, u8>, ε>, + >; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = Cons< + Field< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + &'__a String, + >, + Cons>>>, &'__a u8>, ε>, + > + where + Self: '__a; + } + impl FromFields for Person { + fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + Self { + name: name.value, + age: age.value, + } + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + π(self.name.into(), π(self.age.into(), ε)) + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.name).into(), π((&self.age).into(), ε)) + } + } + ") + } } - let name = "Alice".to_owned(); + #[test] + fn test_two_named_field() { + let name = "Alice".to_owned(); - let person1 = Person { - name: name.clone(), - age: 32, - }; + let person1 = Person { + name: name.clone(), + age: 32, + }; - let product = person1.clone().to_fields(); - assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); + let product = person1.clone().to_fields(); + assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); - let person2 = Person::from_fields(product); + let person2 = Person::from_fields(product); - assert_eq!(person1, person2); + assert_eq!(person1, person2); + } } -#[test] -fn test_generic_struct() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person - where - Name: Display, - { - pub name: Name, - pub age: u8, +pub mod generic_struct { + use core::fmt::Display; + + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person + where + Name: Display, + { + pub name: Name, + pub age: u8, + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person + where + Name: Display, + { + type Fields = Cons< + Field>>>>, Name>, + Cons>>>, u8>, ε>, + >; + } + impl HasFieldsRef for Person + where + Name: Display, + { + type FieldsRef<'__a> = Cons< + Field< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + &'__a Name, + >, + Cons>>>, &'__a u8>, ε>, + > + where + Self: '__a; + } + impl FromFields for Person + where + Name: Display, + { + fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + Self { + name: name.value, + age: age.value, + } + } + } + impl ToFields for Person + where + Name: Display, + { + fn to_fields(self) -> Self::Fields { + π(self.name.into(), π(self.age.into(), ε)) + } + } + impl ToFieldsRef for Person + where + Name: Display, + { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.name).into(), π((&self.age).into(), ε)) + } + } + ") + } } - let name = "Alice".to_owned(); + #[test] + fn test_generic_struct() { + let name = "Alice".to_owned(); - let person1 = Person { - name: name.clone(), - age: 32, - }; + let person1 = Person { + name: name.clone(), + age: 32, + }; - let product = person1.clone().to_fields(); - assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); + let product = person1.clone().to_fields(); + assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); - let person2 = Person::from_fields(product); + let person2 = Person::from_fields(product); - assert_eq!(person1, person2); + assert_eq!(person1, person2); + } } -#[test] -fn test_generic_lifetime_struct() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person<'a, Name> - where - Name: Display, - { - pub name: &'a Name, - pub age: &'a u8, +pub mod generic_lifetime_struct { + use core::fmt::Display; + + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; + + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person<'a, Name> + where + Name: Display, + { + pub name: &'a Name, + pub age: &'a u8, + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl<'a, Name> HasFields for Person<'a, Name> + where + Name: Display, + { + type Fields = Cons< + Field>>>>, &'a Name>, + Cons>>>, &'a u8>, ε>, + >; + } + impl<'a, Name> HasFieldsRef for Person<'a, Name> + where + Name: Display, + { + type FieldsRef<'__a> = Cons< + Field< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + &'__a &'a Name, + >, + Cons>>>, &'__a &'a u8>, ε>, + > + where + Self: '__a; + } + impl<'a, Name> FromFields for Person<'a, Name> + where + Name: Display, + { + fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + Self { + name: name.value, + age: age.value, + } + } + } + impl<'a, Name> ToFields for Person<'a, Name> + where + Name: Display, + { + fn to_fields(self) -> Self::Fields { + π(self.name.into(), π(self.age.into(), ε)) + } + } + impl<'a, Name> ToFieldsRef for Person<'a, Name> + where + Name: Display, + { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.name).into(), π((&self.age).into(), ε)) + } + } + ") + } } - let name = "Alice".to_owned(); + #[test] + fn test_generic_lifetime_struct() { + let name = "Alice".to_owned(); - let person1 = Person { - name: &name, - age: &32, - }; + let person1 = Person { + name: &name, + age: &32, + }; - let product = person1.clone().to_fields(); - assert_eq!(product, Cons((&name).into(), Cons((&32).into(), Nil))); + let product = person1.clone().to_fields(); + assert_eq!(product, Cons((&name).into(), Cons((&32).into(), Nil))); - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, Cons((&&name).into(), Cons((&&32).into(), Nil))); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, Cons((&&name).into(), Cons((&&32).into(), Nil))); - let person2 = Person::from_fields(product); + let person2 = Person::from_fields(product); - assert_eq!(person1, person2); + assert_eq!(person1, person2); + } } -#[test] -fn test_single_unnamed_field() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person(String); +pub mod single_unnamed_field { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; - let name = "Alice".to_owned(); + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person(String); - let person1 = Person(name.clone()); + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person { + type Fields = String; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = &'__a String where Self: '__a; + } + impl FromFields for Person { + fn from_fields(field: Self::Fields) -> Self { + Self(field) + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + self.0 + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + &self.0 + } + } + ") + } + } + + #[test] + fn test_single_unnamed_field() { + let name = "Alice".to_owned(); + + let person1 = Person(name.clone()); - let product = person1.clone().to_fields(); - assert_eq!(product, name.clone()); + let product = person1.clone().to_fields(); + assert_eq!(product, name.clone()); - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, &name); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, &name); - let person2 = Person::from_fields(product); + let person2 = Person::from_fields(product); - assert_eq!(person1, person2); + assert_eq!(person1, person2); + } } -#[test] -fn test_single_unnamed_multi_field() { - #[derive(Clone, Debug, Eq, PartialEq, HasFields)] - pub struct Person(String, u8); +pub mod single_unnamed_multi_field { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_derive_has_fields; - let name = "Alice".to_owned(); + snapshot_derive_has_fields! { + #[derive(HasFields)] + #[derive(Clone, Debug, Eq, PartialEq)] + pub struct Person(String, u8); - let person1 = Person(name.clone(), 32); + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Person { + type Fields = Cons, String>, Cons, u8>, ε>>; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = Cons< + Field, &'__a String>, + Cons, &'__a u8>, ε>, + > + where + Self: '__a; + } + impl FromFields for Person { + fn from_fields(Cons(field_1, Cons(field_0, ε)): Self::Fields) -> Self { + Self(field_1.value, field_0.value) + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + Cons(self.0.into(), Cons(self.1.into(), ε)) + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + Cons((&self.0).into(), Cons((&self.1).into(), ε)) + } + } + ") + } + } - let product = person1.clone().to_fields(); - assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); + #[test] + fn test_single_unnamed_multi_field() { + let name = "Alice".to_owned(); - let product_ref = person1.to_fields_ref(); - assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); + let person1 = Person(name.clone(), 32); - let person2 = Person::from_fields(product); + let product = person1.clone().to_fields(); + assert_eq!(product, Cons(name.clone().into(), Cons(32.into(), Nil))); - assert_eq!(person1, person2); + let product_ref = person1.to_fields_ref(); + assert_eq!(product_ref, Cons((&name).into(), Cons((&32).into(), Nil))); + + let person2 = Person::from_fields(product); + + assert_eq!(person1, person2); + } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs index 4bc1be53..43fd78ec 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs @@ -1,11 +1,389 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(CgpData)] -pub struct Context -where - Foo: Clone, -{ - pub foo: Foo, - pub bar: Bar, - pub baz: Baz, +snapshot_derive_cgp_data! { + #[derive(CgpData)] + pub struct Context + where + Foo: Clone, + { + pub foo: Foo, + pub bar: Bar, + pub baz: Baz, + } + + expand_context(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>> + for Context + where + Foo: Clone, + { + type Value = Foo; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl HasFieldMut>>>> + for Context + where + Foo: Clone, + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.foo + } + } + impl HasField>>>> + for Context + where + Foo: Clone, + { + type Value = Bar; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + impl HasFieldMut>>>> + for Context + where + Foo: Clone, + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.bar + } + } + impl HasField>>>> + for Context + where + Foo: Clone, + { + type Value = Baz; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &Self::Value { + &self.baz + } + } + impl HasFieldMut>>>> + for Context + where + Foo: Clone, + { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.baz + } + } + impl HasFields for Context + where + Foo: Clone, + { + type Fields = Cons< + Field>>>, Foo>, + Cons< + Field>>>, Bar>, + Cons>>>, Baz>, ε>, + >, + >; + } + impl HasFieldsRef for Context + where + Foo: Clone, + { + type FieldsRef<'__a> = Cons< + Field>>>, &'__a Foo>, + Cons< + Field>>>, &'__a Bar>, + Cons< + Field>>>, &'__a Baz>, + ε, + >, + >, + > + where + Self: '__a; + } + impl FromFields for Context + where + Foo: Clone, + { + fn from_fields(π(foo, π(bar, π(baz, Nil))): Self::Fields) -> Self { + Self { + foo: foo.value, + bar: bar.value, + baz: baz.value, + } + } + } + impl ToFields for Context + where + Foo: Clone, + { + fn to_fields(self) -> Self::Fields { + π(self.foo.into(), π(self.bar.into(), π(self.baz.into(), ε))) + } + } + impl ToFieldsRef for Context + where + Foo: Clone, + { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.foo).into(), π((&self.bar).into(), π((&self.baz).into(), ε))) + } + } + pub struct __PartialContext< + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > + where + Foo: Clone, + { + pub foo: <__F0__ as MapType>::Map, + pub bar: <__F1__ as MapType>::Map, + pub baz: <__F2__ as MapType>::Map, + } + impl HasBuilder for Context + where + Foo: Clone, + { + type Builder = __PartialContext; + fn builder() -> Self::Builder { + __PartialContext { + foo: (), + bar: (), + baz: (), + } + } + } + impl IntoBuilder for Context + where + Foo: Clone, + { + type Builder = __PartialContext; + fn into_builder(self) -> Self::Builder { + __PartialContext { + foo: self.foo, + bar: self.bar, + baz: self.baz, + } + } + } + impl PartialData + for __PartialContext + where + Foo: Clone, + { + type Target = Context; + } + impl FinalizeBuild + for __PartialContext + where + Foo: Clone, + { + fn finalize_build(self) -> Self::Target { + Context { + foo: self.foo, + bar: self.bar, + baz: self.baz, + } + } + } + impl< + Foo, + Bar, + Baz, + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + __F2__: MapType, + > UpdateField>>>, __M2__> + for __PartialContext + where + Foo: Clone, + { + type Value = Foo; + type Mapper = __M1__; + type Output = __PartialContext; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.foo, + __PartialContext { + foo: value, + bar: self.bar, + baz: self.baz, + }, + ) + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + __F2__: MapType, + > UpdateField>>>, __M2__> + for __PartialContext + where + Foo: Clone, + { + type Value = Bar; + type Mapper = __M1__; + type Output = __PartialContext; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.bar, + __PartialContext { + foo: self.foo, + bar: value, + baz: self.baz, + }, + ) + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField>>>, __M2__> + for __PartialContext + where + Foo: Clone, + { + type Value = Baz; + type Mapper = __M1__; + type Output = __PartialContext; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.baz, + __PartialContext { + foo: self.foo, + bar: self.bar, + baz: value, + }, + ) + } + } + impl< + Foo, + Bar, + Baz, + __F1__: MapType, + __F2__: MapType, + > HasField>>>> + for __PartialContext + where + Foo: Clone, + { + type Value = Foo; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __F2__: MapType, + > HasField>>>> + for __PartialContext + where + Foo: Clone, + { + type Value = Bar; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + > HasField>>>> + for __PartialContext + where + Foo: Clone, + { + type Value = Baz; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> &Self::Value { + &self.baz + } + } + ") + } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs index 681ea680..8fed369e 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs @@ -1,4 +1,219 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(CgpData)] -pub struct Context(pub u64, pub String, pub bool); +snapshot_derive_cgp_data! { + #[derive(CgpData)] + pub struct Context(pub u64, pub String, pub bool); + + expand_context(output) { + insta::assert_snapshot!(output, @" + impl HasField> for Context { + type Value = u64; + fn get_field(&self, key: ::core::marker::PhantomData>) -> &Self::Value { + &self.0 + } + } + impl HasFieldMut> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>, + ) -> &mut Self::Value { + &mut self.0 + } + } + impl HasField> for Context { + type Value = String; + fn get_field(&self, key: ::core::marker::PhantomData>) -> &Self::Value { + &self.1 + } + } + impl HasFieldMut> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>, + ) -> &mut Self::Value { + &mut self.1 + } + } + impl HasField> for Context { + type Value = bool; + fn get_field(&self, key: ::core::marker::PhantomData>) -> &Self::Value { + &self.2 + } + } + impl HasFieldMut> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>, + ) -> &mut Self::Value { + &mut self.2 + } + } + impl HasFields for Context { + type Fields = Cons< + Field, u64>, + Cons, String>, Cons, bool>, ε>>, + >; + } + impl HasFieldsRef for Context { + type FieldsRef<'__a> = Cons< + Field, &'__a u64>, + Cons, &'__a String>, Cons, &'__a bool>, ε>>, + > + where + Self: '__a; + } + impl FromFields for Context { + fn from_fields( + Cons(field_2, Cons(field_1, Cons(field_0, ε))): Self::Fields, + ) -> Self { + Self(field_2.value, field_1.value, field_0.value) + } + } + impl ToFields for Context { + fn to_fields(self) -> Self::Fields { + Cons(self.0.into(), Cons(self.1.into(), Cons(self.2.into(), ε))) + } + } + impl ToFieldsRef for Context { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + Cons((&self.0).into(), Cons((&self.1).into(), Cons((&self.2).into(), ε))) + } + } + pub struct __PartialContext<__F0__: MapType, __F1__: MapType, __F2__: MapType>( + pub <__F0__ as MapType>::Map, + pub <__F1__ as MapType>::Map, + pub <__F2__ as MapType>::Map, + ); + impl HasBuilder for Context { + type Builder = __PartialContext; + fn builder() -> Self::Builder { + __PartialContext { + 0: (), + 1: (), + 2: (), + } + } + } + impl IntoBuilder for Context { + type Builder = __PartialContext; + fn into_builder(self) -> Self::Builder { + __PartialContext { + 0: self.0, + 1: self.1, + 2: self.2, + } + } + } + impl<__F0__: MapType, __F1__: MapType, __F2__: MapType> PartialData + for __PartialContext<__F0__, __F1__, __F2__> { + type Target = Context; + } + impl FinalizeBuild for __PartialContext { + fn finalize_build(self) -> Self::Target { + Context { + 0: self.0, + 1: self.1, + 2: self.2, + } + } + } + impl< + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + __F2__: MapType, + > UpdateField, __M2__> for __PartialContext<__M1__, __F1__, __F2__> { + type Value = u64; + type Mapper = __M1__; + type Output = __PartialContext<__M2__, __F1__, __F2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData>, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.0, + __PartialContext { + 0: value, + 1: self.1, + 2: self.2, + }, + ) + } + } + impl< + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + __F2__: MapType, + > UpdateField, __M2__> for __PartialContext<__F0__, __M1__, __F2__> { + type Value = String; + type Mapper = __M1__; + type Output = __PartialContext<__F0__, __M2__, __F2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData>, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.1, + __PartialContext { + 0: self.0, + 1: value, + 2: self.2, + }, + ) + } + } + impl< + __F0__: MapType, + __F1__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField, __M2__> for __PartialContext<__F0__, __F1__, __M1__> { + type Value = bool; + type Mapper = __M1__; + type Output = __PartialContext<__F0__, __F1__, __M2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData>, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.2, + __PartialContext { + 0: self.0, + 1: self.1, + 2: value, + }, + ) + } + } + impl<__F1__: MapType, __F2__: MapType> HasField> + for __PartialContext { + type Value = u64; + fn get_field(&self, tag: ::core::marker::PhantomData>) -> &Self::Value { + &self.0 + } + } + impl<__F0__: MapType, __F2__: MapType> HasField> + for __PartialContext<__F0__, IsPresent, __F2__> { + type Value = String; + fn get_field(&self, tag: ::core::marker::PhantomData>) -> &Self::Value { + &self.1 + } + } + impl<__F0__: MapType, __F1__: MapType> HasField> + for __PartialContext<__F0__, __F1__, IsPresent> { + type Value = bool; + fn get_field(&self, tag: ::core::marker::PhantomData>) -> &Self::Value { + &self.2 + } + } + ") + } +} diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs index 9b45dc37..3d7b6e04 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs @@ -2,11 +2,203 @@ use cgp::extra::field::impls::{ CanFinalizeWithDefault, FinalizeOptional, HasOptionalBuilder, SetOptional, }; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(CgpData)] -pub struct Context { - pub foo: String, - pub bar: u64, +snapshot_derive_cgp_data! { + #[derive(CgpData)] + pub struct Context { + pub foo: String, + pub bar: u64, + } + + expand_context(output) { + insta::assert_snapshot!(output, @" + impl HasField>>>> for Context { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl HasFieldMut>>>> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.foo + } + } + impl HasField>>>> for Context { + type Value = u64; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + impl HasFieldMut>>>> for Context { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &mut Self::Value { + &mut self.bar + } + } + impl HasFields for Context { + type Fields = Cons< + Field>>>, String>, + Cons>>>, u64>, ε>, + >; + } + impl HasFieldsRef for Context { + type FieldsRef<'__a> = Cons< + Field>>>, &'__a String>, + Cons>>>, &'__a u64>, ε>, + > + where + Self: '__a; + } + impl FromFields for Context { + fn from_fields(π(foo, π(bar, Nil)): Self::Fields) -> Self { + Self { + foo: foo.value, + bar: bar.value, + } + } + } + impl ToFields for Context { + fn to_fields(self) -> Self::Fields { + π(self.foo.into(), π(self.bar.into(), ε)) + } + } + impl ToFieldsRef for Context { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.foo).into(), π((&self.bar).into(), ε)) + } + } + pub struct __PartialContext<__F0__: MapType, __F1__: MapType> { + pub foo: <__F0__ as MapType>::Map, + pub bar: <__F1__ as MapType>::Map, + } + impl HasBuilder for Context { + type Builder = __PartialContext; + fn builder() -> Self::Builder { + __PartialContext { + foo: (), + bar: (), + } + } + } + impl IntoBuilder for Context { + type Builder = __PartialContext; + fn into_builder(self) -> Self::Builder { + __PartialContext { + foo: self.foo, + bar: self.bar, + } + } + } + impl<__F0__: MapType, __F1__: MapType> PartialData for __PartialContext<__F0__, __F1__> { + type Target = Context; + } + impl FinalizeBuild for __PartialContext { + fn finalize_build(self) -> Self::Target { + Context { + foo: self.foo, + bar: self.bar, + } + } + } + impl< + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + > UpdateField>>>, __M2__> + for __PartialContext<__M1__, __F1__> { + type Value = String; + type Mapper = __M1__; + type Output = __PartialContext<__M2__, __F1__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.foo, + __PartialContext { + foo: value, + bar: self.bar, + }, + ) + } + } + impl< + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField>>>, __M2__> + for __PartialContext<__F0__, __M1__> { + type Value = u64; + type Mapper = __M1__; + type Output = __PartialContext<__F0__, __M2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.bar, + __PartialContext { + foo: self.foo, + bar: value, + }, + ) + } + } + impl<__F1__: MapType> HasField>>>> + for __PartialContext { + type Value = String; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> &Self::Value { + &self.foo + } + } + impl<__F0__: MapType> HasField>>>> + for __PartialContext<__F0__, IsPresent> { + type Value = u64; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> &Self::Value { + &self.bar + } + } + ") + } } #[test] diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs index aef61b21..69e11ffa 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs @@ -1,11 +1,617 @@ use cgp::core::field::impls::CanBuildFrom; use cgp::extra::dispatch::{BuildAndMerge, BuildAndSetField, BuildWithHandlers}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(CgpData)] -pub struct Person { - pub first_name: String, - pub last_name: String, +snapshot_derive_cgp_data! { + #[derive(CgpData)] + pub struct Person { + pub first_name: String, + pub last_name: String, + } + + expand_person(output) { + insta::assert_snapshot!(output, @" + impl HasField< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + > for Person { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + ) -> &Self::Value { + &self.first_name + } + } + impl HasFieldMut< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + > for Person { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + ) -> &mut Self::Value { + &mut self.first_name + } + } + impl HasField< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars<'_', Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for Person { + type Value = String; + fn get_field( + &self, + key: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + ) -> &Self::Value { + &self.last_name + } + } + impl HasFieldMut< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars<'_', Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for Person { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + ) -> &mut Self::Value { + &mut self.last_name + } + } + impl HasFields for Person { + type Fields = Cons< + Field< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + String, + >, + Cons< + Field< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + String, + >, + ε, + >, + >; + } + impl HasFieldsRef for Person { + type FieldsRef<'__a> = Cons< + Field< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + &'__a String, + >, + Cons< + Field< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + &'__a String, + >, + ε, + >, + > + where + Self: '__a; + } + impl FromFields for Person { + fn from_fields(π(first_name, π(last_name, Nil)): Self::Fields) -> Self { + Self { + first_name: first_name.value, + last_name: last_name.value, + } + } + } + impl ToFields for Person { + fn to_fields(self) -> Self::Fields { + π(self.first_name.into(), π(self.last_name.into(), ε)) + } + } + impl ToFieldsRef for Person { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.first_name).into(), π((&self.last_name).into(), ε)) + } + } + pub struct __PartialPerson<__F0__: MapType, __F1__: MapType> { + pub first_name: <__F0__ as MapType>::Map, + pub last_name: <__F1__ as MapType>::Map, + } + impl HasBuilder for Person { + type Builder = __PartialPerson; + fn builder() -> Self::Builder { + __PartialPerson { + first_name: (), + last_name: (), + } + } + } + impl IntoBuilder for Person { + type Builder = __PartialPerson; + fn into_builder(self) -> Self::Builder { + __PartialPerson { + first_name: self.first_name, + last_name: self.last_name, + } + } + } + impl<__F0__: MapType, __F1__: MapType> PartialData for __PartialPerson<__F0__, __F1__> { + type Target = Person; + } + impl FinalizeBuild for __PartialPerson { + fn finalize_build(self) -> Self::Target { + Person { + first_name: self.first_name, + last_name: self.last_name, + } + } + } + impl< + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + > UpdateField< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + __M2__, + > for __PartialPerson<__M1__, __F1__> { + type Value = String; + type Mapper = __M1__; + type Output = __PartialPerson<__M2__, __F1__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.first_name, + __PartialPerson { + first_name: value, + last_name: self.last_name, + }, + ) + } + } + impl< + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars<'_', Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + __M2__, + > for __PartialPerson<__F0__, __M1__> { + type Value = String; + type Mapper = __M1__; + type Output = __PartialPerson<__F0__, __M2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.last_name, + __PartialPerson { + first_name: self.first_name, + last_name: value, + }, + ) + } + } + impl< + __F1__: MapType, + > HasField< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + > for __PartialPerson { + type Value = String; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol< + 10, + Chars< + 'f', + Chars< + 'i', + Chars< + 'r', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + ) -> &Self::Value { + &self.first_name + } + } + impl< + __F0__: MapType, + > HasField< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars<'_', Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for __PartialPerson<__F0__, IsPresent> { + type Value = String; + fn get_field( + &self, + tag: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'l', + Chars< + 'a', + Chars< + 's', + Chars< + 't', + Chars< + '_', + Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + ) -> &Self::Value { + &self.last_name + } + } + ") + } } #[derive(CgpData)] diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs index d1b65ffa..992706ec 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs @@ -1,10 +1,176 @@ use cgp::extra::field::impls::CanBuildWithDefault; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(Debug, Clone, Eq, PartialEq, CgpData)] -struct Point2d { - x: u64, - y: u64, +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, Clone, Eq, PartialEq)] + struct Point2d { + x: u64, + y: u64, + } + + expand_point_2d(output) { + insta::assert_snapshot!(output, @" + impl HasField>> for Point2d { + type Value = u64; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.x + } + } + impl HasFieldMut>> for Point2d { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.x + } + } + impl HasField>> for Point2d { + type Value = u64; + fn get_field( + &self, + key: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.y + } + } + impl HasFieldMut>> for Point2d { + fn get_field_mut( + &mut self, + key: ::core::marker::PhantomData>>, + ) -> &mut Self::Value { + &mut self.y + } + } + impl HasFields for Point2d { + type Fields = Cons< + Field>, u64>, + Cons>, u64>, ε>, + >; + } + impl HasFieldsRef for Point2d { + type FieldsRef<'__a> = Cons< + Field>, &'__a u64>, + Cons>, &'__a u64>, ε>, + > + where + Self: '__a; + } + impl FromFields for Point2d { + fn from_fields(π(x, π(y, Nil)): Self::Fields) -> Self { + Self { x: x.value, y: y.value } + } + } + impl ToFields for Point2d { + fn to_fields(self) -> Self::Fields { + π(self.x.into(), π(self.y.into(), ε)) + } + } + impl ToFieldsRef for Point2d { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + π((&self.x).into(), π((&self.y).into(), ε)) + } + } + struct __PartialPoint2d<__F0__: MapType, __F1__: MapType> { + x: <__F0__ as MapType>::Map, + y: <__F1__ as MapType>::Map, + } + impl HasBuilder for Point2d { + type Builder = __PartialPoint2d; + fn builder() -> Self::Builder { + __PartialPoint2d { x: (), y: () } + } + } + impl IntoBuilder for Point2d { + type Builder = __PartialPoint2d; + fn into_builder(self) -> Self::Builder { + __PartialPoint2d { + x: self.x, + y: self.y, + } + } + } + impl<__F0__: MapType, __F1__: MapType> PartialData for __PartialPoint2d<__F0__, __F1__> { + type Target = Point2d; + } + impl FinalizeBuild for __PartialPoint2d { + fn finalize_build(self) -> Self::Target { + Point2d { x: self.x, y: self.y } + } + } + impl< + __M1__: MapType, + __M2__: MapType, + __F1__: MapType, + > UpdateField>, __M2__> for __PartialPoint2d<__M1__, __F1__> { + type Value = u64; + type Mapper = __M1__; + type Output = __PartialPoint2d<__M2__, __F1__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData>>, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.x, + __PartialPoint2d { + x: value, + y: self.y, + }, + ) + } + } + impl< + __F0__: MapType, + __M1__: MapType, + __M2__: MapType, + > UpdateField>, __M2__> for __PartialPoint2d<__F0__, __M1__> { + type Value = u64; + type Mapper = __M1__; + type Output = __PartialPoint2d<__F0__, __M2__>; + fn update_field( + self, + _tag: ::core::marker::PhantomData>>, + value: __M2__::Map, + ) -> (__M1__::Map, Self::Output) { + ( + self.y, + __PartialPoint2d { + x: self.x, + y: value, + }, + ) + } + } + impl<__F1__: MapType> HasField>> + for __PartialPoint2d { + type Value = u64; + fn get_field( + &self, + tag: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.x + } + } + impl<__F0__: MapType> HasField>> + for __PartialPoint2d<__F0__, IsPresent> { + type Value = u64; + fn get_field( + &self, + tag: ::core::marker::PhantomData>>, + ) -> &Self::Value { + &self.y + } + } + ") + } } #[derive(Debug, Clone, Eq, PartialEq, CgpData)] diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs index 9213f8c9..b6cd23b7 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs @@ -1,11 +1,470 @@ use cgp::core::field::impls::{CanDowncast, CanUpcast}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_derive_cgp_data; -#[derive(Debug, Eq, PartialEq, CgpData)] -pub enum FooBarBazGeneric { - Foo(Foo), - Bar(Bar), - Baz(Baz), +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, Eq, PartialEq)] + pub enum FooBarBazGeneric { + Foo(Foo), + Bar(Bar), + Baz(Baz), + } + + expand_foo_bar_baz_generic(output) { + insta::assert_snapshot!(output, @" + impl HasFields for FooBarBazGeneric { + type Fields = Either< + Field>>>, Foo>, + Either< + Field>>>, Bar>, + Either>>>, Baz>, θ>, + >, + >; + } + impl HasFieldsRef for FooBarBazGeneric { + type FieldsRef<'__a> = Either< + Field>>>, &'__a Foo>, + Either< + Field>>>, &'__a Bar>, + Either< + Field>>>, &'__a Baz>, + θ, + >, + >, + > + where + Self: '__a; + } + impl FromFields for FooBarBazGeneric { + fn from_fields(rest: Self::Fields) -> Self { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Foo(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Bar(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Baz(field) + } + Either::Right(rest) => match rest {} + } + } + } + } + } + } + } + impl ToFields for FooBarBazGeneric { + fn to_fields(self) -> Self::Fields { + match self { + Self::Foo(field) => Either::Left(field.into()), + Self::Bar(field) => Either::Right(Either::Left(field.into())), + Self::Baz(field) => Either::Right(Either::Right(Either::Left(field.into()))), + } + } + } + impl ToFieldsRef for FooBarBazGeneric { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + match self { + Self::Foo(field) => Either::Left(field.into()), + Self::Bar(field) => Either::Right(Either::Left(field.into())), + Self::Baz(field) => Either::Right(Either::Right(Either::Left(field.into()))), + } + } + } + impl FromVariant>>>> + for FooBarBazGeneric { + type Value = Foo; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Foo(value) + } + } + impl FromVariant>>>> + for FooBarBazGeneric { + type Value = Bar; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Bar(value) + } + } + impl FromVariant>>>> + for FooBarBazGeneric { + type Value = Baz; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + value: Self::Value, + ) -> Self { + Self::Baz(value) + } + } + pub enum __PartialFooBarBazGeneric< + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > { + Foo(<__F0__ as MapType>::Map), + Bar(<__F1__ as MapType>::Map), + Baz(<__F2__ as MapType>::Map), + } + pub enum __PartialRefFooBarBazGeneric< + '__a__, + __R__: MapTypeRef, + Foo: '__a__, + Bar: '__a__, + Baz: '__a__, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > { + Foo(<__F0__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, Foo>>), + Bar(<__F1__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, Bar>>), + Baz(<__F2__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, Baz>>), + } + impl PartialData + for __PartialFooBarBazGeneric { + type Target = FooBarBazGeneric; + } + impl< + '__a__, + __R__: MapTypeRef, + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + __F2__: MapType, + > PartialData + for __PartialRefFooBarBazGeneric<'__a__, __R__, Foo, Bar, Baz, __F0__, __F1__, __F2__> { + type Target = FooBarBazGeneric; + } + impl HasExtractor for FooBarBazGeneric { + type Extractor = __PartialFooBarBazGeneric< + Foo, + Bar, + Baz, + IsPresent, + IsPresent, + IsPresent, + >; + fn to_extractor(self) -> Self::Extractor { + match self { + Self::Foo(value) => __PartialFooBarBazGeneric::Foo(value), + Self::Bar(value) => __PartialFooBarBazGeneric::Bar(value), + Self::Baz(value) => __PartialFooBarBazGeneric::Baz(value), + } + } + fn from_extractor(extractor: Self::Extractor) -> Self { + match extractor { + __PartialFooBarBazGeneric::Foo(value) => Self::Foo(value), + __PartialFooBarBazGeneric::Bar(value) => Self::Bar(value), + __PartialFooBarBazGeneric::Baz(value) => Self::Baz(value), + } + } + } + impl HasExtractorRef for FooBarBazGeneric { + type ExtractorRef<'a> = __PartialRefFooBarBazGeneric< + 'a, + IsRef, + Foo, + Bar, + Baz, + IsPresent, + IsPresent, + IsPresent, + > + where + Self: 'a; + fn extractor_ref<'a>(&'a self) -> Self::ExtractorRef<'a> { + match self { + Self::Foo(value) => __PartialRefFooBarBazGeneric::Foo(value), + Self::Bar(value) => __PartialRefFooBarBazGeneric::Bar(value), + Self::Baz(value) => __PartialRefFooBarBazGeneric::Baz(value), + } + } + } + impl HasExtractorMut for FooBarBazGeneric { + type ExtractorMut<'a> = __PartialRefFooBarBazGeneric< + 'a, + IsMut, + Foo, + Bar, + Baz, + IsPresent, + IsPresent, + IsPresent, + > + where + Self: 'a; + fn extractor_mut<'a>(&'a mut self) -> Self::ExtractorMut<'a> { + match self { + Self::Foo(value) => __PartialRefFooBarBazGeneric::Foo(value), + Self::Bar(value) => __PartialRefFooBarBazGeneric::Bar(value), + Self::Baz(value) => __PartialRefFooBarBazGeneric::Baz(value), + } + } + } + impl FinalizeExtract + for __PartialFooBarBazGeneric { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl<'a, __R__: MapTypeRef, Foo, Bar, Baz> FinalizeExtract + for __PartialRefFooBarBazGeneric<'a, __R__, Foo, Bar, Baz, IsVoid, IsVoid, IsVoid> { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl< + Foo, + Bar, + Baz, + __F1__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialFooBarBazGeneric { + type Value = Foo; + type Remainder = __PartialFooBarBazGeneric; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBazGeneric::Foo(value) => Ok(value), + __PartialFooBarBazGeneric::Bar(value) => { + Err(__PartialFooBarBazGeneric::Bar(value)) + } + __PartialFooBarBazGeneric::Baz(value) => { + Err(__PartialFooBarBazGeneric::Baz(value)) + } + } + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialFooBarBazGeneric { + type Value = Bar; + type Remainder = __PartialFooBarBazGeneric; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBazGeneric::Foo(value) => { + Err(__PartialFooBarBazGeneric::Foo(value)) + } + __PartialFooBarBazGeneric::Bar(value) => Ok(value), + __PartialFooBarBazGeneric::Baz(value) => { + Err(__PartialFooBarBazGeneric::Baz(value)) + } + } + } + } + impl< + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + > ExtractField>>>> + for __PartialFooBarBazGeneric { + type Value = Baz; + type Remainder = __PartialFooBarBazGeneric; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> Result { + match self { + __PartialFooBarBazGeneric::Foo(value) => { + Err(__PartialFooBarBazGeneric::Foo(value)) + } + __PartialFooBarBazGeneric::Bar(value) => { + Err(__PartialFooBarBazGeneric::Bar(value)) + } + __PartialFooBarBazGeneric::Baz(value) => Ok(value), + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + Foo, + Bar, + Baz, + __F1__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + IsPresent, + __F1__, + __F2__, + > { + type Value = <__R__ as MapTypeRef>::Map<'__a__, Foo>; + type Remainder = __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + IsVoid, + __F1__, + __F2__, + >; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'F', Chars<'o', Chars<'o', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBazGeneric::Foo(value) => Ok(value), + __PartialRefFooBarBazGeneric::Bar(value) => { + Err(__PartialRefFooBarBazGeneric::Bar(value)) + } + __PartialRefFooBarBazGeneric::Baz(value) => { + Err(__PartialRefFooBarBazGeneric::Baz(value)) + } + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + Foo, + Bar, + Baz, + __F0__: MapType, + __F2__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + __F0__, + IsPresent, + __F2__, + > { + type Value = <__R__ as MapTypeRef>::Map<'__a__, Bar>; + type Remainder = __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + __F0__, + IsVoid, + __F2__, + >; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'r', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBazGeneric::Foo(value) => { + Err(__PartialRefFooBarBazGeneric::Foo(value)) + } + __PartialRefFooBarBazGeneric::Bar(value) => Ok(value), + __PartialRefFooBarBazGeneric::Baz(value) => { + Err(__PartialRefFooBarBazGeneric::Baz(value)) + } + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + Foo, + Bar, + Baz, + __F0__: MapType, + __F1__: MapType, + > ExtractField>>>> + for __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + __F0__, + __F1__, + IsPresent, + > { + type Value = <__R__ as MapTypeRef>::Map<'__a__, Baz>; + type Remainder = __PartialRefFooBarBazGeneric< + '__a__, + __R__, + Foo, + Bar, + Baz, + __F0__, + __F1__, + IsVoid, + >; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol<3, Chars<'B', Chars<'a', Chars<'z', Nil>>>>, + >, + ) -> Result { + match self { + __PartialRefFooBarBazGeneric::Foo(value) => { + Err(__PartialRefFooBarBazGeneric::Foo(value)) + } + __PartialRefFooBarBazGeneric::Bar(value) => { + Err(__PartialRefFooBarBazGeneric::Bar(value)) + } + __PartialRefFooBarBazGeneric::Baz(value) => Ok(value), + } + } + } + ") + } } #[derive(Debug, Eq, PartialEq, CgpData)] diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs index d2024e6c..171a49e7 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs @@ -8,12 +8,437 @@ use cgp::extra::dispatch::{ }; use cgp::extra::handler::{NoCode, UseInputDelegate}; use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; +use cgp_macro_test_util::{ + snapshot_check_components, snapshot_delegate_components, snapshot_derive_cgp_data, +}; -#[derive(Debug, PartialEq, CgpData)] -pub enum Shape { - Circle(Circle), - Rectangle(Rectangle), +snapshot_derive_cgp_data! { + #[derive(CgpData)] + #[derive(Debug, PartialEq)] + pub enum Shape { + Circle(Circle), + Rectangle(Rectangle), + } + + expand_shape(output) { + insta::assert_snapshot!(output, @" + impl HasFields for Shape { + type Fields = Either< + Field< + Symbol< + 6, + Chars< + 'C', + Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + Circle, + >, + Either< + Field< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars< + 'a', + Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + Rectangle, + >, + θ, + >, + >; + } + impl HasFieldsRef for Shape { + type FieldsRef<'__a> = Either< + Field< + Symbol< + 6, + Chars< + 'C', + Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + &'__a Circle, + >, + Either< + Field< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars< + 'a', + Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + &'__a Rectangle, + >, + θ, + >, + > + where + Self: '__a; + } + impl FromFields for Shape { + fn from_fields(rest: Self::Fields) -> Self { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Circle(field) + } + Either::Right(rest) => { + match rest { + Either::Left(field) => { + let field = field.value; + Self::Rectangle(field) + } + Either::Right(rest) => match rest {} + } + } + } + } + } + impl ToFields for Shape { + fn to_fields(self) -> Self::Fields { + match self { + Self::Circle(field) => Either::Left(field.into()), + Self::Rectangle(field) => Either::Right(Either::Left(field.into())), + } + } + } + impl ToFieldsRef for Shape { + fn to_fields_ref<'__a>(&'__a self) -> Self::FieldsRef<'__a> + where + Self: '__a, + { + match self { + Self::Circle(field) => Either::Left(field.into()), + Self::Rectangle(field) => Either::Right(Either::Left(field.into())), + } + } + } + impl FromVariant< + Symbol< + 6, + Chars<'C', Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>>, + >, + > for Shape { + type Value = Circle; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol< + 6, + Chars< + 'C', + Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + value: Self::Value, + ) -> Self { + Self::Circle(value) + } + } + impl FromVariant< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars<'a', Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for Shape { + type Value = Rectangle; + fn from_variant( + _tag: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars< + 'a', + Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + value: Self::Value, + ) -> Self { + Self::Rectangle(value) + } + } + pub enum __PartialShape<__F0__: MapType, __F1__: MapType> { + Circle(<__F0__ as MapType>::Map), + Rectangle(<__F1__ as MapType>::Map), + } + pub enum __PartialRefShape<'__a__, __R__: MapTypeRef, __F0__: MapType, __F1__: MapType> { + Circle(<__F0__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, Circle>>), + Rectangle(<__F1__ as MapType>::Map<<__R__ as MapTypeRef>::Map<'__a__, Rectangle>>), + } + impl<__F0__: MapType, __F1__: MapType> PartialData for __PartialShape<__F0__, __F1__> { + type Target = Shape; + } + impl<'__a__, __R__: MapTypeRef, __F0__: MapType, __F1__: MapType> PartialData + for __PartialRefShape<'__a__, __R__, __F0__, __F1__> { + type Target = Shape; + } + impl HasExtractor for Shape { + type Extractor = __PartialShape; + fn to_extractor(self) -> Self::Extractor { + match self { + Self::Circle(value) => __PartialShape::Circle(value), + Self::Rectangle(value) => __PartialShape::Rectangle(value), + } + } + fn from_extractor(extractor: Self::Extractor) -> Self { + match extractor { + __PartialShape::Circle(value) => Self::Circle(value), + __PartialShape::Rectangle(value) => Self::Rectangle(value), + } + } + } + impl HasExtractorRef for Shape { + type ExtractorRef<'a> = __PartialRefShape<'a, IsRef, IsPresent, IsPresent> + where + Self: 'a; + fn extractor_ref<'a>(&'a self) -> Self::ExtractorRef<'a> { + match self { + Self::Circle(value) => __PartialRefShape::Circle(value), + Self::Rectangle(value) => __PartialRefShape::Rectangle(value), + } + } + } + impl HasExtractorMut for Shape { + type ExtractorMut<'a> = __PartialRefShape<'a, IsMut, IsPresent, IsPresent> + where + Self: 'a; + fn extractor_mut<'a>(&'a mut self) -> Self::ExtractorMut<'a> { + match self { + Self::Circle(value) => __PartialRefShape::Circle(value), + Self::Rectangle(value) => __PartialRefShape::Rectangle(value), + } + } + } + impl FinalizeExtract for __PartialShape { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl<'a, __R__: MapTypeRef> FinalizeExtract + for __PartialRefShape<'a, __R__, IsVoid, IsVoid> { + fn finalize_extract<__T__>(self) -> __T__ { + match self {} + } + } + impl< + __F1__: MapType, + > ExtractField< + Symbol< + 6, + Chars<'C', Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>>, + >, + > for __PartialShape { + type Value = Circle; + type Remainder = __PartialShape; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 6, + Chars< + 'C', + Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + ) -> Result { + match self { + __PartialShape::Circle(value) => Ok(value), + __PartialShape::Rectangle(value) => Err(__PartialShape::Rectangle(value)), + } + } + } + impl< + __F0__: MapType, + > ExtractField< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars<'a', Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for __PartialShape<__F0__, IsPresent> { + type Value = Rectangle; + type Remainder = __PartialShape<__F0__, IsVoid>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars< + 'a', + Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + ) -> Result { + match self { + __PartialShape::Circle(value) => Err(__PartialShape::Circle(value)), + __PartialShape::Rectangle(value) => Ok(value), + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + __F1__: MapType, + > ExtractField< + Symbol< + 6, + Chars<'C', Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>>, + >, + > for __PartialRefShape<'__a__, __R__, IsPresent, __F1__> { + type Value = <__R__ as MapTypeRef>::Map<'__a__, Circle>; + type Remainder = __PartialRefShape<'__a__, __R__, IsVoid, __F1__>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 6, + Chars< + 'C', + Chars<'i', Chars<'r', Chars<'c', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + ) -> Result { + match self { + __PartialRefShape::Circle(value) => Ok(value), + __PartialRefShape::Rectangle(value) => { + Err(__PartialRefShape::Rectangle(value)) + } + } + } + } + impl< + '__a__, + __R__: MapTypeRef, + __F0__: MapType, + > ExtractField< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars<'a', Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>>, + >, + >, + >, + >, + >, + > for __PartialRefShape<'__a__, __R__, __F0__, IsPresent> { + type Value = <__R__ as MapTypeRef>::Map<'__a__, Rectangle>; + type Remainder = __PartialRefShape<'__a__, __R__, __F0__, IsVoid>; + fn extract_field( + self, + _tag: ::core::marker::PhantomData< + Symbol< + 9, + Chars< + 'R', + Chars< + 'e', + Chars< + 'c', + Chars< + 't', + Chars< + 'a', + Chars<'n', Chars<'g', Chars<'l', Chars<'e', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + ) -> Result { + match self { + __PartialRefShape::Circle(value) => Err(__PartialRefShape::Circle(value)), + __PartialRefShape::Rectangle(value) => Ok(value), + } + } + } + ") + } } #[derive(Debug, PartialEq, CgpData)] From 74efaf132e854145aec799f16fa1c1405ee4ce60 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Mon, 29 Jun 2026 01:02:28 +0200 Subject: [PATCH 29/29] AI-revise macro qualification and remove greek identifiers --- Cargo.lock | 10 +++- Cargo.toml | 2 + crates/core/cgp-base-types/src/lib.rs | 2 - crates/core/cgp-base-types/src/types/chars.rs | 17 +----- crates/core/cgp-base-types/src/types/cons.rs | 18 +------ crates/core/cgp-base-types/src/types/nil.rs | 7 +-- .../core/cgp-base-types/src/types/symbol.rs | 4 +- crates/core/cgp-error/Cargo.toml | 2 +- .../cgp-error/src/traits/can_raise_error.rs | 2 +- .../cgp-error/src/traits/can_wrap_error.rs | 2 +- .../cgp-error/src/traits/has_error_type.rs | 3 +- crates/core/cgp-field/src/lib.rs | 2 - crates/core/cgp-field/src/types/field.rs | 22 +------- crates/core/cgp-field/src/types/index.rs | 9 +--- crates/core/cgp-field/src/types/sum.rs | 22 ++------ crates/macros/cgp-macro-core/src/exports.rs | 9 ++++ crates/macros/cgp-macro-core/src/lib.rs | 2 - .../derive_extractor/extract_field_impls.rs | 12 ++--- .../derive_extractor/extractor_enum.rs | 4 +- .../src/types/cgp_data/derive_from_variant.rs | 3 +- .../src/types/cgp_data/derive_has_field.rs | 9 ++-- .../derive_has_fields/from_fields_enum.rs | 4 +- .../derive_has_fields/from_fields_struct.rs | 8 +-- .../cgp_data/derive_has_fields/product.rs | 4 +- .../types/cgp_data/derive_has_fields/sum.rs | 4 +- .../derive_has_fields/to_fields_struct.rs | 6 +-- .../types/cgp_getter/to_use_fields_impl.rs | 3 +- .../src/types/cgp_getter/use_field.rs | 3 +- .../src/types/cgp_getter/with_provider.rs | 9 ++-- .../cgp-macro-core/src/types/cgp_type/item.rs | 7 +-- .../src/types/check_components/table.rs | 4 +- crates/macros/cgp-macro/src/lib.rs | 18 ------- crates/main/cgp-base-extra/Cargo.toml | 13 +++++ crates/main/cgp-base-extra/src/lib.rs | 6 +++ .../main/cgp-base-extra/src/macro_prelude.rs | 5 ++ crates/main/cgp-base/src/lib.rs | 3 ++ crates/main/cgp-core/src/prelude.rs | 4 +- .../cgp_fn_tests/foreign_type_equality.rs | 1 - .../tests/cgp_fn_tests/type_equality.rs | 1 - .../tests/cgp_fn_tests/use_type_alias.rs | 1 - .../has_fields/enum_fields.rs | 8 +-- .../has_fields/struct_fields.rs | 53 ++++++++++--------- .../extensible_data_tests/records/basic.rs | 10 ++-- .../extensible_data_tests/records/generics.rs | 11 ++-- .../extensible_data_tests/records/index.rs | 11 ++-- .../extensible_data_tests/records/optional.rs | 10 ++-- .../extensible_data_tests/records/person.rs | 10 ++-- .../extensible_data_tests/records/point.rs | 10 ++-- .../extensible_data_tests/variants/basic.rs | 4 +- .../extensible_data_tests/variants/generic.rs | 4 +- .../extensible_data_tests/variants/shape.rs | 4 +- .../getter_tests/abstract_type/explicit.rs | 1 - .../getter_tests/abstract_type/import.rs | 1 - .../getter_tests/abstract_type/use_type.rs | 1 - 54 files changed, 178 insertions(+), 227 deletions(-) create mode 100644 crates/main/cgp-base-extra/Cargo.toml create mode 100644 crates/main/cgp-base-extra/src/lib.rs create mode 100644 crates/main/cgp-base-extra/src/macro_prelude.rs diff --git a/Cargo.lock b/Cargo.lock index 293dceca..2fa9c205 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,14 @@ dependencies = [ "cgp-macro", ] +[[package]] +name = "cgp-base-extra" +version = "0.7.0" +dependencies = [ + "cgp-base", + "cgp-type", +] + [[package]] name = "cgp-base-types" version = "0.7.0" @@ -80,7 +88,7 @@ dependencies = [ name = "cgp-error" version = "0.7.0" dependencies = [ - "cgp-base", + "cgp-base-extra", "cgp-field", "cgp-macro", "cgp-type", diff --git a/Cargo.toml b/Cargo.toml index 8fe89c64..7a3f0b0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ resolver = "3" members = [ "crates/main/cgp", "crates/main/cgp-base", + "crates/main/cgp-base-extra", "crates/main/cgp-core", "crates/main/cgp-extra", @@ -50,6 +51,7 @@ keywords = ["cgp"] [workspace.dependencies] cgp = { version = "0.7.0", path = "./crates/main/cgp" } cgp-base = { version = "0.7.0", path = "./crates/main/cgp-base" } +cgp-base-extra = { version = "0.7.0", path = "./crates/main/cgp-base-extra" } cgp-core = { version = "0.7.0", path = "./crates/main/cgp-core" } cgp-extra = { version = "0.7.0", path = "./crates/main/cgp-extra" } diff --git a/crates/core/cgp-base-types/src/lib.rs b/crates/core/cgp-base-types/src/lib.rs index b59e7464..592301f5 100644 --- a/crates/core/cgp-base-types/src/lib.rs +++ b/crates/core/cgp-base-types/src/lib.rs @@ -1,5 +1,3 @@ -#![allow(non_camel_case_types)] - pub mod macro_prelude; pub mod traits; pub mod types; diff --git a/crates/core/cgp-base-types/src/types/chars.rs b/crates/core/cgp-base-types/src/types/chars.rs index e8751c08..9e31f744 100644 --- a/crates/core/cgp-base-types/src/types/chars.rs +++ b/crates/core/cgp-base-types/src/types/chars.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use crate::traits::StaticFormat; /** - The `Chars` type, a.k.a. `ζ`, is used to represent _type-level_ list of + The `Chars` type is used to represent _type-level_ list of `Chars`s, which are equivalent to type-level strings. `Chars` is a specialized version of [`Cons`](crate::types::Cons), with the @@ -13,11 +13,6 @@ use crate::traits::StaticFormat; expected to be either the next `Chars`, or [`Nil`](crate::types::Nil) to represent the end of the string. - Instead of reusing `Cons`, we combine the use of `Cons` within `Chars` so - that its representation is more compact when shown in compiler error messages. - Similar to `Cons`, `Chars` is also shown as `ζ` to further improve its - readability. - We represent type-level strings as list of `Chars`s, because it is currently not possible to use types like `String` or `&str` as const-generic parameters. On the other hand, a single `Chars` can be used as a const-generic parameter, @@ -40,17 +35,9 @@ use crate::traits::StaticFormat; ```rust,ignore type Hello = Chars<'h', Chars<'e', Chars<'l', Chars<'l', Chars<'o', Nil>>>>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type Hello = ζ<'h', ζ<'e', ζ<'l', ζ<'l', ζ<'o', ε>>>>>; - ``` */ #[derive(Eq, PartialEq, Clone, Copy, Default)] -pub struct ζ(pub PhantomData); - -pub use ζ as Chars; +pub struct Chars(pub PhantomData); impl Display for Chars where diff --git a/crates/core/cgp-base-types/src/types/cons.rs b/crates/core/cgp-base-types/src/types/cons.rs index 315c3f39..92543c28 100644 --- a/crates/core/cgp-base-types/src/types/cons.rs +++ b/crates/core/cgp-base-types/src/types/cons.rs @@ -1,15 +1,10 @@ /** - The `Cons` type, a.k.a. `π`, is used to represent the head of a _type-level list_, + The `Cons` type is used to represent the head of a _type-level list_, also known as an _anonymous product type_. `Cons` is used together with [`Nil`] to produce a type-level list using the `Product!` macro. - `Cons` is also shown as `π`, together with [`Nil`] shown as `ε`, to improve the - readability of compiler error messages. Through the shortened name, a product - type would take slightly less space, making it more likely to fit on a single - line for the user to read what the type is. - ## Example Given the following product type definition: @@ -23,15 +18,6 @@ ```rust,ignore type MyTypes = Cons>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type MyTypes = π>>; - ``` */ #[derive(Eq, PartialEq, Clone, Default, Debug)] -#[allow(non_camel_case_types)] -pub struct π(pub Head, pub Tail); - -pub use π as Cons; +pub struct Cons(pub Head, pub Tail); diff --git a/crates/core/cgp-base-types/src/types/nil.rs b/crates/core/cgp-base-types/src/types/nil.rs index 9f6ee60d..a132ba41 100644 --- a/crates/core/cgp-base-types/src/types/nil.rs +++ b/crates/core/cgp-base-types/src/types/nil.rs @@ -1,5 +1,5 @@ /** - The `Nil` type, a.k.a. `ε`, is used to represent the end of a _type-level list_, + The `Nil` type is used to represent the end of a _type-level list_, or an empty type-level list. `Nil` is commonly used as the `Tail` of a [`Cons`] type, to terminate the list. @@ -8,7 +8,4 @@ Read more about type-level lists, a.k.a. the product types, in [`Cons`]. */ #[derive(Eq, PartialEq, Clone, Default, Debug)] -#[allow(non_camel_case_types)] -pub struct ε; - -pub use ε as Nil; +pub struct Nil; diff --git a/crates/core/cgp-base-types/src/types/symbol.rs b/crates/core/cgp-base-types/src/types/symbol.rs index 22fd8705..7b88158a 100644 --- a/crates/core/cgp-base-types/src/types/symbol.rs +++ b/crates/core/cgp-base-types/src/types/symbol.rs @@ -1,9 +1,7 @@ use core::fmt::Display; use core::marker::PhantomData; -pub struct ψ(pub PhantomData); - -pub use ψ as Symbol; +pub struct Symbol(pub PhantomData); use crate::traits::StaticFormat; diff --git a/crates/core/cgp-error/Cargo.toml b/crates/core/cgp-error/Cargo.toml index 52093733..b3411256 100644 --- a/crates/core/cgp-error/Cargo.toml +++ b/crates/core/cgp-error/Cargo.toml @@ -9,7 +9,7 @@ rust-version = { workspace = true } keywords = { workspace = true } [dependencies] -cgp = { version = "0.7.0", path = "../../main/cgp-base", package = "cgp-base" } +cgp = { version = "0.7.0", path = "../../main/cgp-base-extra", package = "cgp-base-extra" } cgp-macro = { workspace = true } cgp-type = { workspace = true } cgp-field = { workspace = true } diff --git a/crates/core/cgp-error/src/traits/can_raise_error.rs b/crates/core/cgp-error/src/traits/can_raise_error.rs index 0717eaa4..ea91d7aa 100644 --- a/crates/core/cgp-error/src/traits/can_raise_error.rs +++ b/crates/core/cgp-error/src/traits/can_raise_error.rs @@ -1,4 +1,4 @@ -use cgp::macro_prelude::*; +use cgp::component::{DefaultNamespace, UseDelegate}; use cgp_macro::cgp_component; use crate::traits::has_error_type::HasErrorType; diff --git a/crates/core/cgp-error/src/traits/can_wrap_error.rs b/crates/core/cgp-error/src/traits/can_wrap_error.rs index 745f6bef..f32321a4 100644 --- a/crates/core/cgp-error/src/traits/can_wrap_error.rs +++ b/crates/core/cgp-error/src/traits/can_wrap_error.rs @@ -1,4 +1,4 @@ -use cgp::macro_prelude::*; +use cgp::component::{DefaultNamespace, UseDelegate}; use cgp_macro::cgp_component; use crate::traits::HasErrorType; diff --git a/crates/core/cgp-error/src/traits/has_error_type.rs b/crates/core/cgp-error/src/traits/has_error_type.rs index 7907f5da..a1e7f357 100644 --- a/crates/core/cgp-error/src/traits/has_error_type.rs +++ b/crates/core/cgp-error/src/traits/has_error_type.rs @@ -1,8 +1,7 @@ use core::fmt::Debug; -use cgp::macro_prelude::*; +use cgp::component::DefaultNamespace; use cgp_macro::cgp_type; -use cgp_type::{TypeProvider, UseType}; /** The `HasErrorType` trait provides an abstract error type that can be used by diff --git a/crates/core/cgp-field/src/lib.rs b/crates/core/cgp-field/src/lib.rs index a03b7ce0..e4988ac9 100644 --- a/crates/core/cgp-field/src/lib.rs +++ b/crates/core/cgp-field/src/lib.rs @@ -1,6 +1,4 @@ #![no_std] -#![allow(mixed_script_confusables)] -#![allow(non_camel_case_types)] pub mod impls; pub mod traits; diff --git a/crates/core/cgp-field/src/types/field.rs b/crates/core/cgp-field/src/types/field.rs index ca4ddca2..09238186 100644 --- a/crates/core/cgp-field/src/types/field.rs +++ b/crates/core/cgp-field/src/types/field.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use core::marker::PhantomData; /** - The `Field` type, a.k.a. `ω`, is used to represent a _named_ field entry + The `Field` type is used to represent a _named_ field entry within a product type or a sum type. `Field` is parameterized by a phantom `Tag` type, which is used to represent @@ -14,11 +14,6 @@ use core::marker::PhantomData; implementations, to include the field name in the generic product or sum representation of the given struct or enum. - `Field` is also shown as `ω` to improve the readability of compiler error - messages. It is mainly useful when the type from `HasFields::Fields` is shown, - which would contain a lot of `Field`s and tend to take up a lot of screen space - to read. - ## Example Given the following struct definition: @@ -38,25 +33,12 @@ use core::marker::PhantomData; type Fields = Product![Field, Field]; } ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - impl HasFields for MyContext { - type Fields = - π<ω, - π<ω, - ε>>; - } - ``` */ -pub struct ω { +pub struct Field { pub value: Value, pub phantom: PhantomData, } -pub use ω as Field; - impl From for Field { fn from(value: Value) -> Self { Self { diff --git a/crates/core/cgp-field/src/types/index.rs b/crates/core/cgp-field/src/types/index.rs index 3a5096ff..d8d46219 100644 --- a/crates/core/cgp-field/src/types/index.rs +++ b/crates/core/cgp-field/src/types/index.rs @@ -1,16 +1,13 @@ use core::fmt::{Debug, Display}; /** - The `Index` type, a.k.a. `δ`, is used to represent a `usize` value at + The `Index` type is used to represent a `usize` value at the _type level_. `Index` is simply defined to be parameterized by a _const-generic_ value of type `usize`. It is most often used to access generic fields by their _index_, instead of by their _name_. - `Index` is also shown as `δ` to improve the readability of compiler error - messages. - ## Example Given the following struct definition: @@ -32,9 +29,7 @@ use core::fmt::{Debug, Display}; } */ #[derive(Eq, PartialEq, Clone, Copy, Default)] -pub struct δ; - -pub use δ as Index; +pub struct Index; impl Display for Index { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { diff --git a/crates/core/cgp-field/src/types/sum.rs b/crates/core/cgp-field/src/types/sum.rs index 3aab93f5..f2511c8b 100644 --- a/crates/core/cgp-field/src/types/sum.rs +++ b/crates/core/cgp-field/src/types/sum.rs @@ -1,16 +1,11 @@ /** - The `Either` type, a.k.a. `σ`, is used to represent an _anonymous sum type_. + The `Either` type is used to represent an _anonymous sum type_. Similar to [`Cons`](crate::types::Cons), `Either` is used to form a sum type by combining a chain of `Either` types, and terminated with a [`Void`] type. But unlike product types, a sum type has values that belong to one of the variants in the list. - `Either` is also shown as `σ`, together with [`Void`] shown as `θ`, to improve - the readability of compiler error messages. Through the shortened name, a sum - type would take slightly less space, making it more likely to fit on a single - line for the user to read what the type is. - `Either` is most often used through the `Sum!` macro, which accepts a list of types and turns them into a chain of `Either` types. @@ -27,21 +22,15 @@ ```rust,ignore type MyUnion = Either>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type MyUnion = σ>>; - ``` */ #[derive(Eq, PartialEq, Debug, Clone)] -pub enum σ { +pub enum Either { Left(Head), Right(Tail), } /** - The `Void` type, a.k.a. `θ`, is used to represent the end of an _anonymous sum type_, + The `Void` type is used to represent the end of an _anonymous sum type_, or an _empty_ sum type. `Void` is commonly used as the `Tail` of a [`Either`] type, to terminate the list. @@ -57,7 +46,4 @@ pub enum σ { Read more about sum types in [`Either`]. */ #[derive(Eq, PartialEq, Debug, Clone)] -pub enum θ {} - -pub use θ as Void; -pub use σ as Either; +pub enum Void {} diff --git a/crates/macros/cgp-macro-core/src/exports.rs b/crates/macros/cgp-macro-core/src/exports.rs index 840f31a4..35a81199 100644 --- a/crates/macros/cgp-macro-core/src/exports.rs +++ b/crates/macros/cgp-macro-core/src/exports.rs @@ -16,12 +16,21 @@ export_constructs! { IsProviderFor, CanUseComponent, UseContext, + UseType, + TypeProvider, + WithProvider, + UseFields, + UseField, Life, HasField, HasFields, HasFieldsRef, HasFieldMut, + FieldGetter, + MutFieldGetter, + FromFields, + FromVariant, HasBuilder, HasExtractor, HasExtractorRef, diff --git a/crates/macros/cgp-macro-core/src/lib.rs b/crates/macros/cgp-macro-core/src/lib.rs index 7ac9a313..694d7518 100644 --- a/crates/macros/cgp-macro-core/src/lib.rs +++ b/crates/macros/cgp-macro-core/src/lib.rs @@ -1,5 +1,3 @@ -#![allow(mixed_script_confusables)] - pub mod exports; pub mod functions; pub mod macros; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs index bc514c0f..9d2e9369 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extract_field_impls.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{Arm, GenericArgument, Ident, ItemEnum, ItemImpl, Type, parse2}; -use crate::exports::ExtractField; +use crate::exports::{ExtractField, IsPresent, IsVoid, MapType, MapTypeRef}; use crate::types::cgp_data::{get_variant_type, index_to_generic_ident, to_generic_args}; use crate::types::field::Symbol; @@ -26,7 +26,7 @@ pub fn derive_extract_field_impls( generics.params.insert( 1, parse2(quote! { - __R__: MapTypeRef + __R__: #MapTypeRef })?, ); } @@ -49,7 +49,7 @@ pub fn derive_extract_field_impls( let generic_param_name = index_to_generic_ident(other_index); generics.params.push(parse2(quote! { - #generic_param_name: MapType + #generic_param_name: #MapType })?); let generic_arg: GenericArgument = parse2(quote! { #generic_param_name })?; @@ -62,8 +62,8 @@ pub fn derive_extract_field_impls( } })?); } else { - source_generic_args.push(parse2(quote! { IsPresent })?); - output_generic_args.push(parse2(quote! { IsVoid })?); + source_generic_args.push(parse2(quote! { #IsPresent })?); + output_generic_args.push(parse2(quote! { #IsVoid })?); match_arms.push(parse2(quote! { #extractor_ident :: #variant_ident ( value ) => { @@ -77,7 +77,7 @@ pub fn derive_extract_field_impls( let value_type = get_variant_type(current_variant)?; if is_ref { - parse2(quote! { <__R__ as MapTypeRef>::Map<'__a__, #value_type> })? + parse2(quote! { <__R__ as #MapTypeRef>::Map<'__a__, #value_type> })? } else { value_type.clone() } diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs index ce6e5f73..625c660e 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_extractor/extractor_enum.rs @@ -21,7 +21,7 @@ pub fn derive_extractor_enum( let generic_param_name = index_to_generic_ident(i); let generic_param: TypeParam = parse2(quote! { - #generic_param_name : MapType + #generic_param_name : #MapType })?; generics.params.push(GenericParam::Type(generic_param)); @@ -29,7 +29,7 @@ pub fn derive_extractor_enum( let field_type = get_variant_type(variant)?; let mapped_type: Type = parse2(quote! { - <#generic_param_name as MapType>::Map<#field_type> + <#generic_param_name as #MapType>::Map<#field_type> })?; variant.fields = type_to_variant_fields(&mapped_type); diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs index 80d8aba8..0891e853 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_from_variant.rs @@ -1,5 +1,6 @@ use syn::{ItemEnum, ItemImpl}; +use crate::exports::FromVariant; use crate::parse_internal; use crate::types::cgp_data::get_variant_type; use crate::types::field::Symbol; @@ -17,7 +18,7 @@ pub fn derive_from_variant_from_enum(item_enum: &ItemEnum) -> syn::Result for #enum_ident #ty_generics + impl #impl_generics #FromVariant<#variant_tag> for #enum_ident #ty_generics #where_clause { type Value = #variant_type; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs index f1348474..f7a84da7 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_field.rs @@ -1,6 +1,7 @@ use syn::spanned::Spanned; use syn::{Fields, ItemImpl, ItemStruct, LitInt}; +use crate::exports::{HasField, HasFieldMut}; use crate::parse_internal; use crate::types::field::{Index, Symbol}; @@ -21,7 +22,7 @@ pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Resu let field_type = &field.ty; let has_field_impl: ItemImpl = parse_internal! { - impl #impl_generics HasField< #field_symbol > + impl #impl_generics #HasField< #field_symbol > for #struct_ident #ty_generics #where_clause { @@ -38,7 +39,7 @@ pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Resu }; let has_field_mut_impl: ItemImpl = parse_internal! { - impl #impl_generics HasFieldMut< #field_symbol > + impl #impl_generics #HasFieldMut< #field_symbol > for #struct_ident #ty_generics #where_clause { @@ -68,7 +69,7 @@ pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Resu let field_type = &field.ty; let has_field_impl: ItemImpl = parse_internal! { - impl #impl_generics HasField< #field_tag > + impl #impl_generics #HasField< #field_tag > for #struct_ident #ty_generics #where_clause { @@ -85,7 +86,7 @@ pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> syn::Resu }; let has_field_mut_impl: ItemImpl = parse_internal! { - impl #impl_generics HasFieldMut< #field_tag > + impl #impl_generics #HasFieldMut< #field_tag > for #struct_ident #ty_generics #where_clause { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs index a605b145..90ea9929 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/from_fields_enum.rs @@ -1,7 +1,7 @@ use quote::quote; use syn::{ItemEnum, ItemImpl, parse2}; -use crate::exports::Either; +use crate::exports::{Either, FromFields}; use crate::types::cgp_data::derive_from_field_params; pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result { @@ -32,7 +32,7 @@ pub fn derive_from_fields_for_enum(item_enum: &ItemEnum) -> syn::Result syn::Result { let struct_name = &item_struct.ident; @@ -13,7 +13,7 @@ pub fn derive_from_fields_for_struct(item_struct: &ItemStruct) -> syn::Result syn::Result<(TokenStream, To })?; fields_arg = quote! { - π( #field_name, #fields_arg ) + #Cons( #field_name, #fields_arg ) }; constructor_args = quote! { @@ -62,7 +62,7 @@ pub fn derive_from_field_params(fields: &Fields) -> syn::Result<(TokenStream, To Ok((fields_arg, constructor_args)) } else { - let mut fields_arg = quote! { ε }; + let mut fields_arg = quote! { #Nil }; let mut constructor_args = quote! {}; for (i, field) in fields.unnamed.iter().enumerate() { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs index bed3d33b..44e323dd 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/product.rs @@ -3,11 +3,11 @@ use quote::quote; use syn::spanned::Spanned; use syn::{Error, Fields, LitInt, Type, parse2}; -use crate::exports::{Cons, Field, Index}; +use crate::exports::{Cons, Field, Index, Nil}; use crate::types::field::Symbol; pub fn item_fields_to_product_type(fields: &Fields, reference: &TokenStream) -> syn::Result { - let mut fields_type = quote! { ε }; + let mut fields_type = quote! { #Nil }; match fields { Fields::Named(fields) => { diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs index 22ff32ed..e1007ae3 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/sum.rs @@ -4,7 +4,7 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{Type, Variant, parse2}; -use crate::exports::{Either, Field}; +use crate::exports::{Either, Field, Void}; use crate::types::cgp_data::item_fields_to_product_type; use crate::types::field::Symbol; @@ -12,7 +12,7 @@ pub fn variants_to_sum_type( variants: &Punctuated, reference: &TokenStream, ) -> syn::Result { - let mut out = quote! { θ }; + let mut out = quote! { #Void }; for variant in variants.iter().rev() { let variant_ident = &variant.ident; diff --git a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs index 34c75114..e9c92173 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_data/derive_has_fields/to_fields_struct.rs @@ -3,7 +3,7 @@ use quote::{ToTokens, quote}; use syn::spanned::Spanned; use syn::{Error, Fields, Ident, ItemImpl, ItemStruct, LitInt, parse2}; -use crate::exports::{Cons, ToFields}; +use crate::exports::{Cons, Nil, ToFields}; pub fn derive_to_fields_for_struct(item_struct: &ItemStruct) -> syn::Result { let struct_name = &item_struct.ident; @@ -55,7 +55,7 @@ pub fn derive_to_fields_constructor( fields: &Fields, construct_field: impl Fn(FieldLabel) -> TokenStream, ) -> syn::Result { - let mut constructors = quote! { ε }; + let mut constructors = quote! { #Nil }; match &fields { Fields::Named(fields) => { @@ -67,7 +67,7 @@ pub fn derive_to_fields_constructor( let constructor = construct_field(FieldLabel::Named(field_name)); constructors = quote! { - π( + #Cons( #constructor, #constructors ) diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs index 18fa6484..e4b0454e 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/to_use_fields_impl.rs @@ -1,6 +1,7 @@ use quote::ToTokens; use syn::{ImplItem, ItemImpl, Type}; +use crate::exports::UseFields; use crate::functions::parse_internal; use crate::types::cgp_getter::{ItemCgpGetter, ReceiverMode}; use crate::types::field::{HasFieldBound, Symbol}; @@ -88,7 +89,7 @@ impl ItemCgpGetter { let (impl_generics, _, where_clause) = provider_generics.split_for_impl(); let item_impl: ItemImpl = parse_internal! { - impl #impl_generics #provider_name #type_generics for UseFields + impl #impl_generics #provider_name #type_generics for #UseFields #where_clause { #( #items )* diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs index 533f4c9e..922398b1 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/use_field.rs @@ -4,6 +4,7 @@ use syn::punctuated::Punctuated; use syn::token::Plus; use syn::{Generics, ItemImpl, Type, TypeParamBound}; +use crate::exports::UseField; use crate::functions::parse_internal; use crate::types::cgp_getter::{GetterField, ItemCgpGetter, ReceiverMode}; use crate::types::field::HasFieldBound; @@ -112,7 +113,7 @@ impl ItemCgpGetter { }; let use_field_impl: ItemImpl = parse_internal! { - impl #impl_generics #provider_name #type_generics for UseField< #tag_type > + impl #impl_generics #provider_name #type_generics for #UseField< #tag_type > #where_clause { #items diff --git a/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs b/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs index eefd22be..0ed6ec96 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_getter/with_provider.rs @@ -2,6 +2,7 @@ use proc_macro2::Span; use quote::{ToTokens, quote}; use syn::{Generics, Ident, ImplItem, ItemImpl}; +use crate::exports::{FieldGetter, MutFieldGetter, WithProvider}; use crate::functions::parse_internal; use crate::types::cgp_getter::{GetterField, ItemCgpGetter, ReceiverMode}; use crate::types::getter::{ContextArg, FieldMode, derive_getter_method}; @@ -81,16 +82,16 @@ impl ItemCgpGetter { let provider_constraint = if field.receiver_mut.is_none() { if let FieldMode::Slice = field.field_mode { quote! { - FieldGetter< #receiver_type, #component_name, Value: AsRef< [ #field_type ] > + 'static > + #FieldGetter< #receiver_type, #component_name, Value: AsRef< [ #field_type ] > + 'static > } } else { quote! { - FieldGetter< #receiver_type, #component_name , Value = #field_type > + #FieldGetter< #receiver_type, #component_name , Value = #field_type > } } } else { quote! { - MutFieldGetter< #receiver_type, #component_name, Value = #field_type > + #MutFieldGetter< #receiver_type, #component_name, Value = #field_type > } }; @@ -118,7 +119,7 @@ impl ItemCgpGetter { }; let out = parse_internal! { - impl #impl_generics #provider_name #type_generics for WithProvider< #provider_ident > + impl #impl_generics #provider_name #type_generics for #WithProvider< #provider_ident > #where_clause { #( #items )* diff --git a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs index c6c2cd39..d13522bc 100644 --- a/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs +++ b/crates/macros/cgp-macro-core/src/types/cgp_type/item.rs @@ -1,6 +1,7 @@ use syn::spanned::Spanned; use syn::{Error, Item, ItemImpl, ItemTrait, TraitItem, TraitItemType}; +use crate::exports::{TypeProvider, UseType, WithProvider}; use crate::parse_internal; use crate::types::cgp_component::EvaluatedCgpComponent; use crate::types::provider_impl::{ItemProviderImpl, ItemProviderImpls}; @@ -56,7 +57,7 @@ impl ItemCgpType { let use_type_impl: ItemImpl = parse_internal! { impl #impl_generics #provider_trait_name #type_generics - for UseType< #type_name > + for #UseType< #type_name > #where_clause { type #type_name = #type_name; @@ -73,7 +74,7 @@ impl ItemCgpType { .make_where_clause() .predicates .push(parse_internal! { - __Provider__: TypeProvider< #context_name, #component_type, Type = #type_name > + __Provider__: #TypeProvider< #context_name, #component_type, Type = #type_name > }); let (impl_generics, _, where_clause) = generics.split_for_impl(); @@ -81,7 +82,7 @@ impl ItemCgpType { let with_provider_impl: ItemImpl = parse_internal! { impl #impl_generics #provider_trait_name #type_generics - for WithProvider< __Provider__ > + for #WithProvider< __Provider__ > #where_clause { type #type_name = #type_name; diff --git a/crates/macros/cgp-macro-core/src/types/check_components/table.rs b/crates/macros/cgp-macro-core/src/types/check_components/table.rs index 16ea61f8..93fdbf1f 100644 --- a/crates/macros/cgp-macro-core/src/types/check_components/table.rs +++ b/crates/macros/cgp-macro-core/src/types/check_components/table.rs @@ -6,7 +6,7 @@ use syn::spanned::Spanned; use syn::token::{Comma, Lt, Pound, Where}; use syn::{Attribute, Ident, Item, ItemImpl, ItemTrait, Type, WhereClause, braced, parse2}; -use crate::exports::CanUseComponent; +use crate::exports::{CanUseComponent, IsProviderFor}; use crate::functions::merge_generics; use crate::parse_internal; use crate::types::check_components::{CheckEntries, EvaluatedCheckEntry, TypeWithGenerics}; @@ -43,7 +43,7 @@ impl CheckComponentsTable { let item_trait: ItemTrait = if self.check_providers.is_some() { parse_internal! { - trait #trait_name <__Component__, __Params__: ?Sized>: IsProviderFor<__Component__, #context_type, __Params__> {} + trait #trait_name <__Component__, __Params__: ?Sized>: #IsProviderFor<__Component__, #context_type, __Params__> {} } } else { parse_internal! { diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index 31c4e62c..aef7ae3a 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -751,12 +751,6 @@ pub fn blanket_trait(attr: TokenStream, item: TokenStream) -> TokenStream { ```rust,ignore type Hello = Char<'h', Char<'e', Char<'l', Char<'l', Char<'o', Nil>>>>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type Hello = ζ<'h', ζ<'e', ζ<'l', ζ<'l', ζ<'o', ε>>>>>; - ``` */ #[proc_macro] #[allow(non_snake_case)] @@ -787,12 +781,6 @@ pub fn Symbol(body: TokenStream) -> TokenStream { ```rust,ignore type MyTypes = Cons>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type MyTypes = π>>; - ``` */ #[proc_macro] #[allow(non_snake_case)] @@ -831,12 +819,6 @@ pub fn product(body: TokenStream) -> TokenStream { ```rust,ignore type MyUnion = Either>>; ``` - - which would be shown with the shortened representation as: - - ```rust,ignore - type MyUnion = σ>>; - ``` */ #[proc_macro] #[allow(non_snake_case)] diff --git a/crates/main/cgp-base-extra/Cargo.toml b/crates/main/cgp-base-extra/Cargo.toml new file mode 100644 index 00000000..d382fb09 --- /dev/null +++ b/crates/main/cgp-base-extra/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "cgp-base-extra" +version = "0.7.0" +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +authors = { workspace = true } +rust-version = { workspace = true } +keywords = { workspace = true } + +[dependencies] +cgp-base = { workspace = true } +cgp-type = { workspace = true } diff --git a/crates/main/cgp-base-extra/src/lib.rs b/crates/main/cgp-base-extra/src/lib.rs new file mode 100644 index 00000000..0683d3ad --- /dev/null +++ b/crates/main/cgp-base-extra/src/lib.rs @@ -0,0 +1,6 @@ +#![no_std] + +pub mod macro_prelude; + +pub use cgp_base::{base_types, component}; +pub use cgp_type as types; diff --git a/crates/main/cgp-base-extra/src/macro_prelude.rs b/crates/main/cgp-base-extra/src/macro_prelude.rs new file mode 100644 index 00000000..00048498 --- /dev/null +++ b/crates/main/cgp-base-extra/src/macro_prelude.rs @@ -0,0 +1,5 @@ +pub use cgp_base::macro_prelude::*; +pub use cgp_type::{ + HasType, TypeOf, TypeProvider, TypeProviderComponent, UseDelegatedType, UseType, + WithDelegatedType, WithType, +}; diff --git a/crates/main/cgp-base/src/lib.rs b/crates/main/cgp-base/src/lib.rs index 52669be9..b33a4759 100644 --- a/crates/main/cgp-base/src/lib.rs +++ b/crates/main/cgp-base/src/lib.rs @@ -1 +1,4 @@ pub mod macro_prelude; + +pub use cgp_base_types as base_types; +pub use cgp_component as component; diff --git a/crates/main/cgp-core/src/prelude.rs b/crates/main/cgp-core/src/prelude.rs index 59101d49..3f779db3 100644 --- a/crates/main/cgp-core/src/prelude.rs +++ b/crates/main/cgp-core/src/prelude.rs @@ -14,9 +14,7 @@ pub use cgp_field::traits::{ HasFieldsRef, IntoBuilder, MapType, MapTypeRef, MutFieldGetter, PartialData, ToFields, ToFieldsRef, UpdateField, }; -pub use cgp_field::types::{ - Chars, Cons, Either, Field, Index, Life, Nil, Symbol, Void, δ, ε, ζ, θ, π, σ, ψ, ω, -}; +pub use cgp_field::types::{Chars, Cons, Either, Field, Index, Life, Nil, Symbol, Void}; pub use cgp_macro::{ BuildField, CgpData, CgpRecord, CgpVariant, ExtractField, FromVariant, HasField, HasFields, Product, Sum, Symbol, cgp_auto_getter, cgp_component, cgp_fn, cgp_getter, cgp_impl, diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index e400657c..2b8dde10 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; snapshot_cgp_type! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 32deee46..0e226cec 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -1,6 +1,5 @@ use std::fmt::Display; -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; snapshot_cgp_type! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index f74ec61e..b813d18a 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -1,6 +1,5 @@ use std::ops::Mul; -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; snapshot_cgp_type! { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs index 1db917c9..074818b1 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/enum_fields.rs @@ -44,7 +44,7 @@ pub mod simple_enum { >, String, >, - θ, + Void, >, >; } @@ -80,7 +80,7 @@ pub mod simple_enum { >, &'__a String, >, - θ, + Void, >, > where @@ -206,7 +206,7 @@ pub mod generic_enum { >, &'a Name, >, - θ, + Void, >, >; } @@ -242,7 +242,7 @@ pub mod generic_enum { >, &'__a &'a Name, >, - θ, + Void, >, > where diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs index 6038af45..adcb2dc1 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/has_fields/struct_fields.rs @@ -14,7 +14,7 @@ pub mod single_name_field { impl HasFields for Person { type Fields = Cons< Field>>>>, String>, - ε, + Nil, >; } impl HasFieldsRef for Person { @@ -23,19 +23,19 @@ pub mod single_name_field { Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, &'__a String, >, - ε, + Nil, > where Self: '__a; } impl FromFields for Person { - fn from_fields(π(name, Nil): Self::Fields) -> Self { + fn from_fields(Cons(name, Nil): Self::Fields) -> Self { Self { name: name.value } } } impl ToFields for Person { fn to_fields(self) -> Self::Fields { - π(self.name.into(), ε) + Cons(self.name.into(), Nil) } } impl ToFieldsRef for Person { @@ -43,7 +43,7 @@ pub mod single_name_field { where Self: '__a, { - π((&self.name).into(), ε) + Cons((&self.name).into(), Nil) } } ") @@ -85,7 +85,7 @@ pub mod two_named_field { impl HasFields for Person { type Fields = Cons< Field>>>>, String>, - Cons>>>, u8>, ε>, + Cons>>>, u8>, Nil>, >; } impl HasFieldsRef for Person { @@ -94,13 +94,13 @@ pub mod two_named_field { Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, &'__a String, >, - Cons>>>, &'__a u8>, ε>, + Cons>>>, &'__a u8>, Nil>, > where Self: '__a; } impl FromFields for Person { - fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(name, Cons(age, Nil)): Self::Fields) -> Self { Self { name: name.value, age: age.value, @@ -109,7 +109,7 @@ pub mod two_named_field { } impl ToFields for Person { fn to_fields(self) -> Self::Fields { - π(self.name.into(), π(self.age.into(), ε)) + Cons(self.name.into(), Cons(self.age.into(), Nil)) } } impl ToFieldsRef for Person { @@ -117,7 +117,7 @@ pub mod two_named_field { where Self: '__a, { - π((&self.name).into(), π((&self.age).into(), ε)) + Cons((&self.name).into(), Cons((&self.age).into(), Nil)) } } ") @@ -170,7 +170,7 @@ pub mod generic_struct { { type Fields = Cons< Field>>>>, Name>, - Cons>>>, u8>, ε>, + Cons>>>, u8>, Nil>, >; } impl HasFieldsRef for Person @@ -182,7 +182,7 @@ pub mod generic_struct { Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, &'__a Name, >, - Cons>>>, &'__a u8>, ε>, + Cons>>>, &'__a u8>, Nil>, > where Self: '__a; @@ -191,7 +191,7 @@ pub mod generic_struct { where Name: Display, { - fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(name, Cons(age, Nil)): Self::Fields) -> Self { Self { name: name.value, age: age.value, @@ -203,7 +203,7 @@ pub mod generic_struct { Name: Display, { fn to_fields(self) -> Self::Fields { - π(self.name.into(), π(self.age.into(), ε)) + Cons(self.name.into(), Cons(self.age.into(), Nil)) } } impl ToFieldsRef for Person @@ -214,7 +214,7 @@ pub mod generic_struct { where Self: '__a, { - π((&self.name).into(), π((&self.age).into(), ε)) + Cons((&self.name).into(), Cons((&self.age).into(), Nil)) } } ") @@ -267,7 +267,7 @@ pub mod generic_lifetime_struct { { type Fields = Cons< Field>>>>, &'a Name>, - Cons>>>, &'a u8>, ε>, + Cons>>>, &'a u8>, Nil>, >; } impl<'a, Name> HasFieldsRef for Person<'a, Name> @@ -279,7 +279,10 @@ pub mod generic_lifetime_struct { Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, &'__a &'a Name, >, - Cons>>>, &'__a &'a u8>, ε>, + Cons< + Field>>>, &'__a &'a u8>, + Nil, + >, > where Self: '__a; @@ -288,7 +291,7 @@ pub mod generic_lifetime_struct { where Name: Display, { - fn from_fields(π(name, π(age, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(name, Cons(age, Nil)): Self::Fields) -> Self { Self { name: name.value, age: age.value, @@ -300,7 +303,7 @@ pub mod generic_lifetime_struct { Name: Display, { fn to_fields(self) -> Self::Fields { - π(self.name.into(), π(self.age.into(), ε)) + Cons(self.name.into(), Cons(self.age.into(), Nil)) } } impl<'a, Name> ToFieldsRef for Person<'a, Name> @@ -311,7 +314,7 @@ pub mod generic_lifetime_struct { where Self: '__a, { - π((&self.name).into(), π((&self.age).into(), ε)) + Cons((&self.name).into(), Cons((&self.age).into(), Nil)) } } ") @@ -408,24 +411,24 @@ pub mod single_unnamed_multi_field { expand_person(output) { insta::assert_snapshot!(output, @" impl HasFields for Person { - type Fields = Cons, String>, Cons, u8>, ε>>; + type Fields = Cons, String>, Cons, u8>, Nil>>; } impl HasFieldsRef for Person { type FieldsRef<'__a> = Cons< Field, &'__a String>, - Cons, &'__a u8>, ε>, + Cons, &'__a u8>, Nil>, > where Self: '__a; } impl FromFields for Person { - fn from_fields(Cons(field_1, Cons(field_0, ε)): Self::Fields) -> Self { + fn from_fields(Cons(field_1, Cons(field_0, Nil)): Self::Fields) -> Self { Self(field_1.value, field_0.value) } } impl ToFields for Person { fn to_fields(self) -> Self::Fields { - Cons(self.0.into(), Cons(self.1.into(), ε)) + Cons(self.0.into(), Cons(self.1.into(), Nil)) } } impl ToFieldsRef for Person { @@ -433,7 +436,7 @@ pub mod single_unnamed_multi_field { where Self: '__a, { - Cons((&self.0).into(), Cons((&self.1).into(), ε)) + Cons((&self.0).into(), Cons((&self.1).into(), Nil)) } } ") diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs index 257cac39..01693cd6 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs @@ -87,7 +87,7 @@ snapshot_derive_cgp_data! { Field>>>, u64>, Cons< Field>>>, String>, - Cons>>>, bool>, ε>, + Cons>>>, bool>, Nil>, >, >; } @@ -98,7 +98,7 @@ snapshot_derive_cgp_data! { Field>>>, &'__a String>, Cons< Field>>>, &'__a bool>, - ε, + Nil, >, >, > @@ -106,7 +106,7 @@ snapshot_derive_cgp_data! { Self: '__a; } impl FromFields for FooBarBaz { - fn from_fields(π(foo, π(bar, π(baz, Nil))): Self::Fields) -> Self { + fn from_fields(Cons(foo, Cons(bar, Cons(baz, Nil))): Self::Fields) -> Self { Self { foo: foo.value, bar: bar.value, @@ -116,7 +116,7 @@ snapshot_derive_cgp_data! { } impl ToFields for FooBarBaz { fn to_fields(self) -> Self::Fields { - π(self.foo.into(), π(self.bar.into(), π(self.baz.into(), ε))) + Cons(self.foo.into(), Cons(self.bar.into(), Cons(self.baz.into(), Nil))) } } impl ToFieldsRef for FooBarBaz { @@ -124,7 +124,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - π((&self.foo).into(), π((&self.bar).into(), π((&self.baz).into(), ε))) + Cons((&self.foo).into(), Cons((&self.bar).into(), Cons((&self.baz).into(), Nil))) } } pub struct __PartialFooBarBaz<__F0__: MapType, __F1__: MapType, __F2__: MapType> { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs index 43fd78ec..8c08ff53 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/generics.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::snapshot_derive_cgp_data; snapshot_derive_cgp_data! { @@ -109,7 +108,7 @@ snapshot_derive_cgp_data! { Field>>>, Foo>, Cons< Field>>>, Bar>, - Cons>>>, Baz>, ε>, + Cons>>>, Baz>, Nil>, >, >; } @@ -123,7 +122,7 @@ snapshot_derive_cgp_data! { Field>>>, &'__a Bar>, Cons< Field>>>, &'__a Baz>, - ε, + Nil, >, >, > @@ -134,7 +133,7 @@ snapshot_derive_cgp_data! { where Foo: Clone, { - fn from_fields(π(foo, π(bar, π(baz, Nil))): Self::Fields) -> Self { + fn from_fields(Cons(foo, Cons(bar, Cons(baz, Nil))): Self::Fields) -> Self { Self { foo: foo.value, bar: bar.value, @@ -147,7 +146,7 @@ snapshot_derive_cgp_data! { Foo: Clone, { fn to_fields(self) -> Self::Fields { - π(self.foo.into(), π(self.bar.into(), π(self.baz.into(), ε))) + Cons(self.foo.into(), Cons(self.bar.into(), Cons(self.baz.into(), Nil))) } } impl ToFieldsRef for Context @@ -158,7 +157,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - π((&self.foo).into(), π((&self.bar).into(), π((&self.baz).into(), ε))) + Cons((&self.foo).into(), Cons((&self.bar).into(), Cons((&self.baz).into(), Nil))) } } pub struct __PartialContext< diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs index 8fed369e..dd82fc18 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/index.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::snapshot_derive_cgp_data; snapshot_derive_cgp_data! { @@ -52,27 +51,27 @@ snapshot_derive_cgp_data! { impl HasFields for Context { type Fields = Cons< Field, u64>, - Cons, String>, Cons, bool>, ε>>, + Cons, String>, Cons, bool>, Nil>>, >; } impl HasFieldsRef for Context { type FieldsRef<'__a> = Cons< Field, &'__a u64>, - Cons, &'__a String>, Cons, &'__a bool>, ε>>, + Cons, &'__a String>, Cons, &'__a bool>, Nil>>, > where Self: '__a; } impl FromFields for Context { fn from_fields( - Cons(field_2, Cons(field_1, Cons(field_0, ε))): Self::Fields, + Cons(field_2, Cons(field_1, Cons(field_0, Nil))): Self::Fields, ) -> Self { Self(field_2.value, field_1.value, field_0.value) } } impl ToFields for Context { fn to_fields(self) -> Self::Fields { - Cons(self.0.into(), Cons(self.1.into(), Cons(self.2.into(), ε))) + Cons(self.0.into(), Cons(self.1.into(), Cons(self.2.into(), Nil))) } } impl ToFieldsRef for Context { @@ -80,7 +79,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - Cons((&self.0).into(), Cons((&self.1).into(), Cons((&self.2).into(), ε))) + Cons((&self.0).into(), Cons((&self.1).into(), Cons((&self.2).into(), Nil))) } } pub struct __PartialContext<__F0__: MapType, __F1__: MapType, __F2__: MapType>( diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs index 3d7b6e04..4c329a81 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/optional.rs @@ -58,19 +58,19 @@ snapshot_derive_cgp_data! { impl HasFields for Context { type Fields = Cons< Field>>>, String>, - Cons>>>, u64>, ε>, + Cons>>>, u64>, Nil>, >; } impl HasFieldsRef for Context { type FieldsRef<'__a> = Cons< Field>>>, &'__a String>, - Cons>>>, &'__a u64>, ε>, + Cons>>>, &'__a u64>, Nil>, > where Self: '__a; } impl FromFields for Context { - fn from_fields(π(foo, π(bar, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(foo, Cons(bar, Nil)): Self::Fields) -> Self { Self { foo: foo.value, bar: bar.value, @@ -79,7 +79,7 @@ snapshot_derive_cgp_data! { } impl ToFields for Context { fn to_fields(self) -> Self::Fields { - π(self.foo.into(), π(self.bar.into(), ε)) + Cons(self.foo.into(), Cons(self.bar.into(), Nil)) } } impl ToFieldsRef for Context { @@ -87,7 +87,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - π((&self.foo).into(), π((&self.bar).into(), ε)) + Cons((&self.foo).into(), Cons((&self.bar).into(), Nil)) } } pub struct __PartialContext<__F0__: MapType, __F1__: MapType> { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs index 69e11ffa..e032058d 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/person.rs @@ -262,7 +262,7 @@ snapshot_derive_cgp_data! { >, String, >, - ε, + Nil, >, >; } @@ -316,14 +316,14 @@ snapshot_derive_cgp_data! { >, &'__a String, >, - ε, + Nil, >, > where Self: '__a; } impl FromFields for Person { - fn from_fields(π(first_name, π(last_name, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(first_name, Cons(last_name, Nil)): Self::Fields) -> Self { Self { first_name: first_name.value, last_name: last_name.value, @@ -332,7 +332,7 @@ snapshot_derive_cgp_data! { } impl ToFields for Person { fn to_fields(self) -> Self::Fields { - π(self.first_name.into(), π(self.last_name.into(), ε)) + Cons(self.first_name.into(), Cons(self.last_name.into(), Nil)) } } impl ToFieldsRef for Person { @@ -340,7 +340,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - π((&self.first_name).into(), π((&self.last_name).into(), ε)) + Cons((&self.first_name).into(), Cons((&self.last_name).into(), Nil)) } } pub struct __PartialPerson<__F0__: MapType, __F1__: MapType> { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs index 992706ec..26db2aee 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/point.rs @@ -49,25 +49,25 @@ snapshot_derive_cgp_data! { impl HasFields for Point2d { type Fields = Cons< Field>, u64>, - Cons>, u64>, ε>, + Cons>, u64>, Nil>, >; } impl HasFieldsRef for Point2d { type FieldsRef<'__a> = Cons< Field>, &'__a u64>, - Cons>, &'__a u64>, ε>, + Cons>, &'__a u64>, Nil>, > where Self: '__a; } impl FromFields for Point2d { - fn from_fields(π(x, π(y, Nil)): Self::Fields) -> Self { + fn from_fields(Cons(x, Cons(y, Nil)): Self::Fields) -> Self { Self { x: x.value, y: y.value } } } impl ToFields for Point2d { fn to_fields(self) -> Self::Fields { - π(self.x.into(), π(self.y.into(), ε)) + Cons(self.x.into(), Cons(self.y.into(), Nil)) } } impl ToFieldsRef for Point2d { @@ -75,7 +75,7 @@ snapshot_derive_cgp_data! { where Self: '__a, { - π((&self.x).into(), π((&self.y).into(), ε)) + Cons((&self.x).into(), Cons((&self.y).into(), Nil)) } } struct __PartialPoint2d<__F0__: MapType, __F1__: MapType> { diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs index 25fcb5b1..932e734e 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs @@ -33,7 +33,7 @@ snapshot_derive_cgp_data! { Field>>>, u64>, Either< Field>>>, String>, - Either>>>, bool>, θ>, + Either>>>, bool>, Void>, >, >; } @@ -44,7 +44,7 @@ snapshot_derive_cgp_data! { Field>>>, &'__a String>, Either< Field>>>, &'__a bool>, - θ, + Void, >, >, > diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs index b6cd23b7..c0ab9c7d 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/generic.rs @@ -18,7 +18,7 @@ snapshot_derive_cgp_data! { Field>>>, Foo>, Either< Field>>>, Bar>, - Either>>>, Baz>, θ>, + Either>>>, Baz>, Void>, >, >; } @@ -29,7 +29,7 @@ snapshot_derive_cgp_data! { Field>>>, &'__a Bar>, Either< Field>>>, &'__a Baz>, - θ, + Void, >, >, > diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs index 171a49e7..7a98bf4a 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs @@ -57,7 +57,7 @@ snapshot_derive_cgp_data! { >, Rectangle, >, - θ, + Void, >, >; } @@ -96,7 +96,7 @@ snapshot_derive_cgp_data! { >, &'__a Rectangle, >, - θ, + Void, >, > where diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs index 655556c5..ce61576e 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; snapshot_cgp_type! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs index 7feed36d..ef603bbb 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; snapshot_cgp_type! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs index 7feed36d..ef603bbb 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs @@ -1,4 +1,3 @@ -use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; snapshot_cgp_type! {