unistore_macros/
lib.rs

1//! unistore-macros - Procedural macros for unistore framework
2//!
3//! 提供 `#[derive(Event)]` 等宏,简化事件和组件定义。
4//!
5//! # 示例
6//!
7//! ```ignore
8//! use unistore::sdk::events::Event;
9//! use unistore_macros::Event;
10//!
11//! #[derive(Clone, Event)]
12//! struct OrderCreated {
13//!     order_id: u64,
14//!     amount: f64,
15//! }
16//!
17//! // 自定义事件名称
18//! #[derive(Clone, Event)]
19//! #[event(name = "user.logged_in")]
20//! struct UserLoggedIn {
21//!     user_id: u64,
22//! }
23//! ```
24
25use proc_macro::TokenStream;
26use quote::quote;
27use syn::{parse_macro_input, DeriveInput, Expr, ExprLit, Lit, Meta};
28
29/// 派生 Event trait 的宏
30///
31/// 自动实现 `unistore::sdk::reactive::Event` trait。
32///
33/// # 属性
34///
35/// - `#[event(name = "custom_name")]` - 自定义事件名称(可选)
36///
37/// # 约束
38///
39/// 使用此宏的类型必须同时 derive `Clone`:
40/// ```ignore
41/// #[derive(Clone, Event)]  // Clone 是必须的
42/// struct MyEvent { ... }
43/// ```
44///
45/// # 示例
46///
47/// ## 基本用法(事件名 = 类型名)
48/// ```ignore
49/// #[derive(Clone, Event)]
50/// struct OrderCreated {
51///     order_id: u64,
52/// }
53/// // event_name() 返回 "OrderCreated"
54/// ```
55///
56/// ## 自定义事件名
57/// ```ignore
58/// #[derive(Clone, Event)]
59/// #[event(name = "order.created")]
60/// struct OrderCreated {
61///     order_id: u64,
62/// }
63/// // event_name() 返回 "order.created"
64/// ```
65#[proc_macro_derive(Event, attributes(event))]
66pub fn derive_event(input: TokenStream) -> TokenStream {
67    let input = parse_macro_input!(input as DeriveInput);
68
69    let name = &input.ident;
70    let name_str = name.to_string();
71
72    // 查找 #[event(name = "...")] 属性
73    let custom_name = find_event_name(&input);
74    let event_name = custom_name.unwrap_or(name_str);
75
76    // 生成 impl 代码
77    let expanded = quote! {
78        impl ::unistore::sdk::events::Event for #name {
79            fn event_name() -> &'static str {
80                #event_name
81            }
82        }
83    };
84
85    TokenStream::from(expanded)
86}
87
88/// 从属性中提取自定义事件名
89fn find_event_name(input: &DeriveInput) -> Option<String> {
90    for attr in &input.attrs {
91        if !attr.path().is_ident("event") {
92            continue;
93        }
94
95        // 解析 #[event(name = "...")]
96        if let Ok(nested) = attr
97            .parse_args_with(syn::punctuated::Punctuated::<Meta, syn::Token![,]>::parse_terminated)
98        {
99            for meta in nested {
100                if let Meta::NameValue(nv) = meta {
101                    if nv.path.is_ident("name") {
102                        if let Expr::Lit(ExprLit {
103                            lit: Lit::Str(lit_str),
104                            ..
105                        }) = &nv.value
106                        {
107                            return Some(lit_str.value());
108                        }
109                    }
110                }
111            }
112        }
113    }
114
115    None
116}