summaryrefslogtreecommitdiff
path: root/mingling_macros/src/dispatcher_chain.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-29 00:52:16 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-29 00:52:28 +0800
commitdb9afa0b06355028eafe3bc29fe0b2429ba8fd0a (patch)
tree60bf74d0853fcc0c1e9363813c26109a6ca38a4f /mingling_macros/src/dispatcher_chain.rs
parent7ce68cd11516bd7cf037ecea99a92aee7c31b2c3 (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.rs94
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()
+}