diff --git a/src/backups.rs b/src/backups.rs index 4d6ee8e..c312949 100644 --- a/src/backups.rs +++ b/src/backups.rs @@ -174,7 +174,7 @@ impl Backup { &self.name } - pub fn device<'a>(&'a self, devices: &'a Vec) -> Option<&Device> { + pub fn device<'a>(&'a self, devices: &'a [Device]) -> Option<&Device> { devices.iter().find(|dev| dev.name() == self.device) } @@ -190,7 +190,7 @@ impl Backup { &self.command } - pub fn add_log(&mut self, newlog: BackupLog) -> () { + pub fn add_log(&mut self, newlog: BackupLog) { self.logs.push(newlog) } diff --git a/src/cmd_backup.rs b/src/cmd_backup.rs index 3181d3b..020afd5 100644 --- a/src/cmd_backup.rs +++ b/src/cmd_backup.rs @@ -1,7 +1,7 @@ use std::{ collections::HashMap, io::{self, stdout, Write}, - path::PathBuf, + path::{PathBuf, Path}, }; use anyhow::{anyhow, Context, Ok, Result}; @@ -28,21 +28,21 @@ pub(crate) fn cmd_backup_add( dest: PathBuf, cmd: BackupAddCommands, repo: Repository, - config_dir: &PathBuf, + config_dir: &Path, storages: &Storages, ) -> Result<()> { trace!("Canonicalize path: {:?}", src); let src = canonicalize(util::expand_tilde(src)?)?; trace!("Canonicalize path: {:?}", dest); let dest = canonicalize(util::expand_tilde(dest)?)?; - let device = devices::get_device(&config_dir)?; + let device = devices::get_device(config_dir)?; let new_backup = new_backup(name, src, dest, cmd, &device, storages)?; let new_backup_name = new_backup.name().clone(); - let mut backups = Backups::read(&config_dir, &device)?; + let mut backups = Backups::read(config_dir, &device)?; println!("Backup config:"); serde_yaml::to_writer(stdout(), &new_backup)?; backups.add(new_backup)?; - backups.write(&config_dir, &device)?; + backups.write(config_dir, &device)?; add_and_commit( &repo, @@ -64,12 +64,12 @@ fn new_backup( storages: &Storages, ) -> Result { let (src_parent, src_diff) = - util::min_parent_storage(&src, &storages, &device).context(format!( + util::min_parent_storage(&src, storages, device).context(format!( "Coundn't find parent storage for src directory {}", src.display() ))?; let (dest_parent, dest_diff) = - util::min_parent_storage(&dest, &storages, &device).context(format!( + util::min_parent_storage(&dest, storages, device).context(format!( "Couldn't find parent storage for dest directory: {}", dest.display() ))?; @@ -94,6 +94,166 @@ fn new_backup( )) } +pub fn cmd_backup_list( + src_storage: Option, + dest_storage: Option, + device_name: Option, + longprint: bool, + config_dir: &Path, + storages: &Storages, +) -> Result<()> { + let devices = devices::get_devices(config_dir)?; + let backups: HashMap<(String, String), Backup> = match device_name { + Some(device_name) => { + let device = devices + .iter() + .find(|dev| dev.name() == device_name) + .context(format!("Device with name {} doesn't exist", device_name))?; + let backups = Backups::read(config_dir, device)?; + let mut allbackups = HashMap::new(); + for (name, backup) in backups.list { + if allbackups.insert((device.name(), name), backup).is_some() { + return Err(anyhow!("unexpected duplication in backups hashmap")); + }; + } + allbackups + } + None => { + let mut allbackups = HashMap::new(); + for device in &devices { + let backups = Backups::read(config_dir, device)?; + for (name, backup) in backups.list { + if allbackups.insert((device.name(), name), backup).is_some() { + return Err(anyhow!("unexpected duplication in backups hashmap")); + }; + } + } + allbackups + } + }; + // source/destination filtering + let backups: HashMap<(String, String), Backup> = backups + .into_iter() + .filter(|((_dev, _name), backup)| { + let src_matched = match &src_storage { + Some(src_storage) => &backup.source().storage == src_storage, + None => true, + }; + let dest_matched = match &dest_storage { + Some(dest_storage) => &backup.destination().storage == dest_storage, + None => true, + }; + src_matched && dest_matched + }) + .collect(); + + let mut stdout = io::BufWriter::new(io::stdout()); + write_backups_list(&mut stdout, backups, longprint, storages, &devices)?; + stdout.flush()?; + Ok(()) +} + +/// TODO: status printing +fn write_backups_list( + mut writer: impl io::Write, + backups: HashMap<(String, String), Backup>, + longprint: bool, + storages: &Storages, + devices: &[Device], +) -> Result<()> { + let mut name_width = 0; + let mut dev_width = 0; + let mut src_width = 0; + let mut src_storage_width = 0; + let mut dest_width = 0; + let mut dest_storage_width = 0; + let mut cmd_name_width = 0; + // get widths + for ((dev, _name), backup) in &backups { + let device = backup.device(devices).context(format!( + "Couldn't find device specified in backup config {}", + backup.name() + ))?; + name_width = name_width.max(backup.name().width()); + dev_width = dev_width.max(dev.width()); + let src = backup.source().path(storages, device)?; + src_width = src_width.max(format!("{}", src.display()).width()); + src_storage_width = src_storage_width.max(backup.source().storage.width()); + let dest = backup.destination().path(storages, device)?; + dest_width = dest_width.max(format!("{}", dest.display()).width()); + dest_storage_width = dest_storage_width.max(backup.destination().storage.width()); + let cmd_name = backup.command().name(); + cmd_name_width = cmd_name_width.max(cmd_name.width()); + } + // main printing + for ((dev, _name), backup) in &backups { + let device = backup.device(devices).context(format!( + "Couldn't find device specified in backup config {}", + backup.name() + ))?; + let src = backup.source().path(storages, device)?; + let dest = backup.destination().path(storages, device)?; + let cmd_name = backup.command().name(); + let last_backup_elapsed = match backup.last_backup() { + Some(log) => { + let time = Local::now() - log.datetime; + util::format_summarized_duration(time) + } + None => "---".to_string(), + }; + writeln!( + writer, + "{name:, + repo: Repository, + config_dir: &Path, +) -> Result<()> { + let device = devices::get_device(config_dir)?; + let mut backups = Backups::read(config_dir, &device)?; + let backup = backups + .get_mut(&name) + .context(format!("Failed to get backup with name {}", name))?; + trace!("Got backup: {:?}", backup); + let backup_name = backup.name().clone(); + let status = BackupResult::from_exit_code(exit_status); + let new_log = BackupLog::new_with_current_time(status, log.unwrap_or("".to_string())); + trace!("New backup log: {:?}", new_log); + backup.add_log(new_log); + trace!("Added"); + backups.write(config_dir, &device)?; + add_and_commit( + &repo, + &backups::backups_file(&device), + &format!("Done backup: {}", backup_name), + )?; + Ok(()) +} + #[cfg(test)] mod test { use std::path::{Component, PathBuf}; @@ -162,166 +322,3 @@ mod test { Ok(()) } } - -pub fn cmd_backup_list( - src_storage: Option, - dest_storage: Option, - device_name: Option, - longprint: bool, - config_dir: &PathBuf, - storages: &Storages, -) -> Result<()> { - let devices = devices::get_devices(&config_dir)?; - let backups: HashMap<(String, String), Backup> = match device_name { - Some(device_name) => { - let device = devices - .iter() - .find(|dev| dev.name() == device_name) - .context(format!("Device with name {} doesn't exist", device_name))?; - let backups = Backups::read(&config_dir, device)?; - let mut allbackups = HashMap::new(); - for (name, backup) in backups.list { - if allbackups.insert((device.name(), name), backup).is_some() { - return Err(anyhow!("unexpected duplication in backups hashmap")); - }; - } - allbackups - } - None => { - let mut allbackups = HashMap::new(); - for device in &devices { - let backups = Backups::read(&config_dir, &device)?; - for (name, backup) in backups.list { - if allbackups.insert((device.name(), name), backup).is_some() { - return Err(anyhow!("unexpected duplication in backups hashmap")); - }; - } - } - allbackups - } - }; - // source/destination filtering - let backups: HashMap<(String, String), Backup> = backups - .into_iter() - .filter(|((_dev, _name), backup)| { - let src_matched = match &src_storage { - Some(src_storage) => &backup.source().storage == src_storage, - None => true, - }; - let dest_matched = match &dest_storage { - Some(dest_storage) => &backup.destination().storage == dest_storage, - None => true, - }; - src_matched && dest_matched - }) - .collect(); - - let mut stdout = io::BufWriter::new(io::stdout()); - write_backups_list(&mut stdout, backups, longprint, storages, &devices)?; - stdout.flush()?; - Ok(()) -} - -/// TODO: status printing -fn write_backups_list( - mut writer: impl io::Write, - backups: HashMap<(String, String), Backup>, - longprint: bool, - storages: &Storages, - devices: &Vec, -) -> Result<()> { - let mut name_width = 0; - let mut dev_width = 0; - let mut src_width = 0; - let mut src_storage_width = 0; - let mut dest_width = 0; - let mut dest_storage_width = 0; - let mut cmd_name_width = 0; - // get widths - for ((dev, _name), backup) in &backups { - let device = backup.device(devices).context(format!( - "Couldn't find device specified in backup config {}", - backup.name() - ))?; - name_width = name_width.max(backup.name().width()); - dev_width = dev_width.max(dev.width()); - let src = backup.source().path(&storages, &device)?; - src_width = src_width.max(format!("{}", src.display()).width()); - src_storage_width = src_storage_width.max(backup.source().storage.width()); - let dest = backup.destination().path(&storages, &device)?; - dest_width = dest_width.max(format!("{}", dest.display()).width()); - dest_storage_width = dest_storage_width.max(backup.destination().storage.width()); - let cmd_name = backup.command().name(); - cmd_name_width = cmd_name_width.max(cmd_name.width()); - } - // main printing - for ((dev, _name), backup) in &backups { - let device = backup.device(devices).context(format!( - "Couldn't find device specified in backup config {}", - backup.name() - ))?; - let src = backup.source().path(&storages, &device)?; - let dest = backup.destination().path(&storages, &device)?; - let cmd_name = backup.command().name(); - let last_backup_elapsed = match backup.last_backup() { - Some(log) => { - let time = Local::now() - log.datetime; - util::format_summarized_duration(time) - } - None => { - format!("---") - } - }; - writeln!( - writer, - "{name:, - repo: Repository, - config_dir: &PathBuf, -) -> Result<()> { - let device = devices::get_device(&config_dir)?; - let mut backups = Backups::read(&config_dir, &device)?; - let backup = backups - .get_mut(&name) - .context(format!("Failed to get backup with name {}", name))?; - trace!("Got backup: {:?}", backup); - let backup_name = backup.name().clone(); - let status = BackupResult::from_exit_code(exit_status); - let new_log = BackupLog::new_with_current_time(status, log.unwrap_or("".to_string())); - trace!("New backup log: {:?}", new_log); - backup.add_log(new_log); - trace!("Added"); - backups.write(&config_dir, &device)?; - add_and_commit( - &repo, - &backups::backups_file(&device), - &format!("Done backup: {}", backup_name), - )?; - Ok(()) -} diff --git a/src/cmd_check.rs b/src/cmd_check.rs index 0ae7b96..abda3dd 100644 --- a/src/cmd_check.rs +++ b/src/cmd_check.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use anyhow::{anyhow, Context, Result}; @@ -8,16 +8,16 @@ use crate::{ storages::{Storage, StorageExt, Storages}, }; -pub(crate) fn cmd_check(config_dir: &PathBuf) -> Result<()> { +pub(crate) fn cmd_check(config_dir: &Path) -> Result<()> { info!("Config dir: {}", &config_dir.display()); - let device = devices::get_device(&config_dir)?; + let device = devices::get_device(config_dir)?; info!("Current device: {:?}", device); - let devices = devices::get_devices(&config_dir)?; + let devices = devices::get_devices(config_dir)?; info!("Configured devices: {:?}", devices); - let storages = Storages::read(&config_dir)?; + let storages = Storages::read(config_dir)?; info!("Storages: {:?}", storages); if !(storages.list.iter().all(|(_name, storage)| match storage { Storage::SubDirectory(storage) => storage.parent(&storages).is_some(), @@ -30,7 +30,7 @@ pub(crate) fn cmd_check(config_dir: &PathBuf) -> Result<()> { info!("All SubDirectory's parent exists."); for device in &devices { - let backups = Backups::read(&config_dir, &device)?; + let backups = Backups::read(config_dir, device)?; for (name, backup) in &backups.list { if name != backup.name() { return Err(anyhow!( diff --git a/src/cmd_init.rs b/src/cmd_init.rs index b4f4b6f..7872aa2 100644 --- a/src/cmd_init.rs +++ b/src/cmd_init.rs @@ -15,7 +15,7 @@ use std::io::{BufWriter, Write}; use std::path::{self, Path, PathBuf}; fn clone_repo( - repo_url: &String, + repo_url: &str, use_sshagent: bool, ssh_key: Option, config_dir: &path::PathBuf, @@ -24,7 +24,7 @@ fn clone_repo( if ssh_key.is_none() && !use_sshagent { info!("No authentication will be used."); info!("Use either ssh_key or ssh-agent to access private repository"); - return Ok(Repository::clone(&repo_url, &config_dir)?); + return Ok(Repository::clone(repo_url, config_dir)?); } // using credentials @@ -68,7 +68,7 @@ fn clone_repo( let mut builder = git2::build::RepoBuilder::new(); builder.fetch_options(fo); - Ok(builder.clone(&repo_url, config_dir)?) + Ok(builder.clone(repo_url, config_dir)?) } pub(crate) fn cmd_init( @@ -91,22 +91,21 @@ pub(crate) fn cmd_init( let repo = match repo_url { Some(repo_url) => { trace!("repo: {}", repo_url); - let repo = clone_repo(&repo_url, use_sshagent, ssh_key, config_dir)?; - repo + clone_repo(&repo_url, use_sshagent, ssh_key, config_dir)? } None => { trace!("No repo provided"); println!("Initializing for the first device..."); // create repository - let repo = Repository::init(&config_dir)?; + let repo = Repository::init(config_dir)?; // set up gitignore { - let f = File::create(&config_dir.join(".gitignore"))?; + let f = File::create(config_dir.join(".gitignore"))?; { let mut buf = BufWriter::new(f); - buf.write("devname".as_bytes())?; + buf.write_all("devname".as_bytes())?; } add_and_commit(&repo, Path::new(".gitignore"), "Add devname to gitignore.")?; full_status(&repo)?; @@ -115,7 +114,7 @@ pub(crate) fn cmd_init( // TDOO: wrap up below into one commit? // set up devices.yml let devices: Vec = vec![]; - write_devices(&config_dir, devices)?; + write_devices(config_dir, devices)?; add_and_commit( &repo, Path::new(DEVICESFILE), @@ -123,7 +122,7 @@ pub(crate) fn cmd_init( )?; // set up storages.yml let storages = Storages::new(); - storages.write(&config_dir)?; + storages.write(config_dir)?; add_and_commit( &repo, Path::new(STORAGESFILE), @@ -131,7 +130,7 @@ pub(crate) fn cmd_init( )?; // set up directory for backups - DirBuilder::new().create(&config_dir.join(backups::BACKUPSDIR))?; + DirBuilder::new().create(config_dir.join(backups::BACKUPSDIR))?; repo } @@ -155,7 +154,7 @@ pub(crate) fn cmd_init( // Add new device to devices.yml { - let mut devices: Vec = get_devices(&config_dir)?; + let mut devices: Vec = get_devices(config_dir)?; trace!("devices: {:?}", devices); if devices.iter().any(|x| x.name() == device.name()) { error!("Device name `{}` is already used.", device.name()); @@ -164,21 +163,21 @@ pub(crate) fn cmd_init( } devices.push(device.clone()); trace!("Devices: {:?}", devices); - write_devices(&config_dir, devices)?; + write_devices(config_dir, devices)?; } full_status(&repo)?; // commit add_and_commit( &repo, - &Path::new(DEVICESFILE), + Path::new(DEVICESFILE), &format!("Add new device: {}", &device.name()), )?; // backups/[device].yml { let backups = Backups::new(); - backups.write(&config_dir, &device)?; + backups.write(config_dir, &device)?; } add_and_commit( &repo, diff --git a/src/cmd_storage.rs b/src/cmd_storage.rs index f59bb03..fb4194e 100644 --- a/src/cmd_storage.rs +++ b/src/cmd_storage.rs @@ -27,14 +27,14 @@ use crate::{ pub(crate) fn cmd_storage_add( args: StorageAddCommands, repo: Repository, - config_dir: &PathBuf, + config_dir: &Path, ) -> Result<()> { trace!("Storage Add with args: {:?}", args); // Get storages - let mut storages = Storages::read(&config_dir)?; + let mut storages = Storages::read(config_dir)?; trace!("found storages: {:?}", storages); - let device = devices::get_device(&config_dir)?; + let device = devices::get_device(config_dir)?; let storage = match args { StorageAddCommands::Physical { name, path } => { if !is_unique_name(&name, &storages) { @@ -54,7 +54,7 @@ pub(crate) fn cmd_storage_add( )? }; println!("storage: {}: {:?}", storage.name(), storage); - Storage::PhysicalStorage(storage) + Storage::Physical(storage) } StorageAddCommands::Directory { name, @@ -113,12 +113,12 @@ pub(crate) fn cmd_storage_add( trace!("updated storages: {:?}", storages); // write to file - storages.write(&config_dir)?; + storages.write(config_dir)?; // commit add_and_commit( &repo, - &Path::new(storages::STORAGESFILE), + Path::new(storages::STORAGESFILE), &format!( "Add new storage({}): {}", new_storage_type, new_storage_name @@ -163,19 +163,19 @@ fn manually_construct_physical_drive_partition( fs, is_removable, local_info, - &device, + device, )) } -pub(crate) fn cmd_storage_list(config_dir: &PathBuf, with_note: bool) -> Result<()> { +pub(crate) fn cmd_storage_list(config_dir: &Path, with_note: bool) -> Result<()> { // Get storages - let storages = Storages::read(&config_dir)?; + let storages = Storages::read(config_dir)?; trace!("found storages: {:?}", storages); if storages.list.is_empty() { println!("No storages found"); return Ok(()); } - let device = devices::get_device(&config_dir)?; + let device = devices::get_device(config_dir)?; let mut stdout = io::BufWriter::new(io::stdout()); write_storages_list(&mut stdout, &storages, &device, with_note)?; stdout.flush()?; @@ -190,12 +190,12 @@ fn write_storages_list( ) -> Result<()> { let name_width = storages .list - .iter() - .map(|(_k, v)| v.name().width()) + .values() + .map(|v| v.name().width()) .max() .unwrap(); trace!("name widths: {}", name_width); - for (_k, storage) in &storages.list { + for storage in storages.list.values() { let size_str = match storage.capacity() { Some(b) => Byte::from_bytes(b.into()) .get_appropriate_unit(true) @@ -203,7 +203,7 @@ fn write_storages_list( .to_string(), None => "".to_string(), }; - let isremovable = if let Storage::PhysicalStorage(s) = storage { + let isremovable = if let Storage::Physical(s) = storage { if s.is_removable() { "+" } else { @@ -212,7 +212,7 @@ fn write_storages_list( } else { " " }; - let path = storage.mount_path(&device).map_or_else( + let path = storage.mount_path(device).map_or_else( |e| { info!("Not found: {}", e); "".to_string() @@ -220,7 +220,7 @@ fn write_storages_list( |v| v.display().to_string(), ); let parent_name = if let Storage::SubDirectory(s) = storage { - s.parent(&storages) + s.parent(storages) .context(format!("Failed to get parent of storage {}", s))? .name() } else { @@ -238,7 +238,7 @@ fn write_storages_list( )?; if long_display { let note = match storage { - Storage::PhysicalStorage(s) => s.kind(), + Storage::Physical(s) => s.kind(), Storage::SubDirectory(s) => &s.notes, Storage::Online(s) => &s.provider, }; @@ -253,11 +253,11 @@ pub(crate) fn cmd_storage_bind( new_alias: String, mount_point: PathBuf, repo: Repository, - config_dir: &PathBuf, + config_dir: &Path, ) -> Result<()> { - let device = devices::get_device(&config_dir)?; + let device = devices::get_device(config_dir)?; // get storages - let mut storages = Storages::read(&config_dir)?; + let mut storages = Storages::read(config_dir)?; let commit_comment = { // find matching storage let storage = &mut storages @@ -284,11 +284,11 @@ pub(crate) fn cmd_storage_bind( trace!("bound new system name to the storage"); trace!("storages: {:#?}", storages); - storages.write(&config_dir)?; + storages.write(config_dir)?; // commit add_and_commit( &repo, - &Path::new(storages::STORAGESFILE), + Path::new(storages::STORAGESFILE), &format!("Bound new storage name to storage ({})", commit_comment), )?; println!("Bound new storage name to storage ({})", commit_comment); diff --git a/src/devices.rs b/src/devices.rs index 6a93f7b..ab400a0 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -27,7 +27,7 @@ impl Device { pub fn new(name: String) -> Device { let sys = System::new(); Device { - name: name, + name, os_name: sys.name().unwrap_or_else(|| { warn!("Failed to get OS name. Saving as \"unknown\"."); "unknown".to_string() @@ -49,17 +49,6 @@ impl Device { } } -#[cfg(test)] -mod tests { - use super::Device; - - #[test] - fn get_name() { - let device = Device::new("test".to_string()); - assert_eq!("test".to_string(), device.name()); - } -} - /// Get devname of the device from file `devname`. fn get_devname(config_dir: &Path) -> Result { let f = File::open(config_dir.join("devname")).context("Failed to open devname file")?; @@ -80,8 +69,7 @@ pub fn get_device(config_dir: &Path) -> Result { trace!("devices: {:?}", devices); devices .into_iter() - .filter(|dev| dev.name() == devname) - .next() + .find(|dev| dev.name() == devname) .context("Couldn't find Device in devices.yml") } @@ -93,7 +81,7 @@ pub fn get_devices(config_dir: &Path) -> Result> { let reader = BufReader::new(f); let yaml: Vec = serde_yaml::from_reader(reader).context("Failed to parse devices.yml")?; - return Ok(yaml); + Ok(yaml) } /// Write `devices` to yaml file in `config_dir`. @@ -106,3 +94,14 @@ pub fn write_devices(config_dir: &Path, devices: Vec) -> Result<()> { let writer = BufWriter::new(f); serde_yaml::to_writer(writer, &devices).map_err(|e| anyhow!(e)) } + +#[cfg(test)] +mod tests { + use super::Device; + + #[test] + fn get_name() { + let device = Device::new("test".to_string()); + assert_eq!("test".to_string(), device.name()); + } +} diff --git a/src/main.rs b/src/main.rs index 4c6ff47..18e332d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,7 +156,7 @@ fn add_and_commit(repo: &Repository, path: &Path, message: &str) -> Result repo.commit( Some("HEAD"), diff --git a/src/storages.rs b/src/storages.rs index d982a3a..b67b9cf 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -27,7 +27,7 @@ pub enum StorageType { /// All storage types. #[derive(Serialize, Deserialize, Debug)] pub enum Storage { - PhysicalStorage(PhysicalDrivePartition), + Physical(PhysicalDrivePartition), SubDirectory(Directory), Online(OnlineStorage), } @@ -36,7 +36,7 @@ impl Storage { /// Full type name like "PhysicalStorage". pub fn typename(&self) -> &str { match self { - Self::PhysicalStorage(_) => "PhysicalStorage", + Self::Physical(_) => "PhysicalStorage", Self::SubDirectory(_) => "SubDirectory", Self::Online(_) => "OnlineStorage", } @@ -45,7 +45,7 @@ impl Storage { /// Short type name with one letter like "P". pub fn shorttypename(&self) -> &str { match self { - Self::PhysicalStorage(_) => "P", + Self::Physical(_) => "P", Self::SubDirectory(_) => "S", Self::Online(_) => "O", } @@ -55,7 +55,7 @@ impl Storage { impl StorageExt for Storage { fn name(&self) -> &String { match self { - Self::PhysicalStorage(s) => s.name(), + Self::Physical(s) => s.name(), Self::SubDirectory(s) => s.name(), Self::Online(s) => s.name(), } @@ -63,7 +63,7 @@ impl StorageExt for Storage { fn local_info(&self, device: &devices::Device) -> Option<&local_info::LocalInfo> { match self { - Self::PhysicalStorage(s) => s.local_info(device), + Self::Physical(s) => s.local_info(device), Self::SubDirectory(s) => s.local_info(device), Self::Online(s) => s.local_info(device), } @@ -71,9 +71,9 @@ impl StorageExt for Storage { fn mount_path(&self, device: &devices::Device) -> Result { match self { - Self::PhysicalStorage(s) => s.mount_path(&device), - Self::SubDirectory(s) => s.mount_path(&device), - Self::Online(s) => s.mount_path(&device), + Self::Physical(s) => s.mount_path(device), + Self::SubDirectory(s) => s.mount_path(device), + Self::Online(s) => s.mount_path(device), } } @@ -84,7 +84,7 @@ impl StorageExt for Storage { device: &devices::Device, ) -> Result<()> { match self { - Storage::PhysicalStorage(s) => s.bound_on_device(alias, mount_point, device), + Storage::Physical(s) => s.bound_on_device(alias, mount_point, device), Storage::SubDirectory(s) => s.bound_on_device(alias, mount_point, device), Storage::Online(s) => s.bound_on_device(alias, mount_point, device), } @@ -92,7 +92,7 @@ impl StorageExt for Storage { fn capacity(&self) -> Option { match self { - Storage::PhysicalStorage(s) => s.capacity(), + Storage::Physical(s) => s.capacity(), Storage::SubDirectory(s) => s.capacity(), Storage::Online(s) => s.capacity(), } @@ -100,7 +100,7 @@ impl StorageExt for Storage { fn parent<'a>(&'a self, storages: &'a Storages) -> Option<&'a Storage> { match self { - Storage::PhysicalStorage(s) => s.parent(storages), + Storage::Physical(s) => s.parent(storages), Storage::SubDirectory(s) => s.parent(storages), Storage::Online(s) => s.parent(storages), } @@ -110,7 +110,7 @@ impl StorageExt for Storage { impl fmt::Display for Storage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::PhysicalStorage(s) => s.fmt(f), + Self::Physical(s) => s.fmt(f), Self::SubDirectory(s) => s.fmt(f), Self::Online(s) => s.fmt(f), } diff --git a/src/storages/directory.rs b/src/storages/directory.rs index 5178c14..e78e2c9 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -52,7 +52,7 @@ impl Directory { device: &devices::Device, storages: &Storages, ) -> Result { - let (parent, diff_path) = util::min_parent_storage(&path, storages, &device) + let (parent, diff_path) = util::min_parent_storage(&path, storages, device) .context("Failed to compare diff of paths")?; trace!("Selected parent: {}", parent.name()); let local_info = LocalInfo::new(alias, path); @@ -78,9 +78,9 @@ impl Directory { /// Resolve mount path of directory with current device. fn mount_path(&self, device: &devices::Device, storages: &Storages) -> Result { let parent_mount_path = self - .parent(&storages) + .parent(storages) .context("Can't find parent storage")? - .mount_path(&device)?; + .mount_path(device)?; Ok(parent_mount_path.join(self.relative_path.clone())) } } @@ -181,7 +181,7 @@ mod test { ); let mut storages = Storages::new(); storages - .add(storages::Storage::PhysicalStorage(physical)) + .add(storages::Storage::Physical(physical)) .unwrap(); storages.add(Storage::SubDirectory(directory)).unwrap(); // assert_eq!(directory.name(), "test_name"); diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 4a110a6..b3fb531 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -5,9 +5,8 @@ use crate::devices::Device; use crate::storages::{Storage, StorageExt, Storages}; use anyhow::{anyhow, Context, Result}; use byte_unit::Byte; -use inquire::Text; use serde::{Deserialize, Serialize}; -use std::path; +use std::path::{self, Path}; use std::{collections::HashMap, fmt}; use sysinfo::{Disk, DiskExt, SystemExt}; @@ -61,7 +60,7 @@ impl PhysicalDrivePartition { let fs = std::str::from_utf8(fs)?; let local_info = LocalInfo::new(alias, disk.mount_point().to_path_buf()); Ok(PhysicalDrivePartition { - name: name, + name, kind: format!("{:?}", disk.kind()), capacity: disk.total_space(), fs: fs.to_string(), @@ -71,12 +70,8 @@ impl PhysicalDrivePartition { }) } - pub fn bind_device( - &mut self, - disk: &sysinfo::Disk, - config_dir: &std::path::PathBuf, - ) -> Result<()> { - let device = devices::get_device(&config_dir)?; + pub fn bind_device(&mut self, disk: &sysinfo::Disk, config_dir: &Path) -> Result<()> { + let device = devices::get_device(config_dir)?; let alias = match disk.name().to_str() { Some(s) => s.to_string(), None => return Err(anyhow!("Failed to convert storage name to valid str.")), @@ -101,33 +96,6 @@ impl PhysicalDrivePartition { } } -#[cfg(test)] -mod test { - use crate::{ - devices::Device, - storages::{local_info::LocalInfo, StorageExt}, - }; - use std::path::PathBuf; - - use super::PhysicalDrivePartition; - - #[test] - fn test_new() { - let localinfo = LocalInfo::new("alias".to_string(), PathBuf::from("/mnt/sample")); - let storage = PhysicalDrivePartition::new( - "name".to_string(), - "SSD".to_string(), - 100, - "ext_4".to_string(), - true, - localinfo, - &Device::new("test_device".to_string()), - ); - assert_eq!(storage.name(), "name"); - assert_eq!(storage.capacity(), Some(100)); - } -} - impl StorageExt for PhysicalDrivePartition { fn name(&self) -> &String { &self.name @@ -203,7 +171,7 @@ pub fn select_physical_storage( trace!("{:?}", disk) } let disk = select_sysinfo_disk(&sys_disks)?; - let storage = PhysicalDrivePartition::try_from_sysinfo_disk(&disk, disk_name, device)?; + let storage = PhysicalDrivePartition::try_from_sysinfo_disk(disk, disk_name, device)?; Ok(storage) } @@ -213,10 +181,7 @@ fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> { .iter() .enumerate() .map(|(i, disk)| { - let name = match disk.name().to_str() { - Some(s) => s, - None => "", - }; + let name = disk.name().to_str().unwrap_or(""); let fs: &str = std::str::from_utf8(disk.file_system()).unwrap_or("unknown"); let kind = format!("{:?}", disk.kind()); let mount_path = disk.mount_point(); @@ -246,3 +211,30 @@ fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> { trace!("selected disk: {:?}", disk); Ok(disk) } + +#[cfg(test)] +mod test { + use crate::{ + devices::Device, + storages::{local_info::LocalInfo, StorageExt}, + }; + use std::path::PathBuf; + + use super::PhysicalDrivePartition; + + #[test] + fn test_new() { + let localinfo = LocalInfo::new("alias".to_string(), PathBuf::from("/mnt/sample")); + let storage = PhysicalDrivePartition::new( + "name".to_string(), + "SSD".to_string(), + 100, + "ext_4".to_string(), + true, + localinfo, + &Device::new("test_device".to_string()), + ); + assert_eq!(storage.name(), "name"); + assert_eq!(storage.capacity(), Some(100)); + } +} diff --git a/src/util.rs b/src/util.rs index 90ead30..36c6714 100644 --- a/src/util.rs +++ b/src/util.rs @@ -21,7 +21,7 @@ pub fn min_parent_storage<'a>( Ok(path) => path, Err(_) => return None, }; - let diff = pathdiff::diff_paths(&path, storage_path)?; + let diff = pathdiff::diff_paths(path, storage_path)?; if diff.components().any(|c| c == path::Component::ParentDir) { None } else { @@ -115,14 +115,12 @@ mod test { .unwrap() .eq(&PathBuf::from("/aaa/bbb/ccc"))); let expanded = expand_tilde(PathBuf::from("~/aaa/bbb/ccc")); - match expanded { - Ok(path) => assert!(path.eq(&dirs::home_dir().unwrap().join("aaa/bbb/ccc"))), - Err(_) => (), + if let Ok(path) = expanded { + assert!(path.eq(&dirs::home_dir().unwrap().join("aaa/bbb/ccc"))) } let expanded = expand_tilde(PathBuf::from("aaa/~/bbb")); - match expanded { - Ok(path) => assert_eq!(path, PathBuf::from("aaa/~/bbb")), - Err(_) => (), + if let Ok(path) = expanded { + assert_eq!(path, PathBuf::from("aaa/~/bbb")) } Ok(()) } diff --git a/tests/cli.rs b/tests/cli.rs index ca0c3cd..23bad22 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -41,7 +41,7 @@ mod cmd_init { let repo_1 = Repository::open(&config_dir_1)?; let upstream_name = "remote"; let mut repo_1_remote = - repo_1.remote(upstream_name, &bare_repo_dir.path().to_str().unwrap())?; + repo_1.remote(upstream_name, bare_repo_dir.path().to_str().unwrap())?; repo_1_remote.push(&["refs/heads/main"], None)?; trace!("bare repo {:?}", bare_repo_dir.display()); println!("{:?}", bare_repo_dir.read_dir()?); @@ -112,7 +112,7 @@ mod cmd_init { let repo_1 = Repository::open(&config_dir_1)?; let upstream_name = "remote"; let mut repo_1_remote = - repo_1.remote(upstream_name, &bare_repo_dir.path().to_str().unwrap())?; + repo_1.remote(upstream_name, bare_repo_dir.path().to_str().unwrap())?; repo_1_remote.push(&["refs/heads/main"], None)?; trace!("bare repo {:?}", bare_repo_dir.display()); println!("{:?}", bare_repo_dir.read_dir()?); @@ -182,9 +182,7 @@ mod cmd_init { .stdout(predicate::str::contains("")); // Add storage (directory) let sample_directory = &sample_storage.join("foo").join("bar"); - DirBuilder::new() - .recursive(true) - .create(&sample_directory)?; + DirBuilder::new().recursive(true).create(sample_directory)?; Command::cargo_bin("xdbm")? .arg("-c") .arg(config_dir_1.path()) @@ -194,7 +192,7 @@ mod cmd_init { .arg("--alias") .arg("docs") .arg("gdrive_docs") - .arg(&sample_directory) + .arg(sample_directory) .assert() .success() .stdout(predicate::str::contains("")); @@ -222,7 +220,7 @@ mod cmd_init { .arg("--alias") .arg("gdocs") .arg("--path") - .arg(&sample_directory) + .arg(sample_directory) .arg("gdrive_docs") .assert() .success() @@ -232,7 +230,7 @@ mod cmd_init { let sample_storage_2 = assert_fs::TempDir::new()?; Command::cargo_bin("xdbm")? .arg("-c") - .arg(&config_dir_2.path()) + .arg(config_dir_2.path()) .arg("storage") .arg("add") .arg("online") @@ -243,13 +241,13 @@ mod cmd_init { .arg("--alias") .arg("nas") .arg("nas") - .arg(&sample_storage_2.path()) + .arg(sample_storage_2.path()) .assert() .success(); Command::cargo_bin("xdbm")? .arg("-c") - .arg(&config_dir_2.path()) + .arg(config_dir_2.path()) .arg("storage") .arg("list") .arg("-l") @@ -257,18 +255,18 @@ mod cmd_init { .success(); // backup add let backup_src = &sample_storage_2.join("foo").join("bar"); - DirBuilder::new().recursive(true).create(&backup_src)?; + DirBuilder::new().recursive(true).create(backup_src)?; let backup_dest = &sample_directory.join("docs"); - DirBuilder::new().recursive(true).create(&backup_dest)?; + DirBuilder::new().recursive(true).create(backup_dest)?; Command::cargo_bin("xdbm")? .arg("-c") - .arg(&config_dir_2.path()) + .arg(config_dir_2.path()) .arg("backup") .arg("add") .arg("--src") - .arg(&backup_src) + .arg(backup_src) .arg("--dest") - .arg(&backup_dest) + .arg(backup_dest) .arg("foodoc") .arg("external") .arg("rsync") @@ -278,13 +276,13 @@ mod cmd_init { Command::cargo_bin("xdbm")? .arg("-c") - .arg(&config_dir_2.path()) + .arg(config_dir_2.path()) .arg("backup") .arg("add") .arg("--src") - .arg(&backup_src) + .arg(backup_src) .arg("--dest") - .arg(&backup_dest) + .arg(backup_dest) .arg("foodoc") .arg("external") .arg("rsync")