aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src/group_impl.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-20 00:59:17 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-20 01:01:27 +0800
commit1f583f625a7d541dc7d47a8136b31d29a5ed5441 (patch)
tree795006c8c2a9f10c866951de5aba318a64007219 /mingling_macros/src/group_impl.rs
parente8ae63988d562969df47ae6d92129974e7fb6980 (diff)
chore(macros): reorganize module hierarchy in mingling_macros
Restructure flat module layout into logical directories (attr/, derive/, func/, systems/, extensions/, utils.rs). Tighten internal function visibility to pub(crate). All public API signatures remain unchanged.
Diffstat (limited to 'mingling_macros/src/group_impl.rs')
-rw-r--r--mingling_macros/src/group_impl.rs147
1 files changed, 0 insertions, 147 deletions
diff --git a/mingling_macros/src/group_impl.rs b/mingling_macros/src/group_impl.rs
deleted file mode 100644
index cac2734..0000000
--- a/mingling_macros/src/group_impl.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-use proc_macro::TokenStream;
-use quote::quote;
-use syn::parse::{Parse, ParseStream};
-use syn::{Ident, Result as SynResult, TypePath};
-
-/// Input for the `group!` macro
-///
-/// # Syntax
-///
-/// ```rust,ignore
-/// /// Only a type path — uses default `crate::ThisProgram` as program
-/// group!(std::io::Error);
-/// group!(ParseIntError);
-///
-/// /// With an alias — creates a `pub type Alias = Path;` and uses `Alias` as variant name
-/// group!(IoError = std::io::Error);
-/// ```
-enum GroupInput {
- /// `group!(TypePath)` — variant name is the last path segment
- Plain(TypePath),
-
- /// `group!(Alias = TypePath)` — variant name is `Alias`, also generates `pub type Alias = TypePath;`
- Aliased { alias: Ident, type_path: TypePath },
-}
-
-impl Parse for GroupInput {
- fn parse(input: ParseStream) -> SynResult<Self> {
- // Peek ahead: if the second token is `=`, parse as aliased form
- let fork = input.fork();
- let _first: Ident = fork.parse()?;
- if fork.peek(syn::Token![=]) {
- // Consume the ident and `=` from the real input
- let alias: Ident = input.parse()?;
- let _eq: syn::Token![=] = input.parse()?;
- let type_path: TypePath = input.parse()?;
- Ok(GroupInput::Aliased { alias, type_path })
- } else {
- let type_path: TypePath = input.parse()?;
- Ok(GroupInput::Plain(type_path))
- }
- }
-}
-
-/// Convert a type path into a valid module name segment
-///
-/// e.g. `std::io::Error` -> `internal_group_std_io_error`
-fn module_name_from_type(type_path: &TypePath) -> Ident {
- let segments: Vec<String> = type_path
- .path
- .segments
- .iter()
- .map(|seg| seg.ident.to_string().to_lowercase())
- .collect();
- Ident::new(
- &format!("internal_group_{}", segments.join("_")),
- proc_macro2::Span::call_site(),
- )
-}
-
-/// Get the last segment name of a type path (the simple type name)
-///
-/// e.g. `std::io::Error` -> `Error`
-fn type_simple_name(type_path: &TypePath) -> Ident {
- type_path
- .path
- .segments
- .last()
- .expect("TypePath must have at least one segment")
- .ident
- .clone()
-}
-
-/// Generate the `use` token for the type path inside the generated module.
-///
-/// - Multi-segment path (e.g. `std::num::ParseIntError`): `use std::num::ParseIntError;`
-/// - Single-segment path (e.g. `ParseIntError`): `use super::ParseIntError;`
-fn gen_type_use(type_path: &TypePath) -> proc_macro2::TokenStream {
- if type_path.path.segments.len() > 1 {
- // Full path: use it directly
- quote! {
- #[allow(unused_imports)]
- use #type_path;
- }
- } else {
- // Single ident: import from parent scope
- let ident = type_simple_name(type_path);
- quote! {
- #[allow(unused_imports)]
- use super::#ident;
- }
- }
-}
-
-pub fn group_macro(input: TokenStream) -> TokenStream {
- let input = syn::parse_macro_input!(input as GroupInput);
-
- let is_aliased = matches!(input, GroupInput::Aliased { .. });
-
- let (type_path, type_name, alias_stmt) = match input {
- GroupInput::Plain(type_path) => {
- let type_name = type_simple_name(&type_path);
- (type_path, type_name, quote! {})
- }
- GroupInput::Aliased { alias, type_path } => {
- let type_name = alias.clone();
- let alias_stmt = quote! {
- pub type #alias = #type_path;
- };
- (type_path, type_name, alias_stmt)
- }
- };
-
- let program_path = crate::default_program_path();
-
- // Create a unique module name from the type path (use alias name for aliased form)
- let module_name = module_name_from_type(&type_path);
- // Generate the appropriate `use` statement for the type
- let type_use = gen_type_use(&type_path);
-
- // For aliased form, also import the alias from parent scope
- let alias_use = if is_aliased {
- quote! { use super::#type_name; }
- } else {
- quote! {}
- };
-
- // Generate the module with the Grouped implementation
- let expanded = quote! {
- #alias_stmt
- #[allow(non_camel_case_types)]
- mod #module_name {
- use #program_path as __MinglingProgram;
- #type_use
- #alias_use
-
- impl ::mingling::Grouped<__MinglingProgram> for #type_name {
- fn member_id() -> __MinglingProgram {
- __MinglingProgram::#type_name
- }
- }
-
- ::mingling::macros::register_type!(#type_name);
- }
- };
-
- expanded.into()
-}