1use crate::error::{ForgeError, ForgeResult};
5
6pub trait UnwrapHelpers<T> {
8 fn unwrap_or_forge_error(
10 self,
11 context: &str,
12 ) -> ForgeResult<T>;
13
14 fn unwrap_or_internal_error(
16 self,
17 context: &str,
18 location: &str,
19 ) -> ForgeResult<T>;
20}
21
22impl<T> UnwrapHelpers<T> for Option<T> {
23 fn unwrap_or_forge_error(
24 self,
25 context: &str,
26 ) -> ForgeResult<T> {
27 self.ok_or_else(|| ForgeError::Internal {
28 message: format!("意外的 None 值: {context}"),
29 location: None,
30 })
31 }
32
33 fn unwrap_or_internal_error(
34 self,
35 context: &str,
36 location: &str,
37 ) -> ForgeResult<T> {
38 self.ok_or_else(|| ForgeError::Internal {
39 message: format!("意外的 None 值: {context}"),
40 location: Some(location.to_string()),
41 })
42 }
43}
44
45impl<T, E> UnwrapHelpers<T> for Result<T, E>
46where
47 E: std::error::Error + Send + Sync + 'static,
48{
49 fn unwrap_or_forge_error(
50 self,
51 context: &str,
52 ) -> ForgeResult<T> {
53 self.map_err(|e| ForgeError::Internal {
54 message: format!("操作失败: {context}"),
55 location: Some(e.to_string()),
56 })
57 }
58
59 fn unwrap_or_internal_error(
60 self,
61 context: &str,
62 location: &str,
63 ) -> ForgeResult<T> {
64 self.map_err(|e| ForgeError::Internal {
65 message: format!("操作失败: {context}"),
66 location: Some(format!("{location}: {e}")),
67 })
68 }
69}
70
71pub mod lock_helpers {
73 use super::*;
74 use std::sync::{RwLock, Mutex};
75
76 pub fn read_lock<'a, T>(
78 lock: &'a RwLock<T>,
79 context: &str,
80 ) -> ForgeResult<std::sync::RwLockReadGuard<'a, T>> {
81 lock.read().map_err(|_| ForgeError::Concurrency {
82 message: format!("无法获取读锁: {context}"),
83 source: None,
84 })
85 }
86
87 pub fn write_lock<'a, T>(
89 lock: &'a RwLock<T>,
90 context: &str,
91 ) -> ForgeResult<std::sync::RwLockWriteGuard<'a, T>> {
92 lock.write().map_err(|_| ForgeError::Concurrency {
93 message: format!("无法获取写锁: {context}"),
94 source: None,
95 })
96 }
97
98 pub fn mutex_lock<'a, T>(
100 lock: &'a Mutex<T>,
101 context: &str,
102 ) -> ForgeResult<std::sync::MutexGuard<'a, T>> {
103 lock.lock().map_err(|_| ForgeError::Concurrency {
104 message: format!("无法获取互斥锁: {context}"),
105 source: None,
106 })
107 }
108}
109
110pub mod collection_helpers {
112 use super::*;
113 use std::collections::HashMap;
114
115 pub fn get_required<'a, K, V>(
117 map: &'a HashMap<K, V>,
118 key: &K,
119 context: &str,
120 ) -> ForgeResult<&'a V>
121 where
122 K: std::hash::Hash + Eq + std::fmt::Debug,
123 {
124 map.get(key).ok_or_else(|| ForgeError::Internal {
125 message: format!("必需的键不存在: {key:?} ({context})"),
126 location: None,
127 })
128 }
129
130 pub fn get_at_index<'a, T>(
132 vec: &'a [T],
133 index: usize,
134 context: &str,
135 ) -> ForgeResult<&'a T> {
136 vec.get(index).ok_or_else(|| ForgeError::Internal {
137 message: format!(
138 "索引 {} 超出范围,长度: {} ({})",
139 index,
140 vec.len(),
141 context
142 ),
143 location: None,
144 })
145 }
146}
147
148pub mod schema_helpers {
150 use super::*;
151 use mf_model::schema::{Schema, SchemaSpec};
152 use std::sync::Arc;
153
154 pub fn compile_schema(
156 spec: SchemaSpec,
157 context: &str,
158 ) -> ForgeResult<Arc<Schema>> {
159 Schema::compile(spec).map(Arc::new).map_err(|e| {
160 ForgeError::Validation {
161 message: format!("Schema 编译失败: {e} ({context})"),
162 field: None,
163 }
164 })
165 }
166}
167
168pub mod state_helpers {
170 use super::*;
171
172 pub fn get_mut_state<'a, T>(
174 option: &'a mut Option<T>,
175 context: &str,
176 ) -> ForgeResult<&'a mut T> {
177 option.as_mut().ok_or_else(|| ForgeError::State {
178 message: format!("状态未初始化: {context}"),
179 source: None,
180 })
181 }
182
183 pub fn get_state<'a, T>(
185 option: &'a Option<T>,
186 context: &str,
187 ) -> ForgeResult<&'a T> {
188 option.as_ref().ok_or_else(|| ForgeError::State {
189 message: format!("状态未初始化: {context}"),
190 source: None,
191 })
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn test_option_helpers() {
201 let some_val: Option<i32> = Some(42);
202 let none_val: Option<i32> = None;
203
204 assert!(some_val.unwrap_or_forge_error("测试值").is_ok());
205 assert!(none_val.unwrap_or_forge_error("空值测试").is_err());
206 }
207
208 #[test]
209 fn test_collection_helpers() {
210 use std::collections::HashMap;
211
212 let mut map = HashMap::new();
213 map.insert("key1", "value1");
214
215 assert!(
216 collection_helpers::get_required(&map, &"key1", "存在的键").is_ok()
217 );
218 assert!(
219 collection_helpers::get_required(&map, &"key2", "不存在的键")
220 .is_err()
221 );
222 }
223}