diff options
Diffstat (limited to 'legacy_data/src/data/local/latest_file_data.rs')
| -rw-r--r-- | legacy_data/src/data/local/latest_file_data.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/legacy_data/src/data/local/latest_file_data.rs b/legacy_data/src/data/local/latest_file_data.rs new file mode 100644 index 0000000..f9b3aeb --- /dev/null +++ b/legacy_data/src/data/local/latest_file_data.rs @@ -0,0 +1,103 @@ +use std::{collections::HashMap, io::Error, path::PathBuf}; + +use cfg_file::ConfigFile; +use serde::{Deserialize, Serialize}; + +use crate::{ + constants::{CLIENT_FILE_LATEST_DATA, CLIENT_FILE_MEMBER_HELD_NOSET, KEY_ACCOUNT}, + data::{ + member::MemberId, + vault::virtual_file::{VirtualFileId, VirtualFileVersion, VirtualFileVersionDescription}, + }, + env::current_local_path, +}; + +/// # 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 + #[serde(rename = "held")] + held_status: HashMap<VirtualFileId, HeldStatus>, + + /// File version + #[serde(rename = "ver")] + versions: HashMap<VirtualFileId, VirtualFileVersion>, + + /// File histories and descriptions + #[serde(rename = "his")] + histories: HashMap<VirtualFileId, Vec<(VirtualFileVersion, VirtualFileVersionDescription)>>, +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub enum HeldStatus { + #[serde(rename = "Hold")] + HeldWith(MemberId), // Held, status changes are sync to the client + + #[serde(rename = "None")] + NotHeld, // Not held, status changes are sync to the client + + #[default] + #[serde(rename = "Unknown")] + 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 data_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_LATEST_DATA.replace(KEY_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, + }) + } + + /// Get the version of the file with the given ID. + pub fn file_version(&self, vfid: &VirtualFileId) -> Option<&VirtualFileVersion> { + self.versions.get(vfid) + } + + /// Get the version of the file with the given ID. + pub fn file_histories( + &self, + vfid: &VirtualFileId, + ) -> Option<&Vec<(VirtualFileVersion, VirtualFileVersionDescription)>> { + self.histories.get(vfid) + } + + /// Update the held status of the files. + pub fn update_info( + &mut self, + map: HashMap< + VirtualFileId, + ( + Option<MemberId>, + VirtualFileVersion, + Vec<(VirtualFileVersion, VirtualFileVersionDescription)>, + ), + >, + ) { + for (vfid, (member_id, version, desc)) in map { + self.held_status.insert( + vfid.clone(), + match member_id { + Some(member_id) => HeldStatus::HeldWith(member_id), + None => HeldStatus::NotHeld, + }, + ); + self.versions.insert(vfid.clone(), version); + self.histories.insert(vfid, desc); + } + } +} |
