use super::{Importer, FormatInfo};
use super::io::SUPPORTED_FORMATS;
use super::dxf::DXFImporter;
use super::svg::SVGImporter;
use super::dwg::DWGImporter;
use super::iges::IGESImporter;
use super::step::STEPImporter;
use crate::data_structure::Document;
use std::path::Path;
pub struct ImporterRegistry {
importers: Vec<Box<dyn Importer>>,
}
impl ImporterRegistry {
pub fn new() -> Self {
let mut registry = Self {
importers: Vec::new(),
};
registry.register_all();
registry
}
fn register_all(&mut self) {
self.importers.push(Box::new(DXFImporter::new()));
self.importers.push(Box::new(SVGImporter::new()));
self.importers.push(Box::new(DWGImporter::new()));
self.importers.push(Box::new(IGESImporter::new()));
self.importers.push(Box::new(STEPImporter::new()));
}
pub fn get_importer(&self, extension: &str) -> Option<&dyn Importer> {
for importer in &self.importers {
if importer.can_import(extension) {
return Some(importer.as_ref());
}
}
None
}
pub fn import_from_file(&self, filename: &str) -> Result<Document, String> {
let path = Path::new(filename);
let extension = path.extension()
.and_then(|ext| ext.to_str())
.map(|ext| ext.to_lowercase())
.ok_or("无法获取文件扩展名")?;
if let Some(importer) = self.get_importer(&extension) {
importer.import_from_file(filename)
.map_err(|e| e.to_string())
} else {
Err(format!("不支持的文件格式: {}", extension))
}
}
pub fn import_from_bytes(&self, data: &[u8], extension: &str) -> Result<Document, String> {
let ext = extension.to_lowercase();
if let Some(importer) = self.get_importer(&ext) {
importer.import_from_bytes(data, &ext)
.map_err(|e| e.to_string())
} else {
Err(format!("不支持的文件格式: {}", ext))
}
}
pub fn supported_formats(&self) -> Vec<&FormatInfo> {
SUPPORTED_FORMATS.iter().collect()
}
}
impl Default for ImporterRegistry {
fn default() -> Self {
Self::new()
}
}
pub fn get_importer(extension: &str) -> Option<Box<dyn Importer>> {
match extension.to_lowercase().as_str() {
"dxf" => Some(Box::new(DXFImporter::new())),
"svg" => Some(Box::new(SVGImporter::new())),
"dwg" => Some(Box::new(DWGImporter::new())),
"iges" | "igs" => Some(Box::new(IGESImporter::new())),
"step" | "stp" => Some(Box::new(STEPImporter::new())),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_importer_registry_formats() {
let registry = ImporterRegistry::new();
let formats = registry.supported_formats();
assert!(formats.len() > 0);
}
#[test]
fn test_get_importer() {
assert!(get_importer("dxf").is_some());
assert!(get_importer("svg").is_some());
assert!(get_importer("dwg").is_some());
assert!(get_importer("iges").is_some());
assert!(get_importer("step").is_some());
assert!(get_importer("unknown").is_none());
}
}