use crate::{Compiler, Result};
use chrono::prelude::Local;
use log::info;
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<P: AsRef<path::Path>>(
compiler: &Compiler,
filename: P,
) -> Result<path::PathBuf> {
let filename = filename.as_ref();
info!("Backing up file: {}", filename.display());
let filename_str = filename
.to_str()
.ok_or(compiler.output_error("Unable to format output filename"))?;
let file_stem = filename
.file_stem()
.ok_or(compiler.output_error(format!("Unable to get base file for: {filename_str}")))?;
let file_parent = filename.parent().ok_or(compiler.output_error(format!(
"Unable to get parent base file for: {filename_str}",
)))?;
let file_extension = filename
.extension()
.ok_or(compiler.output_error(format!("Unable to get extension for: {filename_str}")))?;
let now = Local::now();
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(
compiler.output_error(format!("Error making backup of {filename_str}: {e}",))
);
}
return Ok(new_file);
}
Err(compiler.output_error(format!(
"Unable to make backup of output file: {filename_str}",
)))
}
#[cfg(test)]
mod tests {
#[test]
fn backup_file() {
}
}