use crate::{
config::ForgeConfig, debug::debug, extension_manager::ExtensionManager,
types::RuntimeOptions, ForgeResult,
};
pub struct ExtensionManagerHelper;
impl ExtensionManagerHelper {
pub fn create_extension_manager(
runtime_options: &RuntimeOptions,
forge_config: &ForgeConfig,
) -> ForgeResult<ExtensionManager> {
if !forge_config.extension.xml_schema_paths.is_empty() {
debug!(
"使用配置的XML schema路径: {:?}",
forge_config.extension.xml_schema_paths
);
let paths: Vec<&str> = forge_config
.extension
.xml_schema_paths
.iter()
.map(|s| s.as_str())
.collect();
let extension_manager = ExtensionManager::from_xml_files(&paths)?;
let merged_extensions = Self::merge_extensions_with_xml(
runtime_options,
extension_manager,
)?;
return Ok(merged_extensions);
}
let default_schema_path = "schema/main.xml";
if std::path::Path::new(default_schema_path).exists() {
debug!("使用默认的 schema 文件: {}", default_schema_path);
let extension_manager =
ExtensionManager::from_xml_file(default_schema_path)?;
let merged_extensions = Self::merge_extensions_with_xml(
runtime_options,
extension_manager,
)?;
return Ok(merged_extensions);
}
debug!("未找到XML schema配置,使用默认扩展");
ExtensionManager::new(&runtime_options.get_extensions())
}
pub fn merge_extensions_with_xml(
runtime_options: &RuntimeOptions,
xml_extension_manager: ExtensionManager,
) -> ForgeResult<ExtensionManager> {
let schema = xml_extension_manager.get_schema();
let mut all_extensions = Vec::new();
let factory = schema.factory();
let (nodes, marks) = factory.definitions();
for (name, node_type) in nodes {
let node = crate::node::Node::create(name, node_type.spec.clone());
all_extensions.push(crate::types::Extensions::N(node));
}
for (name, mark_type) in marks {
let mark = crate::mark::Mark::new(name, mark_type.spec.clone());
all_extensions.push(crate::types::Extensions::M(mark));
}
for ext in runtime_options.get_extensions() {
let name = match &ext {
crate::types::Extensions::N(node) => &node.name,
crate::types::Extensions::M(mark) => &mark.name,
crate::types::Extensions::E(_) => {
all_extensions.push(ext);
continue;
},
};
let exists = match &ext {
crate::types::Extensions::N(_) => nodes.contains_key(name),
crate::types::Extensions::M(_) => marks.contains_key(name),
crate::types::Extensions::E(_) => false, };
if !exists {
all_extensions.push(ext);
}
}
ExtensionManager::new(&all_extensions)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extension_manager_helper_creation() {
let options = RuntimeOptions::default();
let config = ForgeConfig::default();
let result =
ExtensionManagerHelper::create_extension_manager(&options, &config);
assert!(result.is_ok());
}
}