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
102 for (name, node_type) in &schema.nodes {
104 let node = crate::node::Node::create(name, node_type.spec.clone());
105 all_extensions.push(crate::types::Extensions::N(node));
106 }
107
108 for (name, mark_type) in &schema.marks {
109 let mark = crate::mark::Mark::new(name, mark_type.spec.clone());
110 all_extensions.push(crate::types::Extensions::M(mark));
111 }
112
113 for ext in runtime_options.get_extensions() {
115 let name = match &ext {
116 crate::types::Extensions::N(node) => &node.name,
117 crate::types::Extensions::M(mark) => &mark.name,
118 crate::types::Extensions::E(_) => {
119 all_extensions.push(ext);
121 continue;
122 },
123 };
124
125 let exists = match &ext {
127 crate::types::Extensions::N(_) => {
128 schema.nodes.contains_key(name)
129 },
130 crate::types::Extensions::M(_) => {
131 schema.marks.contains_key(name)
132 },
133 crate::types::Extensions::E(_) => false, };
135
136 if !exists {
137 all_extensions.push(ext);
138 }
139 }
140
141 ExtensionManager::new(&all_extensions)
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 fn test_extension_manager_helper_creation() {
151 let options = RuntimeOptions::default();
153 let config = ForgeConfig::default();
154
155 let result =
157 ExtensionManagerHelper::create_extension_manager(&options, &config);
158 assert!(result.is_ok());
159 }
160}