diff --git a/src/main.rs b/src/main.rs index 681b326..55ea60e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ use std::{ fs::{File, OpenOptions}, }; use std::{fs, io::prelude::*}; -use sysinfo::{DiskExt, SystemExt}; +use sysinfo::{Disk, DiskExt, SystemExt}; use devices::{Device, DEVICESFILE}; use storages::{physical_drive_partition::*, Storage, StorageExt, StorageType, STORAGESFILE}; @@ -75,6 +75,8 @@ enum StorageCommands { }, /// List all storages. List {}, + /// Add new device-specific name to existing storage. + Bind { storage: String }, } mod devices; @@ -89,7 +91,8 @@ fn main() -> Result<()> { .init(); trace!("Start logging..."); - let mut config_dir = dirs::config_local_dir().context("Failed to get config dir.")?; + let mut config_dir: std::path::PathBuf = + dirs::config_local_dir().context("Failed to get config dir.")?; config_dir.push("xdbm"); trace!("Config dir: {:?}", config_dir); @@ -214,6 +217,28 @@ fn main() -> Result<()> { println!("{}", storage); } } + StorageCommands::Bind { + storage: storage_name, + } => { + // get storages + let mut storages: Vec = get_storages(&config_dir)?; + { + // find matching storage + let storage = &mut storages + .iter_mut() + .find(|s| s.name() == &storage_name) + .context(format!("No storage has name {}", storage_name))?; + // get disk from sysinfo + let mut sysinfo = sysinfo::System::new_all(); + sysinfo.refresh_disks(); + let disk = select_sysinfo_disk(&sysinfo)?; + // add to storages + storage.add_alias(disk, &config_dir)?; + trace!("storage: {}", storage); + } + trace!("bound new system name to the storage"); + trace!("storages: {:#?}", storages); + } }, Commands::Path {} => { println!("{}", &config_dir.display()); @@ -317,7 +342,23 @@ fn select_physical_storage( for disk in sys_disks.disks() { trace!("{:?}", disk) } - let available_disks = sys_disks + let disk = select_sysinfo_disk(&sys_disks)?; + // name the disk + let mut disk_name = String::new(); + trace!("{}", disk_name); + loop { + disk_name = Text::new("Name for the disk:").prompt()?; + if storages.iter().all(|s| s.name() != &disk_name) { + break; + } + println!("The name {} is already used.", disk_name); + } + trace!("selected name: {}", disk_name); + PhysicalDrivePartition::try_from_sysinfo_disk(&disk, disk_name, device) +} + +fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> { + let available_disks = sysinfo .disks() .iter() .enumerate() @@ -347,25 +388,13 @@ fn select_physical_storage( let disk = inquire::Select::new("Select drive:", available_disks).prompt()?; let disk_num: usize = disk.split(':').next().unwrap().parse().unwrap(); trace!("disk_num: {}", disk_num); - let (_, disk) = sys_disks + let disk = sysinfo .disks() .iter() - .enumerate() - .find(|(i, _)| i == &disk_num) - .unwrap(); + .nth(disk_num) + .context("no disk matched with selected one.")?; trace!("selected disk: {:?}", disk); - // name the disk - let mut disk_name = String::new(); - trace!("{}", disk_name); - loop { - disk_name = Text::new("Name for the disk:").prompt()?; - if storages.iter().all(|s| s.name() != &disk_name) { - break; - } - println!("The name {} is already used.", disk_name); - } - trace!("selected name: {}", disk_name); - PhysicalDrivePartition::try_from_sysinfo_disk(disk, disk_name, device) + Ok(disk) } /// Get `Vec` from devices.yml([DEVICESFILE]). diff --git a/src/storages.rs b/src/storages.rs index 23fcff3..712d5eb 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -27,11 +27,20 @@ pub enum Storage { } impl Storage { - pub fn name(&self) -> &String { + pub fn add_alias(&mut self, disk: &sysinfo::Disk, config_dir: &std::path::PathBuf) -> anyhow::Result<()> { + match self { + Self::PhysicalStorage(s) => s.add_alias(disk, config_dir), + } + } +} + +impl StorageExt for Storage { + fn name(&self) -> &String { match self { Self::PhysicalStorage(s) => s.name(), } } + } impl fmt::Display for Storage { diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index a2e1c88..2a95455 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -1,8 +1,8 @@ //! Manipulate partition of physical drive (both removable and unremovable). -use crate::devices::Device; +use crate::{devices::Device, get_device}; use crate::storages::StorageExt; -use anyhow::{Context, Result}; +use anyhow::{anyhow, Context, Result}; use byte_unit::Byte; use serde::{Deserialize, Serialize}; use std::{ @@ -47,28 +47,25 @@ impl PhysicalDrivePartition { }) } - fn add_alias( - self, - disk: sysinfo::Disk, - device: Device, - ) -> Result { + pub fn add_alias( + &mut self, + disk: &sysinfo::Disk, + config_dir: &std::path::PathBuf + ) -> Result<()> { + let device = get_device(&config_dir)?; let alias = match disk.name().to_str() { Some(s) => s.to_string(), - None => return Err("Failed to convert storage name to valid str.".to_string()), + None => return Err(anyhow!("Failed to convert storage name to valid str.")), }; - let mut aliases = self.system_names; - let _ = match aliases.insert(device.name(), alias) { - Some(v) => v, - None => return Err("Failed to insert alias".to_string()), + let aliases = &mut self.system_names; + trace!("aliases: {:?}", aliases); + match aliases.insert(device.name(), alias) { + Some(v) => trace!("old val is: {}", v), + None => trace!("inserted new val"), }; - Ok(PhysicalDrivePartition { - name: self.name, - kind: self.kind, - capacity: self.capacity, - fs: self.fs, - is_removable: self.is_removable, - system_names: aliases, - }) + trace!("aliases: {:?}", aliases); + // self.system_names = aliases; + Ok(()) } } @@ -76,6 +73,7 @@ impl StorageExt for PhysicalDrivePartition { fn name(&self) -> &String { &self.name } + } impl fmt::Display for PhysicalDrivePartition {