diff options
| -rw-r--r-- | CHANGELOG.md | 9 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | docs/README.md | 1 | ||||
| -rw-r--r-- | docs/pages/3-features/1-parser.md | 2 | ||||
| -rw-r--r-- | examples/example-async/src/main.rs | 7 | ||||
| -rw-r--r-- | examples/example-basic/src/main.rs | 4 | ||||
| -rw-r--r-- | examples/example-completion/src/main.rs | 5 | ||||
| -rw-r--r-- | examples/example-general-renderer/src/main.rs | 5 | ||||
| -rw-r--r-- | examples/example-picker/src/main.rs | 3 | ||||
| -rw-r--r-- | mingling/src/example_docs.rs | 24 | ||||
| -rw-r--r-- | mingling_core/src/lib.rs | 6 | ||||
| -rw-r--r-- | mingling_core/src/markers.rs | 2 | ||||
| -rw-r--r-- | mingling_core/src/markers/next_process.rs | 2 | ||||
| -rw-r--r-- | mingling_macros/src/chain.rs | 76 | ||||
| -rw-r--r-- | mingling_macros/src/lib.rs | 26 |
15 files changed, 59 insertions, 114 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf3803..f7a2ec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,15 @@ fn parse_sth(prev: SomeEntry) -> NextProcess { } ``` +5. **\[core\]** Removed `mingling::marker::NextProcess` and moved its creation process to `gen_program!()` + +```rust +use mingling::marker::NextProcess; // Remove this + +// NextProcess generated here +gen_program!(); +``` + --- ### Release 0.1.6 **\[YANKED\]** @@ -68,7 +68,6 @@ use mingling::{ macros::{ chain, completion, dispatcher, gen_program, help, pack, r_println, renderer, suggest, }, - marker::NextProcess, parser::Picker, setup::BasicProgramSetup, }; diff --git a/docs/README.md b/docs/README.md index 781523f..73fd091 100644 --- a/docs/README.md +++ b/docs/README.md @@ -68,7 +68,6 @@ use mingling::{ macros::{ chain, completion, dispatcher, gen_program, help, pack, r_println, renderer, suggest, }, - marker::NextProcess, parser::Picker, setup::BasicProgramSetup, }; diff --git a/docs/pages/3-features/1-parser.md b/docs/pages/3-features/1-parser.md index 1490218..b3c7a05 100644 --- a/docs/pages/3-features/1-parser.md +++ b/docs/pages/3-features/1-parser.md @@ -98,7 +98,6 @@ Then create the basic binary program `fruit` use mingling::{ EnumTag, Groupped, macros::{chain, dispatcher, gen_program, r_println, renderer}, - marker::NextProcess, parser::PickableEnum, }; @@ -242,7 +241,6 @@ Complete code: use mingling::{ AnyOutput, EnumTag, Groupped, macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, - marker::NextProcess, parser::{PickableEnum, Picker}, }; diff --git a/examples/example-async/src/main.rs b/examples/example-async/src/main.rs index 29aee7e..21e27aa 100644 --- a/examples/example-async/src/main.rs +++ b/examples/example-async/src/main.rs @@ -16,10 +16,7 @@ //! cargo run --manifest-path ./examples/example-async/Cargo.toml -- hello World //! ``` -use mingling::{ - macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, - marker::NextProcess, -}; +use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; dispatcher!("hello", HelloCommand => HelloEntry); @@ -39,7 +36,7 @@ pack!(Hello = String); #[chain] // fn parse_name(prev: HelloEntry) -> NextProcess { -async fn parse_name(prev: HelloEntry) -> NextProcess { +async fn parse_name(prev: HelloEntry) -> mingling::ChainProcess<ThisProgram> { let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); Hello::new(name).to_render() } diff --git a/examples/example-basic/src/main.rs b/examples/example-basic/src/main.rs index a35cac6..a91154a 100644 --- a/examples/example-basic/src/main.rs +++ b/examples/example-basic/src/main.rs @@ -6,8 +6,8 @@ //! ``` use mingling::{ + ChainProcess, macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, - marker::NextProcess, }; // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry` @@ -29,7 +29,7 @@ pack!(Hello = String); // Register chain to `ThisProgram`, handling logic from `HelloEntry` #[chain] -fn parse_name(prev: HelloEntry) -> NextProcess { +fn parse_name(prev: HelloEntry) -> ChainProcess<ThisProgram> { // Extract string from `HelloEntry` as argument let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); diff --git a/examples/example-completion/src/main.rs b/examples/example-completion/src/main.rs index 2e21a5c..8f88b2c 100644 --- a/examples/example-completion/src/main.rs +++ b/examples/example-completion/src/main.rs @@ -25,11 +25,10 @@ //! 4. Execute `cargo install --path ./`, then run the corresponding completion script in your shell use mingling::{ - EnumTag, Groupped, ShellContext, Suggest, + ChainProcess, EnumTag, Groupped, ShellContext, Suggest, macros::{ chain, completion, dispatcher, gen_program, r_println, renderer, suggest, suggest_enum, }, - marker::NextProcess, parser::{PickableEnum, Picker}, }; @@ -97,7 +96,7 @@ enum FruitType { impl PickableEnum for FruitType {} #[chain] -fn parse_fruit_info(prev: FruitEntry) -> NextProcess { +fn parse_fruit_info(prev: FruitEntry) -> ChainProcess<ThisProgram> { let picker = Picker::<()>::from(prev.inner); let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack_directly(); let info = FruitInfo { diff --git a/examples/example-general-renderer/src/main.rs b/examples/example-general-renderer/src/main.rs index e879900..bea563d 100644 --- a/examples/example-general-renderer/src/main.rs +++ b/examples/example-general-renderer/src/main.rs @@ -33,9 +33,8 @@ //! ``` use mingling::{ - Groupped, + ChainProcess, Groupped, macros::{chain, dispatcher, gen_program, r_println, renderer}, - marker::NextProcess, parser::Picker, setup::GeneralRendererSetup, }; @@ -61,7 +60,7 @@ struct Info { } #[chain] -fn parse_render(prev: RenderCommandEntry) -> NextProcess { +fn parse_render(prev: RenderCommandEntry) -> ChainProcess<ThisProgram> { let (name, age) = Picker::<()>::new(prev.inner) .pick::<String>(()) .pick::<i32>(()) diff --git a/examples/example-picker/src/main.rs b/examples/example-picker/src/main.rs index 6bc4bfd..5653368 100644 --- a/examples/example-picker/src/main.rs +++ b/examples/example-picker/src/main.rs @@ -19,7 +19,6 @@ use mingling::{ macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, - marker::NextProcess, parser::Picker, }; @@ -35,7 +34,7 @@ pack!(NoNameProvided = ()); pack!(ParsedPickInput = (i32, String)); #[chain] -fn parse(prev: PickEntry) -> NextProcess { +fn parse(prev: PickEntry) -> mingling::ChainProcess<ThisProgram> { // Extract arguments from `PickEntry`'s inner and create a `Picker` let picker = Picker::new(prev.inner); let picked = picker diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs index 8440a2d..81eb2ef 100644 --- a/mingling/src/example_docs.rs +++ b/mingling/src/example_docs.rs @@ -32,10 +32,7 @@ /// /// main.rs /// ```ignore -/// use mingling::{ -/// macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, -/// marker::NextProcess, -/// }; +/// use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; /// /// dispatcher!("hello", HelloCommand => HelloEntry); /// @@ -55,7 +52,7 @@ /// /// #[chain] /// // fn parse_name(prev: HelloEntry) -> NextProcess { -/// async fn parse_name(prev: HelloEntry) -> NextProcess { +/// async fn parse_name(prev: HelloEntry) -> mingling::ChainProcess<ThisProgram> { /// let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); /// Hello::new(name).to_render() /// } @@ -90,8 +87,8 @@ pub mod example_async {} /// main.rs /// ```ignore /// use mingling::{ +/// ChainProcess, /// macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, -/// marker::NextProcess, /// }; /// /// // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry` @@ -113,7 +110,7 @@ pub mod example_async {} /// /// // Register chain to `ThisProgram`, handling logic from `HelloEntry` /// #[chain] -/// fn parse_name(prev: HelloEntry) -> NextProcess { +/// fn parse_name(prev: HelloEntry) -> ChainProcess<ThisProgram> { /// // Extract string from `HelloEntry` as argument /// let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); /// @@ -174,11 +171,10 @@ pub mod example_basic {} /// main.rs /// ```ignore /// use mingling::{ -/// EnumTag, Groupped, ShellContext, Suggest, +/// ChainProcess, EnumTag, Groupped, ShellContext, Suggest, /// macros::{ /// chain, completion, dispatcher, gen_program, r_println, renderer, suggest, suggest_enum, /// }, -/// marker::NextProcess, /// parser::{PickableEnum, Picker}, /// }; /// @@ -246,7 +242,7 @@ pub mod example_basic {} /// impl PickableEnum for FruitType {} /// /// #[chain] -/// fn parse_fruit_info(prev: FruitEntry) -> NextProcess { +/// fn parse_fruit_info(prev: FruitEntry) -> ChainProcess<ThisProgram> { /// let picker = Picker::<()>::from(prev.inner); /// let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack_directly(); /// let info = FruitInfo { @@ -329,9 +325,8 @@ pub mod example_completion {} /// main.rs /// ```ignore /// use mingling::{ -/// Groupped, +/// ChainProcess, Groupped, /// macros::{chain, dispatcher, gen_program, r_println, renderer}, -/// marker::NextProcess, /// parser::Picker, /// setup::GeneralRendererSetup, /// }; @@ -357,7 +352,7 @@ pub mod example_completion {} /// } /// /// #[chain] -/// fn parse_render(prev: RenderCommandEntry) -> NextProcess { +/// fn parse_render(prev: RenderCommandEntry) -> ChainProcess<ThisProgram> { /// let (name, age) = Picker::<()>::new(prev.inner) /// .pick::<String>(()) /// .pick::<i32>(()) @@ -409,7 +404,6 @@ pub mod example_general_renderer {} /// ```ignore /// use mingling::{ /// macros::{chain, dispatcher, gen_program, pack, r_println, renderer}, -/// marker::NextProcess, /// parser::Picker, /// }; /// @@ -425,7 +419,7 @@ pub mod example_general_renderer {} /// pack!(ParsedPickInput = (i32, String)); /// /// #[chain] -/// fn parse(prev: PickEntry) -> NextProcess { +/// fn parse(prev: PickEntry) -> mingling::ChainProcess<ThisProgram> { /// // Extract arguments from `PickEntry`'s inner and create a `Picker` /// let picker = Picker::new(prev.inner); /// let picked = picker diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs index aee0df6..9e65e40 100644 --- a/mingling_core/src/lib.rs +++ b/mingling_core/src/lib.rs @@ -10,7 +10,6 @@ mod any; mod asset; -mod markers; mod program; mod renderer; @@ -41,11 +40,6 @@ pub use crate::program::*; pub use crate::renderer::render_result::*; -/// All marker types of `Mingling` that serve no practical purpose -pub mod marker { - pub use crate::markers::next_process::*; -} - /// `Mingling`'s Program initialization system pub mod setup { pub use crate::program::setup::*; diff --git a/mingling_core/src/markers.rs b/mingling_core/src/markers.rs deleted file mode 100644 index d71434b..0000000 --- a/mingling_core/src/markers.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[doc(hidden)] -pub mod next_process; diff --git a/mingling_core/src/markers/next_process.rs b/mingling_core/src/markers/next_process.rs deleted file mode 100644 index 9169900..0000000 --- a/mingling_core/src/markers/next_process.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[allow(dead_code)] -pub struct NextProcess; 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, |
