From b54cbf00f0a921f05ce5aafe4b8d8aab76c8eb75 Mon Sep 17 00:00:00 2001 From: qwjyh Date: Wed, 6 Dec 2023 11:18:46 +0900 Subject: [PATCH] online storage & fix directory parent find & and so on --- src/main.rs | 11 ++--- src/storages.rs | 30 ++++++------ src/storages/directory.rs | 26 ++++++---- src/storages/online_storage.rs | 61 ++++++++++++++++++++++++ src/storages/physical_drive_partition.rs | 7 +-- 5 files changed, 99 insertions(+), 36 deletions(-) create mode 100644 src/storages/online_storage.rs diff --git a/src/main.rs b/src/main.rs index 6be4517..b868d2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,16 +12,13 @@ extern crate log; extern crate dirs; use anyhow::{anyhow, Context, Result}; -use byte_unit::Byte; use clap::error::ErrorKind; use clap::{CommandFactory, Parser, Subcommand}; use clap_verbosity_flag::Verbosity; use git2::{Commit, Oid, Repository}; use inquire::{validator::Validation, Text}; -use serde::{Deserialize, Serialize}; use serde_yaml; use std::collections::HashMap; -use std::fmt::format; use std::path::PathBuf; use std::{env, io::BufReader, path::Path}; use std::{ @@ -33,8 +30,8 @@ use std::{fs, io::prelude::*}; use sysinfo::{Disk, DiskExt, SystemExt}; use crate::storages::{ - directory::Directory, get_storages, local_info, physical_drive_partition::*, write_storages, - Storage, StorageExt, StorageType, STORAGESFILE, + directory::Directory, get_storages, local_info, online_storage, physical_drive_partition::*, + write_storages, Storage, StorageExt, StorageType, STORAGESFILE, }; use devices::{Device, DEVICESFILE, *}; @@ -81,6 +78,7 @@ enum StorageCommands { #[arg(value_enum)] storage_type: StorageType, + // TODO: set this require and select matching disk for physical #[arg(short, long, value_name = "PATH")] path: Option, }, @@ -235,6 +233,7 @@ fn main() -> Result<()> { )?; (key_name, Storage::SubDirectory(storage)) } + StorageType::Online => todo!(), }; // add to storages @@ -283,7 +282,7 @@ fn main() -> Result<()> { .to_str() .context("Failed to convert disk name to valid string")?; // add to storages - storage.add_alias(disk, &config_dir)?; + storage.bind_device(disk, &config_dir)?; trace!("storage: {}", storage); format!("{} to {}", system_name, storage.name()) }; diff --git a/src/storages.rs b/src/storages.rs index 67faf22..ff24e34 100644 --- a/src/storages.rs +++ b/src/storages.rs @@ -1,8 +1,9 @@ //! Manipulates storages. -use crate::storages::physical_drive_partition::PhysicalDrivePartition; -use crate::storages::directory::Directory; use crate::devices; +use crate::storages::directory::Directory; +use crate::storages::online_storage::OnlineStorage; +use crate::storages::physical_drive_partition::PhysicalDrivePartition; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; use serde::{Deserialize, Serialize}; @@ -15,7 +16,7 @@ pub const STORAGESFILE: &str = "storages.yml"; pub enum StorageType { Physical, SubDirectory, - // Online, + Online, } /// All storage types. @@ -23,24 +24,20 @@ pub enum StorageType { pub enum Storage { PhysicalStorage(PhysicalDrivePartition), SubDirectory(Directory), - // /// Online storage provided by others. - // OnlineStorage { - // name: String, - // provider: String, - // capacity: u8, - // }, + Online(OnlineStorage), } impl Storage { /// Add or update alias of `disk` for current device. - pub fn add_alias( + pub fn bind_device( &mut self, disk: &sysinfo::Disk, config_dir: &std::path::PathBuf, ) -> anyhow::Result<()> { match self { - Self::PhysicalStorage(s) => s.add_alias(disk, config_dir), + Self::PhysicalStorage(s) => s.bind_device(disk, config_dir), Self::SubDirectory(_) => Err(anyhow!("SubDirectory doesn't have system alias.")), + Self::Online(_) => todo!(), } } } @@ -50,16 +47,15 @@ impl StorageExt for Storage { match self { Self::PhysicalStorage(s) => s.name(), Self::SubDirectory(s) => s.name(), + Self::Online(s) => s.name(), } } - fn has_alias( - &self, - device: &devices::Device, - ) -> bool { + fn has_alias(&self, device: &devices::Device) -> bool { match self { Self::PhysicalStorage(s) => s.has_alias(&device), Self::SubDirectory(s) => s.has_alias(&device), + Self::Online(s) => s.has_alias(&device), } } @@ -71,6 +67,7 @@ impl StorageExt for Storage { match self { Self::PhysicalStorage(s) => s.mount_path(&device, &storages), Self::SubDirectory(s) => s.mount_path(&device, &storages), + Self::Online(s) => s.mount_path(&device, &storages), } } } @@ -80,6 +77,7 @@ impl fmt::Display for Storage { match self { Self::PhysicalStorage(s) => s.fmt(f), Self::SubDirectory(s) => s.fmt(f), + Self::Online(s) => s.fmt(f), } } } @@ -88,6 +86,7 @@ impl fmt::Display for Storage { pub trait StorageExt { fn name(&self) -> &String; fn has_alias(&self, device: &devices::Device) -> bool; + /// Get mount path of `self` on `device`. fn mount_path( &self, device: &devices::Device, @@ -97,6 +96,7 @@ pub trait StorageExt { pub mod directory; pub mod local_info; +pub mod online_storage; pub mod physical_drive_partition; /// Get `Vec` from devices.yml([DEVICESFILE]). diff --git a/src/storages/directory.rs b/src/storages/directory.rs index 290c231..5367ea9 100644 --- a/src/storages/directory.rs +++ b/src/storages/directory.rs @@ -2,13 +2,7 @@ use anyhow::{anyhow, Context, Result}; use serde::{Deserialize, Serialize}; -use std::{ - collections::HashMap, - fmt::{self, write}, - hash::Hash, - path, - rc::Rc, -}; +use std::{collections::HashMap, fmt, path}; use crate::devices; @@ -31,7 +25,7 @@ impl Directory { /// - `notes`: supplimental notes. fn new( name: String, - parent: String, // todo implement serialize + parent: String, relative_path: path::PathBuf, notes: String, local_info: HashMap, @@ -58,7 +52,11 @@ impl Directory { .filter_map(|(k, v)| { let diff = pathdiff::diff_paths(&path, v.mount_path(&device, &storages).unwrap())?; trace!("Pathdiff: {:?}", diff); - Some((k, diff)) + if diff.components().any(|c| c == path::Component::ParentDir) { + None + } else { + Some((k, diff)) + } }) .min_by_key(|(_k, v)| { let diff_paths: Vec> = v.components().collect(); @@ -106,6 +104,16 @@ impl Directory { let parent_mount_path = parent.mount_path(&device, &storages)?; Ok(parent_mount_path.join(self.relative_path.clone())) } + + fn bind_device(&mut self, alias: String, device: &devices::Device, storages: &HashMap) -> Result<()> { + let mount_path = self.mount_path(&device, &storages)?; + let new_local_info = LocalInfo::new(alias, mount_path); + match self.local_info.insert(device.name(), new_local_info) { + Some(v) => println!("Value updated. old val is: {:?}", v), + None => println!("inserted new val"), + }; + Ok(()) + } } impl StorageExt for Directory { diff --git a/src/storages/online_storage.rs b/src/storages/online_storage.rs new file mode 100644 index 0000000..06e9abe --- /dev/null +++ b/src/storages/online_storage.rs @@ -0,0 +1,61 @@ +//! Online storage which is not a children of any physical drive. + +use anyhow::Context; +use byte_unit::Byte; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::fmt; +use std::path; + +use crate::devices; + +use super::local_info::LocalInfo; +use super::StorageExt; + +#[derive(Serialize, Deserialize, Debug)] +pub struct OnlineStorage { + name: String, + provider: String, + capacity: u8, + local_info: HashMap, +} + +impl OnlineStorage { + fn new(name: String, provider: String, capacity: u8, path: path::PathBuf, device: &devices::Device) -> OnlineStorage { + todo!() + } +} + +impl StorageExt for OnlineStorage { + fn name(&self) -> &String { + &self.name + } + + fn has_alias(&self, device: &devices::Device) -> bool { + self.local_info.get(&device.name()).is_some() + } + + fn mount_path( + &self, + device: &devices::Device, + _storages: &HashMap, + ) -> anyhow::Result { + Ok(self + .local_info + .get(&device.name()) + .context(format!("LocalInfo for storage: {} not found", &self.name()))? + .mount_path()) + } +} + +impl fmt::Display for OnlineStorage { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "O {name:<10} {size} {provider:<10}", + name = self.name(), + size = Byte::from_bytes(self.capacity.into()).get_appropriate_unit(true), + provider = self.provider, + ) + } +} diff --git a/src/storages/physical_drive_partition.rs b/src/storages/physical_drive_partition.rs index 8f25c62..7c8d4fb 100644 --- a/src/storages/physical_drive_partition.rs +++ b/src/storages/physical_drive_partition.rs @@ -28,11 +28,6 @@ pub struct PhysicalDrivePartition { local_info: HashMap, } -pub struct PhysicalDrivePartitionLocal { - alias: String, - mount_path: path::PathBuf, -} - impl PhysicalDrivePartition { /// Try to get Physical drive info from sysinfo. pub fn try_from_sysinfo_disk( @@ -60,7 +55,7 @@ impl PhysicalDrivePartition { }) } - pub fn add_alias( + pub fn bind_device( &mut self, disk: &sysinfo::Disk, config_dir: &std::path::PathBuf,