use std::path::Path;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct PuertoConfig {
pub project: Project,
#[serde(default)]
pub entity: Vec<Entity>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Project {
pub name: String,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub db: bool,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Entity {
pub name: String,
pub use_cases: Vec<String>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub db: bool,
}
pub fn read(base: &Path) -> Result<PuertoConfig, Box<dyn std::error::Error>> {
let path = base.join("puerto.toml");
let src = std::fs::read_to_string(&path)?;
Ok(toml::from_str(&src)?)
}
pub fn write(base: &Path, config: &PuertoConfig) -> Result<(), Box<dyn std::error::Error>> {
let path = base.join("puerto.toml");
std::fs::write(path, toml::to_string_pretty(config)?)?;
Ok(())
}
pub fn add_entity(
base: &Path,
name: &str,
use_cases: Vec<String>,
db: bool,
) -> Result<(), Box<dyn std::error::Error>> {
let mut config = read(base)?;
if config.entity.iter().any(|e| e.name == name) {
return Ok(());
}
config.entity.push(Entity {
name: name.to_string(),
use_cases,
db,
});
write(base, &config)
}
pub fn add_use_case(
base: &Path,
entity_name: &str,
action: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let mut config = read(base)?;
let entity = config
.entity
.iter_mut()
.find(|e| e.name == entity_name)
.ok_or_else(|| format!("entity '{entity_name}' not found in puerto.toml"))?;
if !entity.use_cases.contains(&action.to_string()) {
entity.use_cases.push(action.to_string());
write(base, &config)?;
}
Ok(())
}