diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-04 13:26:48 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-04 13:26:48 +0800 |
| commit | 4588e17f7ddacd8391a5c881a209735e08d48797 (patch) | |
| tree | 2b513f4d4f8a18ebd3a34cff7c0fb8abf5787321 /mingling_macros/src/func/program_final_gen.rs | |
| parent | f7862affd74ac3b129f9e9791a4cd4e1c7e3e6d1 (diff) | |
feat: add entry metadata system with compile-time typed values
Add `Metadata<B>` trait and `#[metadata(Entry)]` attribute macro
to attach arbitrary, compile-time-typed metadata to entries.
Implement `ProgramCollect::get_metadata<T>()` for runtime retrieval,
backed by a global registry populated by `register_metadata!`.
Extend `pathf` with `MetadataPattern` to resolve metadata types
across modules at build time. Add two examples demonstrating
metadata usage with and without pathf integration.
Diffstat (limited to 'mingling_macros/src/func/program_final_gen.rs')
| -rw-r--r-- | mingling_macros/src/func/program_final_gen.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/mingling_macros/src/func/program_final_gen.rs b/mingling_macros/src/func/program_final_gen.rs index e8545f4..429e60c 100644 --- a/mingling_macros/src/func/program_final_gen.rs +++ b/mingling_macros/src/func/program_final_gen.rs @@ -8,6 +8,7 @@ use crate::COMPILE_TIME_DISPATCHERS; #[cfg(feature = "comp")] use crate::COMPLETIONS; use crate::HELP_REQUESTS; +use crate::METADATA; use crate::PACKED_TYPES; use crate::RENDERERS; use crate::RENDERERS_EXIST; @@ -269,6 +270,38 @@ pub(crate) fn program_final_gen_impl(_input: TokenStream) -> TokenStream { .map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap()) .collect(); + let metadata_tokens: Vec<proc_macro2::TokenStream> = get_global_set(&METADATA) + .lock() + .unwrap() + .clone() + .iter() + .map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap()) + .collect(); + + let get_metadata_fn = if metadata_tokens.is_empty() { + quote! { + fn get_metadata<T: 'static>(_member_id: Self::Enum) -> Option<T> { + None + } + } + } else { + let metadata_arms = metadata_tokens.iter().map(|entry| { + quote! { + #entry + } + }); + quote! { + fn get_metadata<T: 'static>(member_id: Self::Enum) -> Option<T> { + let type_id = ::std::any::TypeId::of::<T>(); + let any = match member_id { + #(#metadata_arms)* + _ => None, + }; + any.and_then(|b| b.downcast::<T>().ok().map(|b| *b)) + } + } + }; + let num_variants = packed_types.len(); let repr_type = if u8::try_from(num_variants).is_ok() { quote! { u8 } @@ -313,6 +346,7 @@ pub(crate) fn program_final_gen_impl(_input: TokenStream) -> TokenStream { } #render_fn #do_chain_fn + #get_metadata_fn fn render_help(any: ::mingling::AnyOutput<Self::Enum>) -> ::mingling::RenderResult { match any.member_id() { #(#help_tokens)* @@ -356,6 +390,7 @@ pub(crate) fn program_final_gen_impl(_input: TokenStream) -> TokenStream { get_global_set(&RENDERERS).lock().unwrap().clear(); get_global_set(&RENDERERS_EXIST).lock().unwrap().clear(); get_global_set(&HELP_REQUESTS).lock().unwrap().clear(); + get_global_set(&METADATA).lock().unwrap().clear(); #[cfg(feature = "comp")] get_global_set(&COMPLETIONS).lock().unwrap().clear(); #[cfg(feature = "dispatch_tree")] |
