diff --git a/src/main.rs b/src/main.rs index e1e73bd..681b326 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,10 +68,13 @@ struct StorageArgs { #[derive(Subcommand)] enum StorageCommands { + /// Add new storage. Add { #[arg(value_enum)] storage_type: StorageType, }, + /// List all storages. + List {}, } mod devices; @@ -175,25 +178,7 @@ fn main() -> Result<()> { match storage_type { StorageType::Physical => { // Get storages - let mut storages: Vec = if let Some(storages_file) = - fs::read_dir(&config_dir)? - .filter(|f| { - f.as_ref().map_or_else( - |_e| false, - |f| { - let storagesfile: OsString = STORAGESFILE.into(); - f.path().file_name() == Some(&storagesfile) - }, - ) - }) - .next() - { - trace!("{} found: {:?}", STORAGESFILE, storages_file); - get_storages(&config_dir)? - } else { - trace!("No {} found", STORAGESFILE); - vec![] - }; + let mut storages: Vec = get_storages(&config_dir)?; trace!("found storages: {:?}", storages); // select storage @@ -221,6 +206,14 @@ fn main() -> Result<()> { } } } + StorageCommands::List {} => { + // Get storages + let storages: Vec = get_storages(&config_dir)?; + trace!("found storages: {:?}", storages); + for storage in storages { + println!("{}", storage); + } + } }, Commands::Path {} => { println!("{}", &config_dir.display()); @@ -375,17 +368,31 @@ fn select_physical_storage( PhysicalDrivePartition::try_from_sysinfo_disk(disk, disk_name, device) } -/// Get `Vec` from devices.yml([DEVICESFILE]) +/// Get `Vec` from devices.yml([DEVICESFILE]). +/// If [DEVICESFILE] isn't found, return empty vec. fn get_storages(config_dir: &Path) -> Result> { - let f = File::open(config_dir.join(STORAGESFILE))?; - let reader = BufReader::new(f); - // for line in reader.lines() { - // trace!("{:?}", line); - // } - // unimplemented!(); - let yaml: Vec = - serde_yaml::from_reader(reader).context("Failed to read devices.yml")?; - Ok(yaml) + if let Some(storages_file) = fs::read_dir(&config_dir)? + .filter(|f| { + f.as_ref().map_or_else( + |_e| false, + |f| { + let storagesfile: OsString = STORAGESFILE.into(); + f.path().file_name() == Some(&storagesfile) + }, + ) + }) + .next() + { + trace!("{} found: {:?}", STORAGESFILE, storages_file); + let f = File::open(config_dir.join(STORAGESFILE))?; + let reader = BufReader::new(f); + let yaml: Vec = + serde_yaml::from_reader(reader).context("Failed to read devices.yml")?; + Ok(yaml) + } else { + trace!("No {} found", STORAGESFILE); + Ok(vec![]) + } } /// Write `storages` to yaml file in `config_dir`. diff --git a/src/storages.rs b/src/storages.rs index a3b253e..23fcff3 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -3,6 +3,7 @@ use clap::ValueEnum; use physical_drive_partition::PhysicalDrivePartition; use serde::{Deserialize, Serialize}; +use std::fmt; /// YAML file to store known storages.. pub const STORAGESFILE: &str = "storages.yml"; @@ -33,6 +34,14 @@ impl Storage { } } +impl fmt::Display for Storage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::PhysicalStorage(s) => s.fmt(f), + } + } +} + /// Trait to manipulate all `Storage`s (Enums). pub trait StorageExt { fn name(&self) -> &String; diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 30e38d7..a2e1c88 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -3,8 +3,12 @@ use crate::devices::Device; use crate::storages::StorageExt; use anyhow::{Context, Result}; +use byte_unit::Byte; use serde::{Deserialize, Serialize}; -use std::collections::{hash_map::RandomState, HashMap}; +use std::{ + collections::{hash_map::RandomState, HashMap}, + fmt, +}; use sysinfo::DiskExt; /// Partitoin of physical (on-premises) drive. @@ -73,3 +77,19 @@ impl StorageExt for PhysicalDrivePartition { &self.name } } + +impl fmt::Display for PhysicalDrivePartition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let removable_indicator = if self.is_removable { "+" } else { "-" }; + write!( + f, + "{name:<10} {size} {removable:<1} {kind:<6} {fs:<5}", + name = self.name(), + size = Byte::from_bytes(self.capacity.into()).get_appropriate_unit(true), + removable = removable_indicator, + kind = self.kind, + fs = self.fs, + // path = self. TODO: display path or contain it in struct + ) + } +}