From 9e5a374164aca71ec99aa8b46e7932a1b74f68cc Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 7 Nov 2025 13:24:43 +0800 Subject: Add path formatting utility and local sheet management - Implement format_path_str function to clean and normalize file paths - Add LocalSheet struct for tracking local file metadata - Support CRUD operations on local sheet mappings - Integrate path formatting into local sheet operations --- crates/vcs_data/src/data/local/local_sheet.rs | 107 +++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 10 deletions(-) (limited to 'crates/vcs_data/src/data/local/local_sheet.rs') diff --git a/crates/vcs_data/src/data/local/local_sheet.rs b/crates/vcs_data/src/data/local/local_sheet.rs index 63b73ac..bfe8d01 100644 --- a/crates/vcs_data/src/data/local/local_sheet.rs +++ b/crates/vcs_data/src/data/local/local_sheet.rs @@ -1,45 +1,61 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, io::Error, path::PathBuf}; use ::serde::{Deserialize, Serialize}; -use cfg_file::ConfigFile; +use cfg_file::{ConfigFile, config::ConfigFile}; use chrono::NaiveDate; +use string_proc::format_path::format_path; use crate::{ constants::CLIENT_FILE_LOCAL_SHEET_NOSET, - data::vault::virtual_file::{VirtualFileId, VirtualFileVersionDescription}, + data::{ + local::LocalWorkspace, + member::MemberId, + vault::virtual_file::{VirtualFileId, VirtualFileVersionDescription}, + }, }; pub type LocalFilePathBuf = PathBuf; +/// # Local Sheet +/// Local sheet information, used to record metadata of actual local files, +/// to compare with upstream information for more optimized file submission, +/// and to determine whether files need to be updated or submitted. +pub struct LocalSheet<'a> { + pub(crate) local_workspace: &'a LocalWorkspace, + pub(crate) member: MemberId, + pub(crate) sheet_name: String, + pub(crate) data: LocalSheetData, +} + #[derive(Debug, Default, Serialize, Deserialize, ConfigFile)] #[cfg_file(path = CLIENT_FILE_LOCAL_SHEET_NOSET)] // Do not use LocalSheet::write or LocalSheet::read -pub struct LocalSheet { +pub struct LocalSheetData { /// Local file path to virtual file ID mapping. #[serde(rename = "mapping")] - mapping: HashMap, // Path to VFID + pub(crate) mapping: HashMap, // Path to VFID } #[derive(Debug, Default, Serialize, Deserialize)] pub struct MappingMetaData { /// Hash value generated immediately after the file is downloaded to the local workspace #[serde(rename = "hash")] - hash_when_updated: String, + pub(crate) hash_when_updated: String, /// Time when the file was downloaded to the local workspace #[serde(rename = "date", with = "naive_date_serde")] - date_when_updated: NaiveDate, + pub(crate) date_when_updated: NaiveDate, /// Size of the file when downloaded to the local workspace #[serde(rename = "size")] - size_when_updated: u64, + pub(crate) size_when_updated: u64, /// Version description when the file was downloaded to the local workspace #[serde(rename = "version")] - version_desc_when_updated: VirtualFileVersionDescription, + pub(crate) version_desc_when_updated: VirtualFileVersionDescription, /// Virtual file ID corresponding to the local path #[serde(rename = "id")] - mapping_vfid: VirtualFileId, + pub(crate) mapping_vfid: VirtualFileId, } mod naive_date_serde { @@ -61,3 +77,74 @@ mod naive_date_serde { NaiveDate::parse_from_str(&s, "%Y-%m-%d").map_err(serde::de::Error::custom) } } + +impl<'a> LocalSheet<'a> { + /// Add mapping to local sheet data + pub fn add_mapping( + &mut self, + path: LocalFilePathBuf, + mapping: MappingMetaData, + ) -> Result<(), std::io::Error> { + let path = format_path(path)?; + if self.data.mapping.contains_key(&path) { + return Err(Error::new( + std::io::ErrorKind::AlreadyExists, + "Mapping already exists", + )); + } + + self.data.mapping.insert(path, mapping); + Ok(()) + } + + /// Move mapping to other path + pub fn move_mapping( + &mut self, + from: LocalFilePathBuf, + to: LocalFilePathBuf, + ) -> Result<(), std::io::Error> { + let from = format_path(from)?; + let to = format_path(to)?; + if self.data.mapping.contains_key(&to) { + return Err(Error::new( + std::io::ErrorKind::AlreadyExists, + "To path already exists.", + )); + } + + let Some(old_value) = self.data.mapping.remove(&from) else { + return Err(Error::new( + std::io::ErrorKind::NotFound, + "From path is not found.", + )); + }; + + self.data.mapping.insert(to, old_value); + + Ok(()) + } + + /// Get muttable mapping data + pub fn mapping_data_mut( + &mut self, + path: LocalFilePathBuf, + ) -> Result<&mut MappingMetaData, std::io::Error> { + let path = format_path(path)?; + let Some(data) = self.data.mapping.get_mut(&path) else { + return Err(Error::new( + std::io::ErrorKind::NotFound, + "Path is not found.", + )); + }; + Ok(data) + } + + /// Persist the sheet to disk + pub async fn persist(&mut self) -> Result<(), std::io::Error> { + let _path = self + .local_workspace + .local_sheet_path(&self.member, &self.sheet_name); + LocalSheetData::write_to(&self.data, &self.sheet_name).await?; + Ok(()) + } +} -- cgit