mf_expression/functions/state_guard.rs
1//! State 守卫模块
2//!
3//! 提供 RAII 模式的 State 管理,确保异常安全
4
5use std::sync::Arc;
6use super::mf_function::MfFunctionRegistry;
7use std::marker::PhantomData;
8
9/// State 守卫,使用 RAII 模式自动管理 State 的设置和清理
10///
11/// 当 StateGuard 被创建时,会自动设置当前线程的 State 上下文
12/// 当 StateGuard 被丢弃时(包括异常情况),会自动清理 State 上下文
13///
14/// # 示例
15/// ```rust,ignore
16/// use std::sync::Arc;
17/// use mf_state::State;
18/// use mf_rules_expression::functions::StateGuard;
19///
20/// // 创建 State
21/// let state = Arc::new(State::default());
22///
23/// {
24/// // 设置 State 上下文
25/// let _guard = StateGuard::new(state);
26///
27/// // 在这个作用域内,自定义函数可以访问 State
28/// // 即使发生 panic,State 也会被正确清理
29///
30/// } // 这里 StateGuard 被自动丢弃,State 上下文被清理
31/// ```
32pub struct StateGuard<S> {
33 _private: PhantomData<S>,
34}
35
36impl<S: Send + Sync + 'static> StateGuard<S> {
37 /// 创建新的 State 守卫
38 ///
39 /// # 参数
40 /// * `state` - 要设置的 State 对象
41 ///
42 /// # 返回值
43 /// 返回 StateGuard 实例,当其被丢弃时会自动清理 State
44 pub fn new(state: Arc<S>) -> Self {
45 MfFunctionRegistry::set_current_state(Some(state));
46 Self { _private: PhantomData }
47 }
48
49 /// 创建空的 State 守卫(用于清理已有的 State)
50 ///
51 /// # 返回值
52 /// 返回 StateGuard 实例,会立即清理当前 State 并在丢弃时保持清理状态
53 pub fn empty() -> Self {
54 MfFunctionRegistry::clear_current_state();
55 Self { _private: PhantomData }
56 }
57
58 /// 获取当前是否有活跃的 State
59 ///
60 /// # 返回值
61 /// * `true` - 当前线程有活跃的 State
62 /// * `false` - 当前线程没有 State
63 pub fn has_active_state() -> bool {
64 MfFunctionRegistry::has_current_state()
65 }
66}
67
68impl<S> Drop for StateGuard<S> {
69 /// 自动清理 State 上下文
70 ///
71 /// 当 StateGuard 被丢弃时(正常情况或异常情况),
72 /// 会自动清理当前线程的 State 上下文
73 fn drop(&mut self) {
74 MfFunctionRegistry::clear_current_state();
75 }
76}
77
78/// 便利宏,用于在指定作用域内设置 State
79///
80/// # 示例
81/// ```rust,ignore
82/// use mf_rules_expression::with_state;
83///
84/// let state = Arc::new(State::default());
85///
86/// with_state!(state => {
87/// // 在这个块内,State 是活跃的
88/// });
89/// // State 在这里已经被清理
90/// ```
91#[macro_export]
92macro_rules! with_state {
93 ($state:expr => $block:block) => {{
94 let _guard = $crate::functions::StateGuard::new($state);
95 $block
96 }};
97}
98
99/// 异步版本的 State 守卫便利函数
100///
101/// # 参数
102/// * `state` - 要设置的 State 对象
103/// * `future` - 要在 State 上下文中执行的异步操作
104///
105/// # 返回值
106/// 返回异步操作的结果
107///
108/// # 示例
109/// ```rust,ignore
110/// use mf_rules_expression::functions::with_state_async;
111///
112/// let state = Arc::new(State::default());
113///
114/// let result = with_state_async(state, async {
115/// // aync block
116/// }).await;
117/// ```
118pub async fn with_state_async<S, T, F, Fut>(
119 state: Arc<S>,
120 future: F,
121) -> T
122where
123 S: Send + Sync + 'static,
124 F: FnOnce() -> Fut,
125 Fut: std::future::Future<Output = T>,
126{
127 let _guard = StateGuard::new(state);
128 future().await
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use std::sync::Arc;
135
136 // A dummy struct for testing purposes
137 struct DummyState;
138
139 #[test]
140 fn test_state_guard_basic() {
141 // 初始状态应该没有 State
142 assert!(!StateGuard::<DummyState>::has_active_state());
143
144 {
145 // 创建一个模拟的 State
146 let state = Arc::new(DummyState);
147 let _guard = StateGuard::new(state);
148
149 // 在这个作用域内应该有活跃的 State
150 assert!(StateGuard::<DummyState>::has_active_state());
151 }
152
153 // 离开作用域后,State 应该被清理
154 assert!(!StateGuard::<DummyState>::has_active_state());
155 }
156
157 #[test]
158 fn test_state_guard_panic_safety() {
159 assert!(!StateGuard::<DummyState>::has_active_state());
160
161 let result = std::panic::catch_unwind(|| {
162 let state = Arc::new(DummyState);
163 let _guard = StateGuard::new(state);
164
165 // 模拟 panic
166 panic!("测试 panic 安全性");
167 });
168
169 // 即使发生了 panic,State 也应该被正确清理
170 assert!(!StateGuard::<DummyState>::has_active_state());
171 assert!(result.is_err());
172 }
173
174 #[test]
175 fn test_empty_guard() {
176 let state = Arc::new(DummyState);
177 let _guard = StateGuard::new(state);
178 assert!(StateGuard::<DummyState>::has_active_state());
179
180 // 创建空守卫应该立即清理 State
181 let _guard_empty = StateGuard::<DummyState>::empty();
182 assert!(!StateGuard::<DummyState>::has_active_state());
183 }
184}