use crate::app::compass::CompassAppError;
use routee_compass_core::config::CompassConfigurationError;
use serde::{Deserialize, Serialize};
use std::{
fs::{File, OpenOptions},
path::Path,
};
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(rename_all = "snake_case")]
pub enum WriteMode {
#[default]
Append,
Overwrite,
Error,
}
impl WriteMode {
pub fn open_file(&self, path: &Path) -> Result<File, CompassAppError> {
match self {
WriteMode::Append => {
if !path.exists() {
create_file(path)?;
}
open_append(path)
}
WriteMode::Overwrite => {
remove_if_exists(path)?;
create_file(path)?;
open_append(path)
}
WriteMode::Error => {
if path.exists() {
Err(CompassAppError::CompassConfigurationError(
CompassConfigurationError::UserConfigurationError(format!(
"file exists but write mode is 'error' {}",
path.to_str().unwrap_or_default()
)),
))?
}
create_file(path)?;
open_append(path)
}
}
}
}
fn remove_if_exists(path: &Path) -> Result<(), CompassAppError> {
if path.exists() {
std::fs::remove_file(path).map_err(|e| {
CompassAppError::BuildFailure(format!(
"attempting to remove existing file {} in overwrite mode, {e}",
path.to_string_lossy()
))
})
} else {
Ok(())
}
}
fn open_append(path: &Path) -> Result<File, CompassAppError> {
OpenOptions::new().append(true).open(path).map_err(|e| {
CompassAppError::InternalError(format!(
"failure opening file {} in append mode: {}",
path.to_str().unwrap_or_default(),
e
))
})
}
fn create_file(path: &Path) -> Result<File, CompassConfigurationError> {
File::create(path).map_err(|e| {
CompassConfigurationError::UserConfigurationError(format!("Could not create file: {e}"))
})
}