summaryrefslogtreecommitdiff
path: root/crates/vcs_data/src/data/local/latest_file_data.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2025-11-20 13:40:12 +0800
committer魏曹先生 <1992414357@qq.com>2025-11-20 13:40:12 +0800
commit8b70533434d86f72a9a62d79f0f447a619e25040 (patch)
tree486d48bc091a590412181c416b8da58ca8f62062 /crates/vcs_data/src/data/local/latest_file_data.rs
parent54bdb27af49788ca4562a72510f3b81278cb133f (diff)
Rename MemberHeld to LatestFileData and add version tracking
The struct now tracks both file holding status and latest file versions for permission validation and update checks.
Diffstat (limited to 'crates/vcs_data/src/data/local/latest_file_data.rs')
-rw-r--r--crates/vcs_data/src/data/local/latest_file_data.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/crates/vcs_data/src/data/local/latest_file_data.rs b/crates/vcs_data/src/data/local/latest_file_data.rs
new file mode 100644
index 0000000..f737650
--- /dev/null
+++ b/crates/vcs_data/src/data/local/latest_file_data.rs
@@ -0,0 +1,70 @@
+use std::{collections::HashMap, io::Error, path::PathBuf};
+
+use cfg_file::ConfigFile;
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ constants::{CLIENT_FILE_MEMBER_HELD, CLIENT_FILE_MEMBER_HELD_NOSET},
+ current::current_local_path,
+ data::{
+ member::MemberId,
+ vault::virtual_file::{VirtualFileId, VirtualFileVersion},
+ },
+};
+
+const ACCOUNT: &str = "{account}";
+
+/// # Latest file data
+/// Records the file holder and the latest version for permission and update checks
+#[derive(Debug, Default, Clone, Serialize, Deserialize, ConfigFile)]
+#[cfg_file(path = CLIENT_FILE_MEMBER_HELD_NOSET)]
+pub struct LatestFileData {
+ /// File holding status
+ held_status: HashMap<VirtualFileId, HeldStatus>,
+
+ /// File version
+ versions: HashMap<VirtualFileId, VirtualFileVersion>,
+}
+
+#[derive(Debug, Default, Clone, Serialize, Deserialize)]
+pub enum HeldStatus {
+ HeldWith(MemberId), // Held, status changes are sync to the client
+ NotHeld, // Not held, status changes are sync to the client
+
+ #[default]
+ WantedToKnow, // Holding status is unknown, notify server must inform client
+}
+
+impl LatestFileData {
+ /// Get the path to the file holding the held status information for the given member.
+ pub fn held_file_path(account: &MemberId) -> Result<PathBuf, std::io::Error> {
+ let Some(local_path) = current_local_path() else {
+ return Err(Error::new(
+ std::io::ErrorKind::NotFound,
+ "Workspace not found.",
+ ));
+ };
+ Ok(local_path.join(CLIENT_FILE_MEMBER_HELD.replace(ACCOUNT, account)))
+ }
+
+ /// Get the member who holds the file with the given ID.
+ pub fn file_holder(&self, vfid: &VirtualFileId) -> Option<&MemberId> {
+ self.held_status.get(vfid).and_then(|status| match status {
+ HeldStatus::HeldWith(id) => Some(id),
+ _ => None,
+ })
+ }
+
+ /// Update the held status of the files.
+ pub fn update_held_status(&mut self, map: HashMap<VirtualFileId, Option<MemberId>>) {
+ for (vfid, member_id) in map {
+ self.held_status.insert(
+ vfid,
+ match member_id {
+ Some(member_id) => HeldStatus::HeldWith(member_id),
+ None => HeldStatus::NotHeld,
+ },
+ );
+ }
+ }
+}