diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-28 09:06:08 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-28 09:06:08 +0800 |
| commit | 748c14588cf1c31c8b8d60a9c94349c0173ef607 (patch) | |
| tree | 4c09bfafd93b629a68f0f78902a33e8dd9ef18d1 /mingling_pathf/src/patterns/groupped_derive.rs | |
| parent | 50f2d767e2d07685e49fb7deae68d506ea11a79d (diff) | |
feat(pathf): add build-time type path resolution system
Add `mingling_pathf` sub-crate and `pathf` feature for automatic
resolution of Mingling type module paths at build time. Scans source
files, identifies macro invocations via pattern matchers, and generates
mapping files consumed by `gen_program!()`.
Diffstat (limited to 'mingling_pathf/src/patterns/groupped_derive.rs')
| -rw-r--r-- | mingling_pathf/src/patterns/groupped_derive.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/mingling_pathf/src/patterns/groupped_derive.rs b/mingling_pathf/src/patterns/groupped_derive.rs new file mode 100644 index 0000000..9f7301d --- /dev/null +++ b/mingling_pathf/src/patterns/groupped_derive.rs @@ -0,0 +1,93 @@ +use syn::Item; + +use crate::pattern_analyzer::{AnalyzeItem, AnalyzePattern}; + +/// Matches `#[derive(Groupped)]` and `#[derive(GrouppedSerialize)]`. +/// +/// Covers the forms: +/// - `#[derive(Groupped)] struct T { ... }` +/// - `#[derive(Groupped, Serialize, ...)] struct T { ... }` +/// - `#[derive(GrouppedSerialize)] struct T { ... }` +pub struct GrouppedDerivePattern; + +impl AnalyzePattern for GrouppedDerivePattern { + fn contains(&self, content: &str) -> bool { + content.contains("Groupped") + } + + fn analyze(&self, content: &str) -> Vec<AnalyzeItem> { + let Ok(syntax) = syn::parse_file(content) else { + return Vec::new(); + }; + + let mut items = Vec::new(); + + for item in &syntax.items { + match item { + Item::Struct(s) => { + if has_groupped_derive(&s.attrs) { + items.push(AnalyzeItem { + module: String::new(), + item_name: s.ident.to_string(), + }); + } + } + Item::Enum(e) => { + if has_groupped_derive(&e.attrs) { + items.push(AnalyzeItem { + module: String::new(), + item_name: e.ident.to_string(), + }); + } + } + Item::Union(u) => { + if has_groupped_derive(&u.attrs) { + items.push(AnalyzeItem { + module: String::new(), + item_name: u.ident.to_string(), + }); + } + } + Item::Mod(item_mod) => { + if let Some((_, nested)) = &item_mod.content { + for n in nested { + match n { + Item::Struct(s) if has_groupped_derive(&s.attrs) => { + items.push(AnalyzeItem { + module: item_mod.ident.to_string(), + item_name: s.ident.to_string(), + }); + } + Item::Enum(e) if has_groupped_derive(&e.attrs) => { + items.push(AnalyzeItem { + module: item_mod.ident.to_string(), + item_name: e.ident.to_string(), + }); + } + _ => {} + } + } + } + } + _ => {} + } + } + + items + } +} + +fn has_groupped_derive(attrs: &[syn::Attribute]) -> bool { + attrs.iter().any(|attr| { + if attr.path().is_ident("derive") { + attr.parse_args::<syn::MetaList>().ok().is_some_and(|meta| { + meta.path.segments.iter().any(|seg| { + let name = seg.ident.to_string(); + name == "Groupped" || name == "GrouppedSerialize" + }) + }) + } else { + false + } + }) +} |
