use crate::config::ModelConfig;
use crate::io::export::ExportPackage;
use crate::presets::preset;
use crate::presets::preset::Preset;
use std::collections::HashMap;
use std::fs;
use std::path::Path;
#[derive(Debug, Clone, Copy)]
pub enum ImportStrategy {
Merge,
Overwrite,
}
pub fn import_presets(input_path: &Path, strategy: ImportStrategy) -> anyhow::Result<Vec<Preset>> {
let content = fs::read_to_string(input_path)?;
let package: ExportPackage = serde_json::from_str(&content)?;
if !preset::is_valid_version(&package.version) {
anyhow::bail!("无效的版本号: {}", package.version);
}
if package.presets.is_empty() {
anyhow::bail!("导出包必须包含至少一个预设");
}
match strategy {
ImportStrategy::Merge => {
Ok(package.presets)
}
ImportStrategy::Overwrite => {
Ok(package.presets)
}
}
}
pub fn validate_import_file(input_path: &Path) -> anyhow::Result<()> {
if !input_path.exists() {
anyhow::bail!("文件不存在: {:?}", input_path);
}
match input_path.extension().and_then(|e| e.to_str()) {
Some("json") => {}
_ => anyhow::bail!("不支持的文件格式,必须是 JSON 文件"),
}
let content = fs::read_to_string(input_path)?;
let package: ExportPackage = serde_json::from_str(&content)?;
if !preset::is_valid_version(&package.version) {
anyhow::bail!("无效的版本号: {}", package.version);
}
if package.presets.is_empty() {
anyhow::bail!("导出包必须包含至少一个预设");
}
let metadata = fs::metadata(input_path)?;
if metadata.len() > 10 * 1024 * 1024 {
anyhow::bail!("文件过大(最多 10MB)");
}
Ok(())
}
pub fn check_import_dependencies(
package: &ExportPackage,
available_models: &HashMap<String, ModelConfig>,
) -> Vec<String> {
let mut missing_models = Vec::new();
for preset in &package.presets {
for model_name in preset.mappings.values() {
if !available_models.contains_key(model_name) && !missing_models.contains(model_name) {
missing_models.push(model_name.clone());
}
}
}
missing_models
}
pub fn preview_import_changes(
package: &ExportPackage,
existing_presets: &HashMap<String, crate::presets::preset::Preset>,
) -> ImportPreview {
let mut new_presets = Vec::new();
let mut conflict_presets = Vec::new();
let skipped_presets = Vec::new();
for preset in &package.presets {
if existing_presets.contains_key(&preset.name) {
conflict_presets.push(preset.name.clone());
} else {
new_presets.push(preset.name.clone());
}
}
ImportPreview {
new_presets,
conflict_presets,
skipped_presets,
}
}
#[derive(Debug, Clone)]
pub struct ImportPreview {
pub new_presets: Vec<String>,
pub conflict_presets: Vec<String>,
pub skipped_presets: Vec<String>,
}