diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-03-31 16:59:35 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-03-31 17:10:29 +0800 |
| commit | 792662d7a81d87f2673d6a13be78d01142fadd92 (patch) | |
| tree | 5e3181f4e3f3d52053e6eb3d6dea9710b200a2e3 | |
| parent | 3572008321bff319d5ab226d0b9979fa89af498e (diff) | |
Remove documentation from macro definitions
| -rw-r--r-- | mingling_macros/src/chain.rs | 4 | ||||
| -rw-r--r-- | mingling_macros/src/lib.rs | 205 | ||||
| -rw-r--r-- | mingling_macros/src/renderer.rs | 3 |
3 files changed, 7 insertions, 205 deletions
diff --git a/mingling_macros/src/chain.rs b/mingling_macros/src/chain.rs index ad74c5c..1fddd3b 100644 --- a/mingling_macros/src/chain.rs +++ b/mingling_macros/src/chain.rs @@ -125,13 +125,17 @@ pub fn chain_attr(item: TokenStream) -> TokenStream { let chain_entry = quote! { #struct_name => #previous_type, }; + let chain_exist_entry = quote! { id if id == std::any::TypeId::of::<#previous_type>() => true, }; + let mut chains = crate::CHAINS.lock().unwrap(); let mut chain_exist = crate::CHAINS_EXIST.lock().unwrap(); + let chain_entry = chain_entry.to_string(); let chain_exist_entry = chain_exist_entry.to_string(); + if !chains.contains(&chain_entry) { chains.push(chain_entry); } diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index b0ed658..05bcf0b 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -24,251 +24,46 @@ pub(crate) static RENDERERS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new( pub(crate) static CHAINS_EXIST: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new())); pub(crate) static RENDERERS_EXIST: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new())); -/// Creates a command node from a dot-separated path string. -/// The path components are automatically converted to kebab-case. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::node; -/// -/// // Creates a node representing "subcommand.action" -/// // The components will be converted to kebab-case -/// let node = node!("subcommand.action"); -/// ``` #[proc_macro] pub fn node(input: TokenStream) -> TokenStream { node::node(input) } -/// Macro for creating wrapper types with automatic trait implementations. -/// -/// This macro creates a new struct that wraps an inner type and automatically -/// implements common traits: -/// - `From<InnerType>` and `Into<InnerType>` -/// - `new()` constructor -/// - `Default` (if inner type implements Default) -/// - `AsRef<InnerType>` and `AsMut<InnerType>` -/// - `Deref` and `DerefMut` to inner type -/// - `Into<mingling::AnyOutput>` and `Into<mingling::ChainProcess>` -/// - Helper methods `to_chain()` and `to_render()` for chaining operations -/// -/// When the `serde` feature is enabled, the struct also derives `serde::Serialize`. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::pack; -/// -/// // Creates a wrapper type around String -/// pack!(NameString = String); -/// -/// // Usage: -/// let name = NameString::new("Hello".to_string()); -/// let inner: String = name.into(); // Into conversion -/// let name2 = NameString::from("World".to_string()); // From conversion -/// let ref_str: &String = name2.as_ref(); // AsRef -/// let chain_process = name2.to_chain(); // Convert to ChainProcess -/// ``` #[proc_macro] pub fn pack(input: TokenStream) -> TokenStream { pack::pack(input) } -/// Creates a dispatcher chain for command execution. -/// -/// This macro generates a dispatcher struct that implements the `Dispatcher` trait -/// for command chain execution. It creates a dispatcher that begins a chain process -/// with the given command name and arguments. -/// -/// # Syntax -/// -/// `dispatcher!("command_name", CommandStruct => Packed)` -/// -/// - `command_name`: A string literal representing the command name -/// - `CommandStruct`: The name of the dispatcher struct to generate -/// - `Packed`: The name of the chain wrapper struct to generate -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::dispatcher; -/// -/// // Creates a dispatcher for the "init" command -/// dispatcher!("init", InitDispatcher => InitChain); -/// -/// // This generates: -/// // - A dispatcher struct `InitDispatcher` that implements `Dispatcher` -/// // - A chain wrapper struct `InitChain` wrapping `Vec<String>` -/// // - The dispatcher will create a chain process when invoked -/// ``` #[proc_macro] pub fn dispatcher(input: TokenStream) -> TokenStream { dispatcher_chain::dispatcher_chain(input) } -/// Creates a dispatcher for rendering operations. -/// -/// This macro generates a dispatcher struct that implements the `Dispatcher` trait -/// for rendering operations. It creates a dispatcher that begins a render process -/// with the given command name and arguments. -/// -/// # Syntax -/// -/// `dispatcher_render!("command_name", CommandStruct => Packed)` -/// -/// - `command_name`: A string literal representing the command name -/// - `CommandStruct`: The name of the dispatcher struct to generate -/// - `Packed`: The name of the chain wrapper struct to generate -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::dispatcher_render; -/// -/// // Creates a render dispatcher for the "show" command -/// dispatcher_render!("show", ShowDispatcher => ShowChain); -/// -/// // This generates: -/// // - A dispatcher struct `ShowDispatcher` that implements `Dispatcher` -/// // - A chain wrapper struct `ShowChain` wrapping `Vec<String>` -/// // - The dispatcher will create a render process when invoked -/// ``` #[proc_macro] pub fn dispatcher_render(input: TokenStream) -> TokenStream { dispatcher_chain::dispatcher_render(input) } -/// Macro for printing to a RenderResult without newline. -/// -/// This macro expands to a call to `RenderResult::print` with formatted arguments. -/// It expects a mutable reference to a `RenderResult` named `r` to be in scope. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::r_print; -/// -/// let mut r = RenderResult::default(); -/// r_print!("Hello, {}!", "world"); -/// ``` #[proc_macro] pub fn r_print(input: TokenStream) -> TokenStream { render::r_print(input) } -/// Macro for printing to a RenderResult with newline. -/// -/// This macro expands to a call to `RenderResult::println` with formatted arguments. -/// It expects a mutable reference to a `RenderResult` named `r` to be in scope. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::r_println; -/// -/// let mut r = RenderResult::default(); -/// r_println!("Hello, {}!", "world"); -/// ``` #[proc_macro] pub fn r_println(input: TokenStream) -> TokenStream { render::r_println(input) } -/// Attribute macro for automatically generating structs that implement the `Chain` trait. -/// -/// This macro transforms an async function into a struct that implements -/// the `Chain` trait. The struct name is automatically generated from the function name -/// by converting it to PascalCase. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::chain; -/// -/// #[chain] -/// pub async fn init_entry(_: InitBegin) -> mingling::ChainProcess { -/// AnyOutput::new::<InitResult>("Init!".to_string().into()).route_chain() -/// } -/// ``` -/// -/// This generates: -/// ```ignore -/// pub struct InitEntry; -/// impl Chain for InitEntry { -/// type Previous = InitBegin; -/// async fn proc(_: Self::Previous) -> mingling::ChainProcess { -/// AnyOutput::new::<InitResult>("Init!".to_string().into()).route_chain() -/// } -/// } -/// ``` #[proc_macro_attribute] pub fn chain(_attr: TokenStream, item: TokenStream) -> TokenStream { chain::chain_attr(item) } -/// Attribute macro for automatically generating structs that implement the `Renderer` trait. -/// -/// This macro transforms a function into a struct that implements -/// the `Renderer` trait. The struct name is automatically generated from the function name -/// by converting it to PascalCase. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::renderer; -/// -/// #[renderer] -/// fn init_result_render(p: InitResult) { -/// let str: String = p.into(); -/// r_println!("{}", str); -/// } -/// ``` -/// -/// This generates: -/// ```ignore -/// pub struct InitResultRender; -/// impl Renderer for InitResultRender { -/// type Previous = InitResult; -/// -/// fn render(p: Self::Previous, r: &mut RenderResult) { -/// let str: String = p.into(); -/// r_println!("{}", str); -/// } -/// } -/// ``` #[proc_macro_attribute] pub fn renderer(_attr: TokenStream, item: TokenStream) -> TokenStream { renderer::renderer_attr(item) } -/// Macro for creating a program structure that collects all chains and renderers. -/// -/// This macro creates a struct that implements the `ProgramCollect` trait, -/// which collects all chains and renderers registered with `#[chain]` and `#[renderer]` -/// attribute macros. The program can then be used to execute the command chain. -/// -/// # Examples -/// -/// ```ignore -/// use mingling_macros::program; -/// -/// program!(MyProgram); -/// -/// // This generates: -/// pub struct MyProgram; -/// impl mingling::ProgramCollect for MyProgram { -/// mingling::__dispatch_program_renderers!(...); -/// mingling::__dispatch_program_chains!(...); -/// fn has_renderer(any: &mingling::AnyOutput) -> bool { ... } -/// fn has_chain(any: &mingling::AnyOutput) -> bool { ... } -/// } -/// impl MyProgram { -/// pub fn new() -> mingling::Program<MyProgram> { -/// mingling::Program::new() -/// } -/// } -/// ``` #[proc_macro] pub fn program(input: TokenStream) -> TokenStream { let name = parse_macro_input!(input as Ident); diff --git a/mingling_macros/src/renderer.rs b/mingling_macros/src/renderer.rs index de244c0..21c20c8 100644 --- a/mingling_macros/src/renderer.rs +++ b/mingling_macros/src/renderer.rs @@ -104,14 +104,17 @@ pub fn renderer_attr(item: TokenStream) -> TokenStream { let renderer_entry = quote! { #struct_name => #previous_type, }; + let renderer_exist_entry = quote! { id if id == std::any::TypeId::of::<#previous_type>() => true, }; let mut renderers = crate::RENDERERS.lock().unwrap(); let mut renderer_exist = crate::RENDERERS_EXIST.lock().unwrap(); + let renderer_entry_str = renderer_entry.to_string(); let renderer_exist_entry_str = renderer_exist_entry.to_string(); + if !renderers.contains(&renderer_entry_str) { renderers.push(renderer_entry_str); } |
