diff options
Diffstat (limited to 'crates/vcs')
| -rw-r--r-- | crates/vcs/src/constants.rs | 10 | ||||
| -rw-r--r-- | crates/vcs/src/workspace/vault.rs | 6 | ||||
| -rw-r--r-- | crates/vcs/src/workspace/vault/virtual_file.rs | 80 | ||||
| -rw-r--r-- | crates/vcs/vcs_test/src/test_vault_setup_and_member_register.rs | 6 | ||||
| -rw-r--r-- | crates/vcs/vcs_test/src/test_virtual_file_creation_and_update.rs | 14 |
5 files changed, 80 insertions, 36 deletions
diff --git a/crates/vcs/src/constants.rs b/crates/vcs/src/constants.rs index eb7b019..a55aef5 100644 --- a/crates/vcs/src/constants.rs +++ b/crates/vcs/src/constants.rs @@ -22,11 +22,11 @@ pub const SERVER_FILE_MEMBER_INFO: &str = "./members/{member_id}.toml"; // crate pub const SERVER_FILE_MEMBER_PUB: &str = "./key/{member_id}.pem"; // crates::utils::tcp_connection::instance // Server - Virtual File Storage -pub const SERVER_PATH_VIRTUAL_FILE_TEMP: &str = "./.temp/{temp_name}"; -pub const SERVER_PATH_VIRTUAL_FILE_ROOT: &str = "./storage/"; -pub const SERVER_PATH_VIRTUAL_FILE_STORAGE: &str = "./storage/{vf_id}/"; -pub const SERVER_FILE_VIRTUAL_FILE_VERSION_INSTANCE: &str = "./storage/{vf_id}/{vf_version}.rf"; -pub const SERVER_FILE_VIRTUAL_FILE_META: &str = "./storage/{vf_id}/meta.yaml"; +pub const SERVER_PATH_VF_TEMP: &str = "./.temp/{temp_name}"; +pub const SERVER_PATH_VF_ROOT: &str = "./storage/"; +pub const SERVER_PATH_VF_STORAGE: &str = "./storage/{vf_index}/{vf_id}/"; +pub const SERVER_FILE_VF_VERSION_INSTANCE: &str = "./storage/{vf_index}/{vf_id}/{vf_version}.rf"; +pub const SERVER_FILE_VF_META: &str = "./storage/{vf_index}/{vf_id}/meta.yaml"; pub const SERVER_FILE_README: &str = "./README.md"; diff --git a/crates/vcs/src/workspace/vault.rs b/crates/vcs/src/workspace/vault.rs index caac662..912c6e2 100644 --- a/crates/vcs/src/workspace/vault.rs +++ b/crates/vcs/src/workspace/vault.rs @@ -9,7 +9,7 @@ use cfg_file::config::ConfigFile; use crate::{ constants::{ SERVER_FILE_README, SERVER_FILE_VAULT, SERVER_PATH_MEMBER_PUB, SERVER_PATH_MEMBERS, - SERVER_PATH_SHEETS, SERVER_PATH_VIRTUAL_FILE_ROOT, + SERVER_PATH_SHEETS, SERVER_PATH_VF_ROOT, }, current::{current_vault_path, find_vault_path}, workspace::vault::config::VaultConfig, @@ -74,7 +74,7 @@ impl Vault { create_dir_all(vault_path.join(SERVER_PATH_MEMBERS))?; // 5. Setup storage directory - create_dir_all(vault_path.join(SERVER_PATH_VIRTUAL_FILE_ROOT))?; + create_dir_all(vault_path.join(SERVER_PATH_VF_ROOT))?; // Final, generate README.md let readme_content = format!( @@ -120,7 +120,7 @@ Please report any issues or questions on the GitHub issue tracker. ## Thanks :) Thank you for using `JustEnoughVCS!` ", - SERVER_PATH_MEMBER_PUB, SERVER_PATH_VIRTUAL_FILE_ROOT + SERVER_PATH_MEMBER_PUB, SERVER_PATH_VF_ROOT ) .trim() .to_string(); diff --git a/crates/vcs/src/workspace/vault/virtual_file.rs b/crates/vcs/src/workspace/vault/virtual_file.rs index 321f0e1..8fadb9b 100644 --- a/crates/vcs/src/workspace/vault/virtual_file.rs +++ b/crates/vcs/src/workspace/vault/virtual_file.rs @@ -13,9 +13,8 @@ use uuid::Uuid; use crate::{ constants::{ - SERVER_FILE_VIRTUAL_FILE_META, SERVER_FILE_VIRTUAL_FILE_VERSION_INSTANCE, - SERVER_PATH_VIRTUAL_FILE_ROOT, SERVER_PATH_VIRTUAL_FILE_STORAGE, - SERVER_PATH_VIRTUAL_FILE_TEMP, + SERVER_FILE_VF_META, SERVER_FILE_VF_VERSION_INSTANCE, SERVER_PATH_VF_ROOT, + SERVER_PATH_VF_STORAGE, SERVER_PATH_VF_TEMP, }, workspace::vault::{MemberId, Vault}, }; @@ -23,7 +22,9 @@ use crate::{ pub type VirtualFileId = String; pub type VirtualFileVersion = String; +const VF_PREFIX: &str = "vf_"; const ID_PARAM: &str = "{vf_id}"; +const ID_INDEX: &str = "{vf_index}"; const VERSION_PARAM: &str = "{vf_version}"; const TEMP_NAME: &str = "{temp_name}"; @@ -74,18 +75,58 @@ impl Vault { pub fn virtual_file_temp_path(&self) -> PathBuf { let random_receive_name = format!("{}", uuid::Uuid::new_v4()); self.vault_path - .join(SERVER_PATH_VIRTUAL_FILE_TEMP.replace(TEMP_NAME, &random_receive_name)) + .join(SERVER_PATH_VF_TEMP.replace(TEMP_NAME, &random_receive_name)) } /// Get the directory where virtual files are stored pub fn virtual_file_storage_dir(&self) -> PathBuf { - self.vault_path().join(SERVER_PATH_VIRTUAL_FILE_ROOT) + self.vault_path().join(SERVER_PATH_VF_ROOT) } /// Get the directory where a specific virtual file is stored - pub fn virtual_file_dir(&self, id: VirtualFileId) -> PathBuf { - self.vault_path() - .join(SERVER_PATH_VIRTUAL_FILE_STORAGE.replace(ID_PARAM, &id.to_string())) + pub fn virtual_file_dir(&self, id: &VirtualFileId) -> Result<PathBuf, std::io::Error> { + Ok(self.vault_path().join( + SERVER_PATH_VF_STORAGE + .replace(ID_PARAM, &id.to_string()) + .replace(ID_INDEX, &Self::vf_index(id)?), + )) + } + + // Generate index path of virtual file + fn vf_index(id: &VirtualFileId) -> Result<String, std::io::Error> { + // Remove VF_PREFIX if present + let id_str = if id.starts_with(VF_PREFIX) { + &id[VF_PREFIX.len()..] + } else { + id + }; + + // Extract the first part before the first hyphen + let first_part = id_str.split('-').next().ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "Invalid virtual file ID format: no hyphen found", + ) + })?; + + // Ensure the first part has exactly 8 characters + if first_part.len() != 8 { + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "Invalid virtual file ID format: first part must be 8 characters", + ))?; + } + + // Split into 2-character chunks and join with path separator + let mut path = String::new(); + for i in (0..first_part.len()).step_by(2) { + if i > 0 { + path.push('/'); + } + path.push_str(&first_part[i..i + 2]); + } + + Ok(path) } /// Get the directory where a specific virtual file's metadata is stored @@ -95,28 +136,31 @@ impl Vault { version: &VirtualFileVersion, ) -> PathBuf { self.vault_path().join( - SERVER_FILE_VIRTUAL_FILE_VERSION_INSTANCE + SERVER_FILE_VF_VERSION_INSTANCE .replace(ID_PARAM, &id.to_string()) - .replace(VERSION_PARAM, &version.to_string()), + .replace(ID_INDEX, &version.to_string()), ) } /// Get the directory where a specific virtual file's metadata is stored pub fn virtual_file_meta_path(&self, id: &VirtualFileId) -> PathBuf { self.vault_path() - .join(SERVER_FILE_VIRTUAL_FILE_META.replace(ID_PARAM, &id.to_string())) + .join(SERVER_FILE_VF_META.replace(ID_PARAM, &id.to_string())) } /// Get the virtual file with the given ID - pub fn virtual_file(&self, id: &VirtualFileId) -> Option<VirtualFile<'_>> { - let dir = self.virtual_file_dir(id.clone()); - if dir.exists() { - Some(VirtualFile { + pub fn virtual_file(&self, id: &VirtualFileId) -> Result<VirtualFile<'_>, std::io::Error> { + let dir = self.virtual_file_dir(id); + if dir?.exists() { + Ok(VirtualFile { id: id.clone(), current_vault: self, }) } else { - None + Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + "Cannot found virtual file!", + )) } } @@ -157,7 +201,7 @@ impl Vault { ) -> Result<VirtualFileId, std::io::Error> { const FIRST_VERSION: &str = "0"; let receive_path = self.virtual_file_temp_path(); - let new_id = format!("vf_{}", Uuid::new_v4()); + let new_id = format!("{}{}", VF_PREFIX, Uuid::new_v4()); let move_path = self.virtual_file_real_path(&new_id, &FIRST_VERSION.to_string()); match instance.read_file(receive_path.clone()).await { @@ -296,7 +340,7 @@ impl Vault { .await?; // Ensure virtual file exist - let Some(_) = self.virtual_file(virtual_file_id) else { + let Ok(_) = self.virtual_file(virtual_file_id) else { return Err(Error::new( ErrorKind::NotFound, format!("Virtual file `{}` not found!", virtual_file_id), diff --git a/crates/vcs/vcs_test/src/test_vault_setup_and_member_register.rs b/crates/vcs/vcs_test/src/test_vault_setup_and_member_register.rs index e84a411..85b473b 100644 --- a/crates/vcs/vcs_test/src/test_vault_setup_and_member_register.rs +++ b/crates/vcs/vcs_test/src/test_vault_setup_and_member_register.rs @@ -1,10 +1,10 @@ use std::io::Error; use cfg_file::config::ConfigFile; -use env::{ +use vcs::{ constants::{ SERVER_FILE_MEMBER_INFO, SERVER_FILE_README, SERVER_FILE_VAULT, SERVER_PATH_MEMBER_PUB, - SERVER_PATH_MEMBERS, SERVER_PATH_SHEETS, SERVER_PATH_VIRTUAL_FILE_ROOT, + SERVER_PATH_MEMBERS, SERVER_PATH_SHEETS, SERVER_PATH_VF_ROOT, }, workspace::{ member::Member, @@ -32,7 +32,7 @@ async fn test_vault_setup_and_member_register() -> Result<(), std::io::Error> { assert!(dir.join(SERVER_PATH_SHEETS).exists()); assert!(dir.join(SERVER_PATH_MEMBERS).exists()); assert!(dir.join(SERVER_PATH_MEMBER_PUB).exists()); - assert!(dir.join(SERVER_PATH_VIRTUAL_FILE_ROOT).exists()); + assert!(dir.join(SERVER_PATH_VF_ROOT).exists()); // Get vault let config = VaultConfig::read_from(dir.join(SERVER_FILE_VAULT)).await?; diff --git a/crates/vcs/vcs_test/src/test_virtual_file_creation_and_update.rs b/crates/vcs/vcs_test/src/test_virtual_file_creation_and_update.rs index 7da2bef..d2a2e44 100644 --- a/crates/vcs/vcs_test/src/test_virtual_file_creation_and_update.rs +++ b/crates/vcs/vcs_test/src/test_virtual_file_creation_and_update.rs @@ -1,13 +1,6 @@ use std::time::Duration; use cfg_file::config::ConfigFile; -use env::{ - constants::SERVER_FILE_VAULT, - workspace::{ - member::Member, - vault::{Vault, config::VaultConfig, virtual_file::VirtualFileVersionDescription}, - }, -}; use tcp_connection::{ handle::{ClientHandle, ServerHandle}, target::TcpServerTarget, @@ -17,6 +10,13 @@ use tokio::{ join, time::{sleep, timeout}, }; +use vcs::{ + constants::SERVER_FILE_VAULT, + workspace::{ + member::Member, + vault::{Vault, config::VaultConfig, virtual_file::VirtualFileVersionDescription}, + }, +}; use crate::get_test_dir; |
