aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src/lib.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-20 01:30:10 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-20 01:30:10 +0800
commitd3177c386d739a3dc0e06890ad8f14713ef44ee0 (patch)
tree98193b025812ee13b1f0f0bb38e1d58fd2558f3d /mingling_macros/src/lib.rs
parent9d491352d161ee629cc47459537344ba0ea4bb35 (diff)
Add `group!` macro for registering external types
Diffstat (limited to 'mingling_macros/src/lib.rs')
-rw-r--r--mingling_macros/src/lib.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index 9880cd6..bb296ef 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -153,6 +153,8 @@ mod dispatcher_clap;
#[cfg(feature = "extra_macros")]
mod entry;
mod enum_tag;
+#[cfg(feature = "extra_macros")]
+mod group_impl;
mod groupped;
mod help;
mod node;
@@ -230,6 +232,56 @@ pub(crate) fn check_single_segment_type(
}
}
+/// Registers an outside-type as a member of a program group without modifying its definition.
+///
+/// This macro allows you to use outside-types from external crates (like `std::io::Error`)
+/// within the Mingling framework by generating a `Groupped` implementation and registering
+/// the type's simple name as an enum variant.
+///
+/// # Syntax
+///
+/// Two forms are supported:
+///
+/// ```rust,ignore
+/// // Explicit mode — specify both program path and outside-type:
+/// group!(crate::ThisProgram, std::io::Error);
+///
+/// // Implicit mode — uses default `crate::ThisProgram` as the program:
+/// group!(std::io::Error);
+/// ```
+///
+/// # How it works
+///
+/// The macro generates a module containing:
+/// - A `use` import for the program path and the outside-type
+/// - An `impl Groupped<Program>` for the outside-type
+/// - A `register_type!` call with the type's simple name
+///
+/// The type's simple name (e.g. `Error`) is used as the enum variant in the generated
+/// program enum, just like `#[derive(Groupped)]` or `pack!`.
+///
+/// # Example
+///
+/// ```rust,ignore
+/// use mingling::macros::group;
+///
+/// // Register std::io::Error as a group member
+/// group!(std::io::Error);
+///
+/// // With explicit program path:
+/// group!(crate::MyProgram, serde_json::Error);
+/// ```
+///
+/// After expansion, the type can be used in chains and renderers like any
+/// `#[derive(Groupped)]` type.
+///
+/// This macro is only available with the `extra_macros` feature.
+#[cfg(feature = "extra_macros")]
+#[proc_macro]
+pub fn group(input: TokenStream) -> TokenStream {
+ group_impl::group_macro(input)
+}
+
/// Creates a `Node` from a dot-separated path string.
///
/// Each segment is converted to kebab-case (unless it starts with `_`).
@@ -1801,6 +1853,7 @@ pub fn program_final_gen(input: TokenStream) -> TokenStream {
let expanded = quote! {
#[derive(Debug, PartialEq, Eq, Clone)]
#[repr(#repr_type)]
+ #[allow(nonstandard_style)]
pub enum #name {
#(#packed_types),*
}