From 7ce68cd11516bd7cf037ecea99a92aee7c31b2c3 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 28 Mar 2026 00:47:46 +0800 Subject: Add initial Mingling framework codebase --- mingling_macros/src/chain_struct.rs | 185 ++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 mingling_macros/src/chain_struct.rs (limited to 'mingling_macros/src/chain_struct.rs') 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 { + let type_name = input.parse()?; + input.parse::()?; + 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` and `Into` +/// - `new()` constructor +/// - `Default` (if the inner type implements Default) +/// - `AsRef` and `AsMut` +/// - `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 for #type_name { + fn into(self) -> mingling::AnyOutput { + mingling::AnyOutput::new(self) + } + } + + impl Into 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() +} -- cgit