aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src
diff options
context:
space:
mode:
authorWeicao-CatilGrass <1992414357@qq.com>2026-04-27 11:09:35 +0800
committerWeicao-CatilGrass <1992414357@qq.com>2026-04-27 11:29:26 +0800
commitae91bf2f6412edee65660085811248e0127fa97b (patch)
tree504a055510a7592e64ec382cbef97cded7c7e69f /mingling_macros/src
parent704eb899babd85125d29cf41315e9df90515046f (diff)
Remove `marker::NextProcess` and generate it via `gen_program!`
Diffstat (limited to 'mingling_macros/src')
-rw-r--r--mingling_macros/src/chain.rs76
-rw-r--r--mingling_macros/src/lib.rs26
2 files changed, 32 insertions, 70 deletions
diff --git a/mingling_macros/src/chain.rs b/mingling_macros/src/chain.rs
index 7894362..daa6b1c 100644
--- a/mingling_macros/src/chain.rs
+++ b/mingling_macros/src/chain.rs
@@ -9,9 +9,7 @@
use proc_macro::TokenStream;
use quote::{ToTokens, quote};
use syn::spanned::Spanned;
-use syn::{
- FnArg, Ident, ItemFn, Pat, PatType, ReturnType, Signature, Type, TypePath, parse_macro_input,
-};
+use syn::{FnArg, Ident, ItemFn, Pat, PatType, Signature, Type, TypePath, parse_macro_input};
/// Extracts the previous type and parameter name from function arguments
fn extract_previous_info(sig: &Signature) -> syn::Result<(Pat, TypePath)> {
@@ -45,23 +43,6 @@ fn extract_previous_info(sig: &Signature) -> syn::Result<(Pat, TypePath)> {
}
}
-/// Extracts the return type from the function signature
-fn extract_return_type(sig: &Signature) -> syn::Result<TypePath> {
- match &sig.output {
- ReturnType::Type(_, ty) => match &**ty {
- Type::Path(type_path) => Ok(type_path.clone()),
- _ => Err(syn::Error::new(
- ty.span(),
- "Return type must be a type path",
- )),
- },
- ReturnType::Default => Err(syn::Error::new(
- sig.span(),
- "Chain function must have a return type",
- )),
- }
-}
-
pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the attribute arguments (e.g., MyProgram from #[chain(MyProgram)])
// If no argument is provided, use ThisProgram
@@ -100,21 +81,9 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
Err(e) => return e.to_compile_error().into(),
};
- // Extract the return type
- let return_type = match extract_return_type(&input_fn.sig) {
- Ok(ty) => ty,
- Err(e) => return e.to_compile_error().into(),
- };
-
- // Ensure the return type is named "NextProcess"
- if return_type.path.segments.last().unwrap().ident != "NextProcess" {
- return syn::Error::new(
- return_type.span(),
- "Return type must be 'mingling::marker::NextProcess'",
- )
- .to_compile_error()
- .into();
- }
+ // Get the function signature components for direct substitution
+ let sig = &input_fn.sig;
+ let inputs = &sig.inputs;
// Get the function body
let fn_body = &input_fn.block;
@@ -135,24 +104,23 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
let pascal_case_name = just_fmt::pascal_case!(fn_name.to_string());
let struct_name = Ident::new(&pascal_case_name, fn_name.span());
+ // Determine the program type for the return type
+ let program_type = if use_crate_prefix {
+ quote! { ThisProgram }
+ } else {
+ quote! { #group_name }
+ };
+
#[cfg(feature = "async")]
let proc_fn = if is_async_fn {
quote! {
- async fn proc(#prev_param: Self::Previous) ->
- ::mingling::ChainProcess<ThisProgram>
- {
- let _ = NextProcess;
- // Call the original function
+ async fn proc(#inputs) -> ::mingling::ChainProcess<#program_type> {
#fn_name(#prev_param).await.into()
}
}
} else {
quote! {
- async fn proc(#prev_param: Self::Previous) ->
- ::mingling::ChainProcess<ThisProgram>
- {
- let _ = NextProcess;
- // Call the original function
+ async fn proc(#inputs) -> ::mingling::ChainProcess<#program_type> {
#fn_name(#prev_param).into()
}
}
@@ -162,18 +130,14 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
let origin_proc_fn = if is_async_fn {
quote! {
#(#fn_attrs)*
- #vis async fn #fn_name(#prev_param: #previous_type)
- -> impl Into<::mingling::ChainProcess<#group_name>>
- {
+ #vis async fn #fn_name(#inputs) -> impl Into<::mingling::ChainProcess<#program_type>> {
#fn_body
}
}
} else {
quote! {
#(#fn_attrs)*
- #vis fn #fn_name(#prev_param: #previous_type)
- -> impl Into<::mingling::ChainProcess<#group_name>>
- {
+ #vis fn #fn_name(#inputs) -> impl Into<::mingling::ChainProcess<#program_type>> {
#fn_body
}
}
@@ -181,11 +145,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
#[cfg(not(feature = "async"))]
let proc_fn = quote! {
- fn proc(#prev_param: Self::Previous) ->
- ::mingling::ChainProcess<ThisProgram>
- {
- let _ = NextProcess;
- // Call the original function
+ fn proc(#inputs) -> ::mingling::ChainProcess<#program_type> {
#fn_name(#prev_param).into()
}
};
@@ -193,9 +153,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
#[cfg(not(feature = "async"))]
let origin_proc_fn = quote! {
#(#fn_attrs)*
- #vis fn #fn_name(#prev_param: #previous_type)
- -> impl Into<::mingling::ChainProcess<#group_name>>
- {
+ #vis fn #fn_name(#inputs) -> impl Into<::mingling::ChainProcess<#program_type>> {
#fn_body
}
};
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index 58d4e28..f9be1de 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -131,18 +131,22 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
let name = read_name(&input);
#[cfg(feature = "comp")]
- let out = TokenStream::from(quote! {
+ let comp_gen = quote! {
::mingling::macros::program_comp_gen!(#name);
- ::mingling::macros::program_fallback_gen!(#name);
- ::mingling::macros::program_final_gen!(#name);
- });
+ };
+
#[cfg(not(feature = "comp"))]
- let out = TokenStream::from(quote! {
+ let comp_gen = quote! {};
+
+ TokenStream::from(quote! {
+ // Shit, this feature is unstable
+ // pub type NextProcess = impl Into<::mingling::ChainProcess<#name>>;
+ pub type NextProcess = ::mingling::ChainProcess<#name>;
+
+ #comp_gen
::mingling::macros::program_fallback_gen!(#name);
::mingling::macros::program_final_gen!(#name);
- });
-
- out
+ })
}
#[proc_macro]
@@ -153,7 +157,7 @@ pub fn program_comp_gen(input: TokenStream) -> TokenStream {
#[cfg(feature = "async")]
let fn_exec_comp = quote! {
#[::mingling::macros::chain(#name)]
- pub async fn __exec_completion(prev: CompletionContext) -> NextProcess {
+ pub async fn __exec_completion(prev: CompletionContext) -> ::mingling::ChainProcess<#name> {
let read_ctx = ::mingling::ShellContext::try_from(prev.inner);
match read_ctx {
Ok(ctx) => {
@@ -168,7 +172,7 @@ pub fn program_comp_gen(input: TokenStream) -> TokenStream {
#[cfg(not(feature = "async"))]
let fn_exec_comp = quote! {
#[::mingling::macros::chain(#name)]
- pub fn __exec_completion(prev: CompletionContext) -> NextProcess {
+ pub fn __exec_completion(prev: CompletionContext) -> ::mingling::ChainProcess<#name> {
let read_ctx = ::mingling::ShellContext::try_from(prev.inner);
match read_ctx {
Ok(ctx) => {
@@ -185,7 +189,7 @@ pub fn program_comp_gen(input: TokenStream) -> TokenStream {
use __completion_gen::*;
pub mod __completion_gen {
use super::*;
- use mingling::marker::NextProcess;
+
::mingling::macros::dispatcher!(#name, "__comp", CompletionDispatcher => CompletionContext);
::mingling::macros::pack!(
#name,