mf_core/extension_manager/mod.rs
1use std::sync::Arc;
2use std::time::Instant;
3
4use mf_model::schema::Schema;
5use mf_state::plugin::Plugin;
6
7use crate::{
8 helpers::get_schema_by_resolved_extensions::get_schema_by_resolved_extensions,
9 metrics, types::Extensions, ForgeResult, XmlSchemaParser, extension::OpFn,
10};
11/// 扩展管理器
12pub struct ExtensionManager {
13 plugins: Vec<Arc<Plugin>>,
14 schema: Arc<Schema>,
15 op_fns: OpFn,
16}
17/// ExtensionManager构建器
18///
19/// 提供灵活的方式来配置和创建ExtensionManager,支持多种扩展来源
20#[derive(Default)]
21pub struct ExtensionManagerBuilder {
22 extensions: Vec<Extensions>,
23 xml_files: Vec<String>,
24 xml_contents: Vec<String>,
25}
26
27impl ExtensionManagerBuilder {
28 /// 创建新的构建器
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 /// 添加代码定义的扩展
34 ///
35 /// # 参数
36 /// * `extension` - 要添加的扩展
37 ///
38 /// # 示例
39 /// ```rust
40 /// use mf_core::{ExtensionManagerBuilder, types::Extensions, node::Node};
41 /// use mf_model::node_definition::NodeSpec;
42 ///
43 /// let node = Node::create("custom_node", NodeSpec::default());
44 /// let manager = ExtensionManagerBuilder::new()
45 /// .add_extension(Extensions::N(node))
46 /// .build()?;
47 /// ```
48 pub fn add_extension(
49 mut self,
50 extension: Extensions,
51 ) -> Self {
52 self.extensions.push(extension);
53 self
54 }
55
56 /// 批量添加代码定义的扩展
57 ///
58 /// # 参数
59 /// * `extensions` - 要添加的扩展列表
60 pub fn add_extensions(
61 mut self,
62 extensions: Vec<Extensions>,
63 ) -> Self {
64 self.extensions.extend(extensions);
65 self
66 }
67
68 /// 添加XML文件路径
69 ///
70 /// # 参数
71 /// * `xml_file_path` - XML schema文件路径
72 ///
73 /// # 示例
74 /// ```rust
75 /// use mf_core::ExtensionManagerBuilder;
76 ///
77 /// let manager = ExtensionManagerBuilder::new()
78 /// .add_xml_file("./schemas/base-nodes.xml")
79 /// .add_xml_file("./schemas/custom-marks.xml")
80 /// .build()?;
81 /// ```
82 pub fn add_xml_file<P: AsRef<str>>(
83 mut self,
84 xml_file_path: P,
85 ) -> Self {
86 self.xml_files.push(xml_file_path.as_ref().to_string());
87 self
88 }
89
90 /// 批量添加XML文件路径
91 ///
92 /// # 参数
93 /// * `xml_file_paths` - XML schema文件路径列表
94 pub fn add_xml_files<P: AsRef<str>>(
95 mut self,
96 xml_file_paths: &[P],
97 ) -> Self {
98 for path in xml_file_paths {
99 self.xml_files.push(path.as_ref().to_string());
100 }
101 self
102 }
103
104 /// 添加XML内容字符串
105 ///
106 /// # 参数
107 /// * `xml_content` - XML schema内容
108 ///
109 /// # 示例
110 /// ```rust
111 /// use mf_core::ExtensionManagerBuilder;
112 ///
113 /// let xml = r#"
114 /// <?xml version="1.0" encoding="UTF-8"?>
115 /// <schema>
116 /// <nodes>
117 /// <node name="custom">
118 /// <desc>自定义节点</desc>
119 /// </node>
120 /// </nodes>
121 /// </schema>
122 /// "#;
123 ///
124 /// let manager = ExtensionManagerBuilder::new()
125 /// .add_xml_content(xml)
126 /// .build()?;
127 /// ```
128 pub fn add_xml_content<S: AsRef<str>>(
129 mut self,
130 xml_content: S,
131 ) -> Self {
132 self.xml_contents.push(xml_content.as_ref().to_string());
133 self
134 }
135
136 /// 批量添加XML内容字符串
137 ///
138 /// # 参数
139 /// * `xml_contents` - XML schema内容列表
140 pub fn add_xml_contents<S: AsRef<str>>(
141 mut self,
142 xml_contents: &[S],
143 ) -> Self {
144 for content in xml_contents {
145 self.xml_contents.push(content.as_ref().to_string());
146 }
147 self
148 }
149
150 /// 构建ExtensionManager
151 ///
152 /// # 返回值
153 /// * `ForgeResult<ExtensionManager>` - 构建的ExtensionManager实例或错误
154 pub fn build(self) -> ForgeResult<ExtensionManager> {
155 let start_time = Instant::now();
156 let mut all_extensions = self.extensions;
157
158 // 解析XML文件
159 for xml_file in &self.xml_files {
160 let extensions =
161 XmlSchemaParser::parse_multi_file_to_extensions(xml_file)
162 .map_err(|e| {
163 crate::error::error_utils::config_error(format!(
164 "解析XML文件 {xml_file} 失败: {e}"
165 ))
166 })?;
167 all_extensions.extend(extensions);
168 }
169
170 // 解析XML内容
171 for xml_content in &self.xml_contents {
172 let extensions = XmlSchemaParser::parse_to_extensions(xml_content)
173 .map_err(|e| {
174 crate::error::error_utils::config_error(format!(
175 "解析XML内容失败: {e}"
176 ))
177 })?;
178 all_extensions.extend(extensions);
179 }
180
181 metrics::xml_parsing_duration(start_time.elapsed());
182
183 // 创建ExtensionManager
184 ExtensionManager::new(&all_extensions)
185 }
186}
187
188impl ExtensionManager {
189 /// 创建ExtensionManager构建器
190 ///
191 /// # 示例
192 /// ```rust
193 /// use mf_core::ExtensionManager;
194 ///
195 /// let manager = ExtensionManager::builder()
196 /// .add_xml_file("./schemas/main.xml")
197 /// .build()?;
198 /// ```
199 pub fn builder() -> ExtensionManagerBuilder {
200 ExtensionManagerBuilder::new()
201 }
202
203 pub fn new(extensions: &Vec<Extensions>) -> ForgeResult<Self> {
204 let start_time = Instant::now();
205 let schema = Arc::new(get_schema_by_resolved_extensions(extensions)?);
206 let mut plugins = vec![];
207 let mut op_fns = vec![];
208 let mut extension_count = 0;
209 let mut plugin_count = 0;
210 for extension in extensions {
211 if let Extensions::E(extension) = extension {
212 extension_count += 1;
213 for plugin in extension.get_plugins() {
214 plugin_count += 1;
215 plugins.push(plugin.clone());
216 }
217 for op_fn in extension.get_op_fns() {
218 op_fns.push(op_fn.clone());
219 }
220 }
221 }
222
223 metrics::extensions_loaded(extension_count);
224 metrics::plugins_loaded(plugin_count);
225 metrics::extension_manager_creation_duration(start_time.elapsed());
226
227 Ok(ExtensionManager { schema, plugins, op_fns })
228 }
229
230 /// 从XML文件创建ExtensionManager(便捷方法)
231 ///
232 /// # 参数
233 /// * `xml_file_path` - XML schema文件路径
234 ///
235 /// # 返回值
236 /// * `ForgeResult<Self>` - 返回ExtensionManager实例或错误
237 ///
238 /// # 示例
239 /// ```rust
240 /// use mf_core::ExtensionManager;
241 ///
242 /// let manager = ExtensionManager::from_xml_file("./schemas/main.xml")?;
243 /// ```
244 pub fn from_xml_file(xml_file_path: &str) -> ForgeResult<Self> {
245 Self::builder().add_xml_file(xml_file_path).build()
246 }
247
248 /// 从XML字符串创建ExtensionManager(便捷方法)
249 ///
250 /// # 参数
251 /// * `xml_content` - XML schema内容字符串
252 ///
253 /// # 返回值
254 /// * `ForgeResult<Self>` - 返回ExtensionManager实例或错误
255 ///
256 /// # 示例
257 /// ```rust
258 /// use mf_core::ExtensionManager;
259 ///
260 /// let xml = r#"
261 /// <?xml version="1.0" encoding="UTF-8"?>
262 /// <schema top_node="doc">
263 /// <nodes>
264 /// <node name="doc">
265 /// <content>paragraph+</content>
266 /// </node>
267 /// </nodes>
268 /// </schema>
269 /// "#;
270 ///
271 /// let manager = ExtensionManager::from_xml_string(xml)?;
272 /// ```
273 pub fn from_xml_string(xml_content: &str) -> ForgeResult<Self> {
274 Self::builder().add_xml_content(xml_content).build()
275 }
276
277 /// 从多个XML文件创建ExtensionManager(便捷方法)
278 ///
279 /// # 参数
280 /// * `xml_file_paths` - XML schema文件路径列表
281 ///
282 /// # 返回值
283 /// * `ForgeResult<Self>` - 返回ExtensionManager实例或错误
284 ///
285 /// # 示例
286 /// ```rust
287 /// use mf_core::ExtensionManager;
288 ///
289 /// let files = vec![
290 /// "./schemas/base-nodes.xml",
291 /// "./schemas/formatting-marks.xml",
292 /// "./schemas/custom-extensions.xml"
293 /// ];
294 ///
295 /// let manager = ExtensionManager::from_xml_files(&files)?;
296 /// ```
297 pub fn from_xml_files(xml_file_paths: &[&str]) -> ForgeResult<Self> {
298 Self::builder().add_xml_files(xml_file_paths).build()
299 }
300
301 /// 从Extensions和XML文件混合创建ExtensionManager(便捷方法)
302 ///
303 /// # 参数
304 /// * `extensions` - 已有的Extensions列表
305 /// * `xml_file_paths` - 额外的XML schema文件路径列表
306 ///
307 /// # 返回值
308 /// * `ForgeResult<Self>` - 返回ExtensionManager实例或错误
309 ///
310 /// # 示例
311 /// ```rust
312 /// use mf_core::{ExtensionManager, types::Extensions};
313 ///
314 /// let existing_extensions = vec![/* ... */];
315 /// let xml_files = vec!["./schemas/additional.xml"];
316 ///
317 /// let manager = ExtensionManager::from_mixed_sources(
318 /// &existing_extensions,
319 /// &xml_files
320 /// )?;
321 /// ```
322 pub fn from_mixed_sources(
323 extensions: &[Extensions],
324 xml_file_paths: &[&str],
325 ) -> ForgeResult<Self> {
326 Self::builder()
327 .add_extensions(extensions.to_vec())
328 .add_xml_files(xml_file_paths)
329 .build()
330 }
331 pub fn get_op_fns(&self) -> &OpFn {
332 &self.op_fns
333 }
334
335 pub fn get_schema(&self) -> Arc<Schema> {
336 self.schema.clone()
337 }
338 pub fn get_plugins(&self) -> &Vec<Arc<Plugin>> {
339 &self.plugins
340 }
341
342 /// 添加从快照恢复的插件
343 pub fn add_restored_plugins(
344 &mut self,
345 plugins: Vec<std::sync::Arc<mf_state::plugin::Plugin>>,
346 ) -> ForgeResult<()> {
347 self.plugins.extend(plugins);
348 Ok(())
349 }
350}