mf_core/helpers/
runtime_common.rs1use crate::{
13 config::ForgeConfig, debug::debug, extension_manager::ExtensionManager,
14 types::RuntimeOptions, ForgeResult,
15};
16
17pub struct ExtensionManagerHelper;
21
22impl ExtensionManagerHelper {
23 pub fn create_extension_manager(
37 runtime_options: &RuntimeOptions,
38 forge_config: &ForgeConfig,
39 ) -> ForgeResult<ExtensionManager> {
40 if !forge_config.extension.xml_schema_paths.is_empty() {
42 debug!(
43 "使用配置的XML schema路径: {:?}",
44 forge_config.extension.xml_schema_paths
45 );
46
47 let paths: Vec<&str> = forge_config
49 .extension
50 .xml_schema_paths
51 .iter()
52 .map(|s| s.as_str())
53 .collect();
54 let extension_manager = ExtensionManager::from_xml_files(&paths)?;
55
56 let merged_extensions = Self::merge_extensions_with_xml(
58 runtime_options,
59 extension_manager,
60 )?;
61 return Ok(merged_extensions);
62 }
63
64 let default_schema_path = "schema/main.xml";
66 if std::path::Path::new(default_schema_path).exists() {
67 debug!("使用默认的 schema 文件: {}", default_schema_path);
68 let extension_manager =
69 ExtensionManager::from_xml_file(default_schema_path)?;
70 let merged_extensions = Self::merge_extensions_with_xml(
71 runtime_options,
72 extension_manager,
73 )?;
74 return Ok(merged_extensions);
75 }
76
77 debug!("未找到XML schema配置,使用默认扩展");
79 ExtensionManager::new(&runtime_options.get_extensions())
80 }
81
82 pub fn merge_extensions_with_xml(
96 runtime_options: &RuntimeOptions,
97 xml_extension_manager: ExtensionManager,
98 ) -> ForgeResult<ExtensionManager> {
99 let schema = xml_extension_manager.get_schema();
100 let mut all_extensions = Vec::new();
101 let factory = schema.factory();
102 let (nodes, marks) = factory.definitions();
103 for (name, node_type) in nodes {
105 let node = crate::node::Node::create(name, node_type.spec.clone());
106 all_extensions.push(crate::types::Extensions::N(node));
107 }
108
109 for (name, mark_type) in marks {
110 let mark = crate::mark::Mark::new(name, mark_type.spec.clone());
111 all_extensions.push(crate::types::Extensions::M(mark));
112 }
113
114 for ext in runtime_options.get_extensions() {
116 let name = match &ext {
117 crate::types::Extensions::N(node) => &node.name,
118 crate::types::Extensions::M(mark) => &mark.name,
119 crate::types::Extensions::E(_) => {
120 all_extensions.push(ext);
122 continue;
123 },
124 };
125
126 let exists = match &ext {
128 crate::types::Extensions::N(_) => nodes.contains_key(name),
129 crate::types::Extensions::M(_) => marks.contains_key(name),
130 crate::types::Extensions::E(_) => false, };
132
133 if !exists {
134 all_extensions.push(ext);
135 }
136 }
137
138 ExtensionManager::new(&all_extensions)
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn test_extension_manager_helper_creation() {
148 let options = RuntimeOptions::default();
150 let config = ForgeConfig::default();
151
152 let result =
154 ExtensionManagerHelper::create_extension_manager(&options, &config);
155 assert!(result.is_ok());
156 }
157}