aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_macros')
-rw-r--r--mingling_macros/src/chain.rs6
-rw-r--r--mingling_macros/src/dispatcher.rs11
-rw-r--r--mingling_macros/src/dispatcher_clap.rs79
-rw-r--r--mingling_macros/src/groupped.rs18
-rw-r--r--mingling_macros/src/lib.rs5
-rw-r--r--mingling_macros/src/pack.rs18
-rw-r--r--mingling_macros/src/program_setup.rs16
7 files changed, 83 insertions, 70 deletions
diff --git a/mingling_macros/src/chain.rs b/mingling_macros/src/chain.rs
index 47f32e3..3c0cca5 100644
--- a/mingling_macros/src/chain.rs
+++ b/mingling_macros/src/chain.rs
@@ -134,8 +134,6 @@ fn extract_args_info(sig: &Signature) -> syn::Result<(Pat, TypePath, Vec<Resourc
}
pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
- let default_program_ident = crate::default_program_ident();
-
// Parse the attribute arguments (e.g., MyProgram from #[chain(MyProgram)])
// If no argument is provided, use ThisProgram
let (group_name, use_crate_prefix) = if attr.is_empty() {
@@ -235,7 +233,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
// Determine the program type for the return type
let program_type = if use_crate_prefix {
- quote! { #default_program_ident }
+ crate::default_program_path()
} else {
quote! { #group_name }
};
@@ -390,7 +388,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
::mingling::macros::register_chain!(#previous_type, #struct_name);
- impl ::mingling::Chain<#default_program_ident> for #struct_name {
+ impl ::mingling::Chain<#program_type> for #struct_name {
type Previous = #previous_type;
#proc_fn
diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs
index 64f0339..a74db6d 100644
--- a/mingling_macros/src/dispatcher.rs
+++ b/mingling_macros/src/dispatcher.rs
@@ -109,6 +109,11 @@ pub fn dispatcher(input: TokenStream) -> TokenStream {
} else {
group_name.clone()
};
+ let program_path = if use_default {
+ crate::default_program_path()
+ } else {
+ quote! { #group_name }
+ };
quote! {
#[derive(Debug, Default)]
@@ -119,14 +124,14 @@ pub fn dispatcher(input: TokenStream) -> TokenStream {
#comp_entry
#dispatch_tree_entry
- impl ::mingling::Dispatcher<#program_ident> for #command_struct {
+ impl ::mingling::Dispatcher<#program_path> for #command_struct {
fn node(&self) -> ::mingling::Node {
::mingling::macros::node!(#command_name_str)
}
- fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess<#program_ident> {
+ fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess<#program_path> {
#pack::new(args).to_chain()
}
- fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher<#program_ident>> {
+ fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher<#program_path>> {
Box::new(#command_struct)
}
}
diff --git a/mingling_macros/src/dispatcher_clap.rs b/mingling_macros/src/dispatcher_clap.rs
index 2a1ac44..b32883e 100644
--- a/mingling_macros/src/dispatcher_clap.rs
+++ b/mingling_macros/src/dispatcher_clap.rs
@@ -132,40 +132,49 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
let struct_name = &input_struct.ident;
// Determine the program name and other fields
- let (command_name_str, dispatcher_struct, options, program_ident) = match &attr_input {
- DispatcherClapInput::Default {
- command_name,
- dispatcher_struct,
- options,
- } => (
- command_name.value(),
- dispatcher_struct.clone(),
- ClapOptions {
- error_struct: options.error_struct.clone(),
- help_enabled: options.help_enabled,
- },
- Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()),
- ),
- DispatcherClapInput::Explicit {
- group_name,
- command_name,
- dispatcher_struct,
- options,
- } => (
- command_name.value(),
- dispatcher_struct.clone(),
- ClapOptions {
- error_struct: options.error_struct.clone(),
- help_enabled: options.help_enabled,
- },
- group_name.clone(),
- ),
- };
+ let (command_name_str, dispatcher_struct, options, program_ident, program_path) =
+ match &attr_input {
+ DispatcherClapInput::Default {
+ command_name,
+ dispatcher_struct,
+ options,
+ } => {
+ let path = crate::default_program_path();
+ (
+ command_name.value(),
+ dispatcher_struct.clone(),
+ ClapOptions {
+ error_struct: options.error_struct.clone(),
+ help_enabled: options.help_enabled,
+ },
+ Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()),
+ path,
+ )
+ }
+ DispatcherClapInput::Explicit {
+ group_name,
+ command_name,
+ dispatcher_struct,
+ options,
+ } => {
+ let path = quote! { #group_name };
+ (
+ command_name.value(),
+ dispatcher_struct.clone(),
+ ClapOptions {
+ error_struct: options.error_struct.clone(),
+ help_enabled: options.help_enabled,
+ },
+ group_name.clone(),
+ path,
+ )
+ }
+ };
// Generate the `begin` method body
let begin_body = if let Some(ref error_struct) = options.error_struct {
quote! {
- if ::mingling::this::<#program_ident>().user_context.help {
+ if ::mingling::this::<#program_path>().user_context.help {
return #struct_name::default().to_chain();
}
match <#struct_name as ::clap::Parser>::try_parse_from(clap_args) {
@@ -177,7 +186,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
}
} else {
quote! {
- if ::mingling::this::<#program_ident>().user_context.help {
+ if ::mingling::this::<#program_path>().user_context.help {
return #struct_name::default().to_chain();
}
let parsed = <#struct_name as ::clap::Parser>::try_parse_from(clap_args)
@@ -205,7 +214,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
fn #help_fn_name(_prev: #struct_name) {
use clap::ColorChoice;
- let this = ::mingling::this::<#program_ident>();
+ let this = ::mingling::this::<#program_path>();
match this.stdout_setting.clap_help_print_behaviour {
::mingling::ClapHelpPrintBehaviour::WriteToRenderResult => {
<#struct_name as ::clap::CommandFactory>::command()
@@ -238,7 +247,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
#[doc(hidden)]
struct #dispatcher_struct;
- impl ::mingling::Dispatcher<#program_ident> for #dispatcher_struct {
+ impl ::mingling::Dispatcher<#program_path> for #dispatcher_struct {
fn node(&self) -> ::mingling::Node {
::mingling::macros::node!(#command_name_str)
}
@@ -246,7 +255,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
fn begin(
&self,
args: Vec<String>,
- ) -> ::mingling::ChainProcess<#program_ident> {
+ ) -> ::mingling::ChainProcess<#program_path> {
// Prepend a dummy program name for clap's parse_from
let clap_args = std::iter::once(String::new())
.chain(args)
@@ -257,7 +266,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
fn clone_dispatcher(
&self,
- ) -> Box<dyn ::mingling::Dispatcher<#program_ident>> {
+ ) -> Box<dyn ::mingling::Dispatcher<#program_path>> {
Box::new(#dispatcher_struct)
}
}
diff --git a/mingling_macros/src/groupped.rs b/mingling_macros/src/groupped.rs
index 4fd0665..e385812 100644
--- a/mingling_macros/src/groupped.rs
+++ b/mingling_macros/src/groupped.rs
@@ -1,10 +1,7 @@
use proc_macro::TokenStream;
-use proc_macro2::Span;
use quote::quote;
use syn::{Attribute, DeriveInput, Ident, parse_macro_input};
-use crate::DEFAULT_PROGRAM_NAME;
-
/// Parses the `#[group(...)]` attribute to extract the group type
fn parse_group_attribute(attrs: &[Attribute]) -> Option<Ident> {
for attr in attrs {
@@ -25,8 +22,9 @@ pub fn derive_groupped(input: TokenStream) -> TokenStream {
let struct_name = input.ident;
// Parse attributes to find #[group(...)]
- let group_ident = parse_group_attribute(&input.attrs)
- .unwrap_or_else(|| Ident::new(DEFAULT_PROGRAM_NAME, Span::call_site()));
+ let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input.attrs)
+ .map(|ident| quote! { #ident })
+ .unwrap_or_else(crate::default_program_path);
let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls(
struct_name.clone(),
@@ -56,8 +54,9 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream {
let struct_name = input_parsed.ident.clone();
// Parse attributes to find #[group(...)]
- let group_ident = parse_group_attribute(&input_parsed.attrs)
- .unwrap_or_else(|| Ident::new(DEFAULT_PROGRAM_NAME, Span::call_site()));
+ let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input_parsed.attrs)
+ .map(|ident| quote! { #ident })
+ .unwrap_or_else(crate::default_program_path);
let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls(
struct_name.clone(),
@@ -83,7 +82,10 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream {
expanded.into()
}
-fn build_any_output_convert_impls(struct_name: Ident, group_ident: Ident) -> TokenStream {
+fn build_any_output_convert_impls(
+ struct_name: Ident,
+ group_ident: proc_macro2::TokenStream,
+) -> TokenStream {
quote! {
impl ::std::convert::Into<::mingling::AnyOutput<#group_ident>> for #struct_name {
fn into(self) -> ::mingling::AnyOutput<#group_ident> {
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index 7dd2fe2..d5bdf35 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -46,10 +46,15 @@ mod suggest;
pub(crate) const DEFAULT_PROGRAM_NAME: &str = "ThisProgram";
+#[allow(dead_code)]
pub(crate) fn default_program_ident() -> Ident {
Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site())
}
+pub(crate) fn default_program_path() -> proc_macro2::TokenStream {
+ quote::quote! { crate::ThisProgram }
+}
+
// Global variables
#[cfg(feature = "general_renderer")]
pub(crate) static GENERAL_RENDERERS: Lazy<Mutex<BTreeSet<String>>> =
diff --git a/mingling_macros/src/pack.rs b/mingling_macros/src/pack.rs
index 2242082..1c0bb7b 100644
--- a/mingling_macros/src/pack.rs
+++ b/mingling_macros/src/pack.rs
@@ -52,7 +52,7 @@ impl Parse for PackInput {
}
pub fn pack(input: TokenStream) -> TokenStream {
- let default_program_ident = crate::default_program_ident();
+ let default_program_path = crate::default_program_path();
// Parse the input
let pack_input = syn::parse_macro_input!(input as PackInput);
@@ -211,13 +211,13 @@ pub fn pack(input: TokenStream) -> TokenStream {
#default_impl
#register_impl
- impl Into<mingling::AnyOutput<#default_program_ident>> for #type_name {
- fn into(self) -> mingling::AnyOutput<#default_program_ident> {
+ impl Into<mingling::AnyOutput<#default_program_path>> for #type_name {
+ fn into(self) -> mingling::AnyOutput<#default_program_path> {
mingling::AnyOutput::new(self)
}
}
- impl From<#type_name> for mingling::ChainProcess<#default_program_ident> {
+ impl From<#type_name> for mingling::ChainProcess<#default_program_path> {
fn from(value: #type_name) -> Self {
mingling::AnyOutput::new(value).route_chain()
}
@@ -225,19 +225,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_ident> {
+ pub fn to_chain(self) -> mingling::ChainProcess<#default_program_path> {
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_ident> {
+ pub fn to_render(self) -> mingling::ChainProcess<#default_program_path> {
mingling::AnyOutput::new(self).route_renderer()
}
}
- impl ::mingling::Groupped<#default_program_ident> for #type_name {
- fn member_id() -> #default_program_ident {
- #default_program_ident::#type_name
+ impl ::mingling::Groupped<#default_program_path> for #type_name {
+ fn member_id() -> #default_program_path {
+ #default_program_path::#type_name
}
}
}
diff --git a/mingling_macros/src/program_setup.rs b/mingling_macros/src/program_setup.rs
index 57b7e6c..dd32581 100644
--- a/mingling_macros/src/program_setup.rs
+++ b/mingling_macros/src/program_setup.rs
@@ -3,8 +3,6 @@ use quote::quote;
use syn::spanned::Spanned;
use syn::{FnArg, Ident, ItemFn, Pat, PatType, ReturnType, Signature, Type, parse_macro_input};
-use crate::DEFAULT_PROGRAM_NAME;
-
/// Extracts the program parameter from function arguments
fn extract_program_param(sig: &Signature) -> syn::Result<(Pat, Type)> {
// The function should have exactly one parameter
@@ -50,17 +48,13 @@ fn extract_return_type(sig: &Signature) -> syn::Result<()> {
}
pub fn setup_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
- let default_program_ident = crate::default_program_ident();
-
// Parse the attribute arguments (e.g., MyProgram from #[program_setup(MyProgram)])
// If no argument is provided, use ThisProgram
let (program_name, use_crate_prefix) = if attr.is_empty() {
- (
- Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()),
- true,
- )
+ (crate::default_program_path(), true)
} else {
- (parse_macro_input!(attr as Ident), false)
+ let ident: Ident = parse_macro_input!(attr as Ident);
+ (quote! { #ident }, false)
};
// Parse the function item
@@ -110,8 +104,8 @@ pub fn setup_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
#[doc(hidden)]
#vis struct #struct_name;
- impl ::mingling::setup::ProgramSetup<#default_program_ident> for #struct_name {
- fn setup(&mut self, program: &mut ::mingling::Program<#default_program_ident>) {
+ impl ::mingling::setup::ProgramSetup<#program_name> for #struct_name {
+ fn setup(&mut self, program: &mut ::mingling::Program<#program_name>) {
// Call the original function with the actual Program type
#fn_name(program);
}