use crate::{Result, Runtime};
use chrono::prelude::Local;
use std::fs;
use std::path;
const BACKUP_FORMATS: &[&str] = &[
"%Y_%m_%d",
"%Y_%m_%d-%I_%M%p",
"%Y_%m_%d-%I_%M_%S%p",
"%Y_%m_%d-%I_%M_%S_%f%p",
];
pub(crate) fn backup_file(runtime: &Runtime, filename: &path::PathBuf) -> Result<path::PathBuf> {
runtime.progress(format!("Backing up file: {}", filename.display()));
let now = Local::now();
let filename_str = filename.to_str().ok_or(
runtime
.output
.clone()
.into_error("Unable to format output filename"),
)?;
let file_stem = filename.file_stem().ok_or(
runtime
.output
.clone()
.into_error(format!("Unable to get base file for: {filename_str}",)),
)?;
let file_parent = filename
.parent()
.ok_or(runtime.output.clone().into_error(format!(
"Unable to get parent base file for: {filename_str}",
)))?;
let file_extension = filename.extension().ok_or(
runtime
.output
.clone()
.into_error(format!("Unable to get extension for: {filename_str}",)),
)?;
for time_format in BACKUP_FORMATS.iter() {
let timestamp = now.format(time_format);
let mut new_file = file_parent.to_path_buf();
new_file.push(format!("{}-{timestamp}", file_stem.to_str().unwrap()));
new_file.set_extension(file_extension);
if new_file.exists() {
continue;
}
if let Err(e) = fs::copy(filename, &new_file) {
return Err(runtime
.output
.clone()
.into_error(format!("Error making backup of {filename_str}: {e}",)));
}
return Ok(new_file);
}
Err(runtime.output.clone().into_error(format!(
"Unable to make backup of output file: {filename_str}",
)))
}
#[cfg(test)]
mod tests {
#[test]
fn backup_file() {
}
}