54 lines
1.3 KiB
Rust
54 lines
1.3 KiB
Rust
use std::fs;
|
|
use std::io;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
pub fn backup_path(path: &Path) -> PathBuf {
|
|
sibling_with_suffix(path, "bak")
|
|
}
|
|
|
|
pub fn corrupt_path(path: &Path) -> PathBuf {
|
|
sibling_with_suffix(
|
|
path,
|
|
&format!("corrupt.{}", uuid::Uuid::new_v4().hyphenated()),
|
|
)
|
|
}
|
|
|
|
pub fn temp_path(path: &Path) -> PathBuf {
|
|
sibling_with_suffix(path, &format!("tmp.{}", uuid::Uuid::new_v4().hyphenated()))
|
|
}
|
|
|
|
pub fn write_with_backup(path: &Path, contents: &[u8]) -> io::Result<()> {
|
|
if let Some(parent) = path.parent() {
|
|
fs::create_dir_all(parent)?;
|
|
}
|
|
|
|
let temp_path = temp_path(path);
|
|
fs::write(&temp_path, contents)?;
|
|
|
|
let backup_path = backup_path(path);
|
|
if path.exists() {
|
|
fs::copy(path, &backup_path)?;
|
|
fs::remove_file(path)?;
|
|
}
|
|
|
|
match fs::rename(&temp_path, path) {
|
|
Ok(()) => Ok(()),
|
|
Err(error) => {
|
|
let _ = fs::remove_file(&temp_path);
|
|
if !path.exists() && backup_path.exists() {
|
|
let _ = fs::copy(&backup_path, path);
|
|
}
|
|
Err(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn sibling_with_suffix(path: &Path, suffix: &str) -> PathBuf {
|
|
let file_name = path
|
|
.file_name()
|
|
.and_then(|value| value.to_str())
|
|
.unwrap_or("proxywarden-file");
|
|
|
|
path.with_file_name(format!("{file_name}.{suffix}"))
|
|
}
|