Files
huskies/server/src/service/settings/io.rs
T

53 lines
2.0 KiB
Rust

//! Settings I/O — the ONLY place in `service/settings/` that may perform side effects.
//!
//! Side effects here include: reading/writing `.huskies/project.toml` and
//! spawning the editor process via `std::process::Command`.
//! All business logic, branching, and type definitions belong in `mod.rs`,
//! `project.rs`, or `validate.rs`.
use super::Error;
use std::path::Path;
/// Read the raw TOML content from `config_path`.
///
/// Returns an empty string if the file does not exist yet, so callers can
/// treat a missing config the same as an empty one.
///
/// # Errors
/// - [`Error::Io`] if the file exists but cannot be read.
pub(super) fn read_config_toml(config_path: &Path) -> Result<String, Error> {
if config_path.exists() {
std::fs::read_to_string(config_path).map_err(|e| Error::Io(format!("Read config: {e}")))
} else {
Ok(String::new())
}
}
/// Write `content` to `config_path`, creating parent directories as needed.
///
/// # Errors
/// - [`Error::Io`] if the directory cannot be created or the file write fails.
pub(super) fn write_config_toml(config_path: &Path, content: &str) -> Result<(), Error> {
if let Some(parent) = config_path.parent() {
std::fs::create_dir_all(parent)
.map_err(|e| Error::Io(format!("Create .huskies dir: {e}")))?;
}
std::fs::write(config_path, content).map_err(|e| Error::Io(format!("Write config: {e}")))
}
/// Spawn the editor process with `file_ref` as the sole argument.
///
/// Does not wait for the editor to exit — fire-and-forget so the UI remains
/// responsive.
///
/// # Errors
/// - [`Error::SpawnError`] if the operating system cannot start the process
/// (e.g. the editor binary is not on `$PATH`).
pub(super) fn spawn_editor(editor_command: &str, file_ref: &str) -> Result<(), Error> {
std::process::Command::new(editor_command)
.arg(file_ref)
.spawn()
.map(|_| ())
.map_err(|e| Error::Spawn(format!("Failed to open editor: {e}")))
}