use std::path::PathBuf; use chrono::NaiveDateTime; use crate::error::Result; pub mod file; pub mod ftp; pub mod sftp; pub trait RemoteBackupFile { /// Type containing the location of the remote_backup backup type LocationType; /// Get the underlying location type fn location(&self) -> Self::LocationType; /// Get the time the remote_backup file was created fn time_created(&self) -> chrono::NaiveDateTime; /// Parse the time created from the file name fn parse_file_name(file_name: &str) -> Option { let time: Vec<&str> = file_name.split("_backup.tar.gz").collect(); if let Some(time_str) = time.get(0) { chrono::NaiveDateTime::parse_from_str(time_str, "%d-%m-%y_%H.%M.%S").ok() } else { None } } } pub trait RemoteBackupSite { /// Struct representing the location of a backup on the site type FileType: RemoteBackupFile; /// Backup a file to the the remote_backup site fn backup_to_remote(&mut self, file: PathBuf) -> Result<()>; /// Get the locations backups contained on the remote_backup site fn get_backups(&mut self) -> Result>; /// Remove a backup from the side fn remove_backup(&mut self, backup: Self::FileType) -> Result<()>; /// Number of backups to keep on the site fn backups_to_keep(&self) -> usize; /// Cleanup old backups on the remote_backup site fn cleanup(&mut self) -> Result { let mut backups = self.get_backups()?; backups.sort_by_key(|backup| backup.time_created()); let mut backups: Vec = backups.into_iter().rev().collect(); let mut removed_count: usize = 0; if backups.len() > self.backups_to_keep() { for _ in 0..(backups.len() - self.backups_to_keep()) { if let Some(backup) = backups.pop() { self.remove_backup(backup)?; removed_count += 1; } } } Ok(removed_count) } } /// Backup location that can be represented by a path pub struct PathLocation { location: PathBuf, time_created: NaiveDateTime, } impl PathLocation { /// New PathLocation fn new(path: PathBuf) -> Option { if let Some(file_name) = path.file_name() { let file_name = file_name.to_str().unwrap(); if let Some(time) = Self::parse_file_name(file_name) { Some(Self { location: path, time_created: time, }) } else { None } } else { None } } } impl RemoteBackupFile for PathLocation { type LocationType = PathBuf; fn location(&self) -> Self::LocationType { self.location.to_path_buf() } fn time_created(&self) -> NaiveDateTime { self.time_created } }