use std::path::{Path, PathBuf};
use crate::definition::Definition;
use super::convert::slug_from_name;
use super::types::{EditorError, EditorModel, EditorSource};
impl EditorModel {
pub fn load(path: &Path) -> Result<Self, EditorError> {
if !path.exists() {
return Err(EditorError::NotFound(path.to_path_buf()));
}
let content = std::fs::read_to_string(path)?;
let def: Definition =
serde_json::from_str(&content).map_err(|e| EditorError::InvalidJson(e.to_string()))?;
Ok(Self::from_definition(
&def,
EditorSource::File(path.to_path_buf()),
))
}
pub fn save_to(&self, path: &Path) -> Result<(), EditorError> {
let def = self.to_definition();
let json = serde_json::to_string_pretty(&def)
.map_err(|e| EditorError::InvalidJson(e.to_string()))?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let temp_path = path.with_extension("bnto.json.tmp");
std::fs::write(&temp_path, &json)?;
std::fs::rename(&temp_path, path)?;
Ok(())
}
pub fn save_path(&self, recipes_dir: &Path) -> PathBuf {
match &self.source {
EditorSource::File(path) => path.clone(),
EditorSource::New | EditorSource::Predefined(_) => {
let slug = slug_from_name(&self.recipe_name);
let filename = if slug.is_empty() {
"untitled".to_string()
} else {
slug
};
recipes_dir.join(format!("{filename}.bnto.json"))
}
}
}
}