summaryrefslogtreecommitdiff
path: root/mingling_macros/src/chain_struct.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-28 00:47:46 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-28 00:47:46 +0800
commit7ce68cd11516bd7cf037ecea99a92aee7c31b2c3 (patch)
treea3923ad41c91aa21fe169fd6b4b1bf8898a82589 /mingling_macros/src/chain_struct.rs
Add initial Mingling framework codebase
Diffstat (limited to 'mingling_macros/src/chain_struct.rs')
-rw-r--r--mingling_macros/src/chain_struct.rs185
1 files changed, 185 insertions, 0 deletions
diff --git a/mingling_macros/src/chain_struct.rs b/mingling_macros/src/chain_struct.rs
new file mode 100644
index 0000000..82a596d
--- /dev/null
+++ b/mingling_macros/src/chain_struct.rs
@@ -0,0 +1,185 @@
+//! Chain Struct Macro Implementation
+//!
+//! This module provides the `chain_struct!` macro for creating wrapper types
+//! with automatic implementations of common traits.
+
+use proc_macro::TokenStream;
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::{Ident, Result as SynResult, Token, Type};
+
+/// Parses input in the format: `TypeName = InnerType`
+struct ChainStructInput {
+ type_name: Ident,
+ inner_type: Type,
+}
+
+impl Parse for ChainStructInput {
+ fn parse(input: ParseStream) -> SynResult<Self> {
+ let type_name = input.parse()?;
+ input.parse::<Token![=]>()?;
+ let inner_type = input.parse()?;
+
+ Ok(ChainStructInput {
+ type_name,
+ inner_type,
+ })
+ }
+}
+
+/// Implementation of the `chain_struct!` macro
+///
+/// This macro creates a wrapper struct with automatic implementations of:
+/// - `From<InnerType>` and `Into<InnerType>`
+/// - `new()` constructor
+/// - `Default` (if the inner type implements Default)
+/// - `AsRef<InnerType>` and `AsMut<InnerType>`
+/// - `Deref` and `DerefMut` to the inner type
+///
+/// # Examples
+///
+/// ```ignore
+/// use mingling_macros::chain_struct;
+///
+/// // Creates a wrapper type around String
+/// chain_struct!(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
+/// ```
+pub fn chain_struct(input: TokenStream) -> TokenStream {
+ let ChainStructInput {
+ type_name,
+ inner_type,
+ } = syn::parse_macro_input!(input as ChainStructInput);
+
+ // Generate the struct definition
+ #[cfg(not(feature = "serde"))]
+ let struct_def = quote! {
+ #[derive(Debug)]
+ pub struct #type_name {
+ inner: #inner_type,
+ }
+ };
+
+ #[cfg(feature = "serde")]
+ let struct_def = quote! {
+ #[derive(Debug, serde::Serialize)]
+ pub struct #type_name {
+ inner: #inner_type,
+ }
+ };
+
+ // Generate the new() method
+ let new_impl = quote! {
+ impl #type_name {
+ /// Creates a new instance of the wrapper type
+ pub fn new(inner: #inner_type) -> Self {
+ Self { inner }
+ }
+ }
+ };
+
+ // Generate From and Into implementations
+ let from_into_impl = quote! {
+ impl From<#inner_type> for #type_name {
+ fn from(inner: #inner_type) -> Self {
+ Self::new(inner)
+ }
+ }
+
+ impl From<#type_name> for #inner_type {
+ fn from(wrapper: #type_name) -> #inner_type {
+ wrapper.inner
+ }
+ }
+ };
+
+ // Generate AsRef and AsMut implementations
+ let as_ref_impl = quote! {
+ impl ::std::convert::AsRef<#inner_type> for #type_name {
+ fn as_ref(&self) -> &#inner_type {
+ &self.inner
+ }
+ }
+
+ impl ::std::convert::AsMut<#inner_type> for #type_name {
+ fn as_mut(&mut self) -> &mut #inner_type {
+ &mut self.inner
+ }
+ }
+ };
+
+ // Generate Deref and DerefMut implementations
+ let deref_impl = quote! {
+ impl ::std::ops::Deref for #type_name {
+ type Target = #inner_type;
+
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
+ }
+
+ impl ::std::ops::DerefMut for #type_name {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.inner
+ }
+ }
+ };
+
+ // Check if the inner type implements Default by generating conditional code
+ let default_impl = quote! {
+ impl ::std::default::Default for #type_name
+ where
+ #inner_type: ::std::default::Default,
+ {
+ fn default() -> Self {
+ Self::new(::std::default::Default::default())
+ }
+ }
+ };
+
+ let any_out_impl = quote! {
+ impl Into<mingling::AnyOutput> for #type_name {
+ fn into(self) -> mingling::AnyOutput {
+ mingling::AnyOutput::new(self)
+ }
+ }
+
+ impl Into<mingling::ChainProcess> for #type_name {
+ fn into(self) -> mingling::ChainProcess {
+ mingling::AnyOutput::new(self).route_chain()
+ }
+ }
+
+ impl #type_name {
+ /// Converts the wrapper type into a `ChainProcess` for chaining operations.
+ pub fn to_chain(self) -> mingling::ChainProcess {
+ mingling::AnyOutput::new(self).route_chain()
+ }
+
+ /// Converts the wrapper type into a `ChainProcess` for rendering operations.
+ pub fn to_render(self) -> mingling::ChainProcess {
+ mingling::AnyOutput::new(self).route_renderer()
+ }
+ }
+ };
+
+ // Combine all implementations
+ let expanded = quote! {
+ #struct_def
+
+ #new_impl
+ #from_into_impl
+ #as_ref_impl
+ #deref_impl
+ #default_impl
+
+ #any_out_impl
+ };
+
+ expanded.into()
+}