diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-03-29 00:52:16 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-03-29 00:52:28 +0800 |
| commit | db9afa0b06355028eafe3bc29fe0b2429ba8fd0a (patch) | |
| tree | 60bf74d0853fcc0c1e9363813c26109a6ca38a4f /mingling_macros/src/dispatcher_chain.rs | |
| parent | 7ce68cd11516bd7cf037ecea99a92aee7c31b2c3 (diff) | |
Completed the first preliminary usable version of the Mingling
framework.
Diffstat (limited to 'mingling_macros/src/dispatcher_chain.rs')
| -rw-r--r-- | mingling_macros/src/dispatcher_chain.rs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/mingling_macros/src/dispatcher_chain.rs b/mingling_macros/src/dispatcher_chain.rs new file mode 100644 index 0000000..d9d95a5 --- /dev/null +++ b/mingling_macros/src/dispatcher_chain.rs @@ -0,0 +1,94 @@ +//! Dispatcher Chain and Dispatcher Render Macros +//! +//! This module provides macros for creating dispatcher chain and dispatcher render structs +//! with automatic implementations of the `DispatcherChain` trait. + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse::{Parse, ParseStream}; +use syn::{Ident, Result as SynResult, Token}; + +/// Parses input in the format: `"command_name", CommandStruct => ChainStruct` +struct DispatcherChainInput { + command_name: syn::LitStr, + command_struct: Ident, + chain_struct: Ident, +} + +impl Parse for DispatcherChainInput { + fn parse(input: ParseStream) -> SynResult<Self> { + let command_name = input.parse()?; + input.parse::<Token![,]>()?; + let command_struct = input.parse()?; + input.parse::<Token![=>]>()?; + let chain_struct = input.parse()?; + + Ok(DispatcherChainInput { + command_name, + command_struct, + chain_struct, + }) + } +} + +pub fn dispatcher_chain(input: TokenStream) -> TokenStream { + let DispatcherChainInput { + command_name, + command_struct, + chain_struct, + } = syn::parse_macro_input!(input as DispatcherChainInput); + + let command_name_str = command_name.value(); + + let expanded = quote! { + #[derive(Debug, Default)] + pub struct #command_struct; + + ::mingling::macros::chain_struct!(#chain_struct = Vec<String>); + + impl ::mingling::Dispatcher for #command_struct { + fn node(&self) -> ::mingling::Node { + ::mingling::macros::node!(#command_name_str) + } + fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess { + #chain_struct::new(args).to_chain() + } + fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher> { + Box::new(#command_struct) + } + } + }; + + expanded.into() +} + +pub fn dispatcher_render(input: TokenStream) -> TokenStream { + let DispatcherChainInput { + command_name, + command_struct, + chain_struct, + } = syn::parse_macro_input!(input as DispatcherChainInput); + + let command_name_str = command_name.value(); + + let expanded = quote! { + #[derive(Debug, Default)] + pub struct #command_struct; + + ::mingling::macros::chain_struct!(#chain_struct = Vec<String>); + + impl ::mingling::Dispatcher for #command_struct { + fn node(&self) -> ::mingling::Node { + ::mingling::macros::node!(#command_name_str) + } + fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess { + #chain_struct::new(args).to_render() + } + fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher> { + Box::new(#command_struct) + } + } + }; + + expanded.into() +} |
