diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-05-16 22:31:52 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-05-16 22:31:52 +0800 |
| commit | 60b91db3df168532f9143f0cafb7b5166e1dc78b (patch) | |
| tree | ddb10f909a46033af16d725ab0dae8385227b985 /mingling_macros/src/pack.rs | |
| parent | 05d07bbc627b59fd07a8764a972b4aac63a46f53 (diff) | |
Accept paths for program name parameters in macros
All proc macros (`pack!`, `dispatcher!`, `#[chain]`, `#[program_setup]`,
`#[dispatcher_clap]`, `#[derive(Groupped)]`) now parse program names as
`syn::Path` instead of bare `Ident`, allowing use of paths like
`crate::MyProgram` or `my_crate::MyProgram`.
The default program name `ThisProgram` is no longer re-exported or
required
as an import — generated code references `crate::ThisProgram` directly.
Diffstat (limited to 'mingling_macros/src/pack.rs')
| -rw-r--r-- | mingling_macros/src/pack.rs | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/mingling_macros/src/pack.rs b/mingling_macros/src/pack.rs index 1c0bb7b..657f1bb 100644 --- a/mingling_macros/src/pack.rs +++ b/mingling_macros/src/pack.rs @@ -3,11 +3,9 @@ use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::{Ident, Result as SynResult, Token, Type}; -use crate::DEFAULT_PROGRAM_NAME; - enum PackInput { Explicit { - group_name: Ident, + group_name: syn::Path, type_name: Ident, inner_type: Type, }, @@ -19,12 +17,18 @@ enum PackInput { impl Parse for PackInput { fn parse(input: ParseStream) -> SynResult<Self> { - // Try to parse as explicit format first: GroupName, TypeName = InnerType - let lookahead = input.lookahead1(); - - if lookahead.peek(Ident) && input.peek2(Token![,]) { - // Explicit format: GroupName, TypeName = InnerType - let group_name = input.parse()?; + // Look ahead to determine format: + // - `Path, TypeName = InnerType` → Explicit + // - `TypeName = InnerType` → Default + // + // Both start with an ident. We peek at the second token: + // if it's a `,` or `::`, it's explicit; if it's `=`, it's default. + + if (input.peek(Ident) || input.peek(Token![crate])) + && (input.peek2(Token![,]) || input.peek2(Token![::])) + { + // Explicit format: Path, TypeName = InnerType + let group_name = input.parse::<syn::Path>()?; input.parse::<Token![,]>()?; let type_name = input.parse()?; input.parse::<Token![=]>()?; @@ -35,7 +39,7 @@ impl Parse for PackInput { type_name, inner_type, }) - } else if lookahead.peek(Ident) && input.peek2(Token![=]) { + } else if input.peek(Ident) && input.peek2(Token![=]) { // Default format: TypeName = InnerType let type_name = input.parse()?; input.parse::<Token![=]>()?; @@ -46,14 +50,12 @@ impl Parse for PackInput { inner_type, }) } else { - Err(lookahead.error()) + Err(input.lookahead1().error()) } } } pub fn pack(input: TokenStream) -> TokenStream { - let default_program_path = crate::default_program_path(); - // Parse the input let pack_input = syn::parse_macro_input!(input as PackInput); @@ -63,16 +65,11 @@ pub fn pack(input: TokenStream) -> TokenStream { group_name, type_name, inner_type, - } => (group_name, type_name, inner_type, false), + } => (quote! { #group_name }, type_name, inner_type, false), PackInput::Default { type_name, inner_type, - } => ( - Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()), - type_name, - inner_type, - true, - ), + } => (crate::default_program_path(), type_name, inner_type, true), }; // Generate the struct definition @@ -211,13 +208,13 @@ pub fn pack(input: TokenStream) -> TokenStream { #default_impl #register_impl - impl Into<mingling::AnyOutput<#default_program_path>> for #type_name { - fn into(self) -> mingling::AnyOutput<#default_program_path> { + impl Into<mingling::AnyOutput<#group_name>> for #type_name { + fn into(self) -> mingling::AnyOutput<#group_name> { mingling::AnyOutput::new(self) } } - impl From<#type_name> for mingling::ChainProcess<#default_program_path> { + impl From<#type_name> for mingling::ChainProcess<#group_name> { fn from(value: #type_name) -> Self { mingling::AnyOutput::new(value).route_chain() } @@ -225,19 +222,19 @@ pub fn pack(input: TokenStream) -> TokenStream { impl #type_name { /// Converts the wrapper type into a `ChainProcess` for chaining operations. - pub fn to_chain(self) -> mingling::ChainProcess<#default_program_path> { + pub fn to_chain(self) -> mingling::ChainProcess<#group_name> { mingling::AnyOutput::new(self).route_chain() } /// Converts the wrapper type into a `ChainProcess` for rendering operations. - pub fn to_render(self) -> mingling::ChainProcess<#default_program_path> { + pub fn to_render(self) -> mingling::ChainProcess<#group_name> { mingling::AnyOutput::new(self).route_renderer() } } - impl ::mingling::Groupped<#default_program_path> for #type_name { - fn member_id() -> #default_program_path { - #default_program_path::#type_name + impl ::mingling::Groupped<#group_name> for #type_name { + fn member_id() -> #group_name { + #group_name::#type_name } } } |
