diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-02-26 16:31:04 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-02-26 16:31:04 +0800 |
| commit | 3c4699e2b82659da8517bea3d1cecfad6bb976a9 (patch) | |
| tree | 8b7ae7ef585f0091365ab3771d11776a85d1cb44 | |
| parent | 9420a530e371747cd6df79a5f3bbbf814effe949 (diff) | |
Remove status command and workspace reader
| -rw-r--r-- | src/cmds/arg/status.rs | 6 | ||||
| -rw-r--r-- | src/cmds/cmd/status.rs | 156 | ||||
| -rw-r--r-- | src/cmds/collect/status.rs | 38 | ||||
| -rw-r--r-- | src/cmds/out/status.rs | 47 | ||||
| -rw-r--r-- | src/cmds/renderer/status.rs | 258 | ||||
| -rw-r--r-- | src/systems/cmd.rs | 1 | ||||
| -rw-r--r-- | src/systems/cmd/macros.rs | 4 | ||||
| -rw-r--r-- | src/systems/cmd/workspace_reader.rs | 378 |
8 files changed, 0 insertions, 888 deletions
diff --git a/src/cmds/arg/status.rs b/src/cmds/arg/status.rs deleted file mode 100644 index fbfe5f5..0000000 --- a/src/cmds/arg/status.rs +++ /dev/null @@ -1,6 +0,0 @@ -use clap::Parser; - -#[derive(Parser, Debug)] -pub struct JVStatusArgument { - what: Option<String>, // status of what to query -} diff --git a/src/cmds/cmd/status.rs b/src/cmds/cmd/status.rs deleted file mode 100644 index 3ca2a25..0000000 --- a/src/cmds/cmd/status.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::{any::TypeId, collections::HashMap, time::SystemTime}; - -use crate::{ - cmd_output, - cmds::{ - arg::status::JVStatusArgument, - collect::status::JVStatusCollect, - r#in::empty::JVEmptyInput, - out::status::{JVStatusOutput, JVStatusWrongModifyReason}, - }, - systems::cmd::{ - cmd_system::JVCommandContext, - errors::{CmdExecuteError, CmdPrepareError}, - workspace_reader::LocalWorkspaceReader, - }, -}; -use cmd_system_macros::exec; -use just_enough_vcs::lib::{ - constants::VAULT_HOST_NAME, data::local::workspace_analyzer::ModifiedRelativePathBuf, -}; - -pub struct JVStatusCommand; -type Cmd = JVStatusCommand; -type Arg = JVStatusArgument; -type In = JVEmptyInput; -type Collect = JVStatusCollect; - -fn help_str() -> String { - "".to_string() -} - -async fn prepare(_args: &Arg, _ctx: &JVCommandContext) -> Result<In, CmdPrepareError> { - Ok(In {}) -} - -async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> { - // Initialize a reader for the local workspace and a default result structure - let mut reader = LocalWorkspaceReader::default(); - let mut collect = JVStatusCollect::default(); - - // Analyze the current status of the local workspace - // (detects changes like created, modified, moved, etc.) - let analyzed = reader.analyze_local_status().await?; - - // Retrieve the current account (member) ID - let account = reader.current_account().await?; - - // Retrieve the name of the current sheet - let sheet_name = reader.sheet_name().await?; - - // Is Host Mode - let is_host_mode = reader.is_host_mode().await?; - - let cached_sheet = reader.cached_sheet(&sheet_name).await?; - let sheet_holder = cached_sheet.holder().cloned().unwrap_or_default(); - let is_ref_sheet = sheet_holder == VAULT_HOST_NAME; - - // Get Latest file data - let latest_file_data = reader.pop_latest_file_data(&account).await?; - - // Get the timestamp of the last update, defaulting to the current time if not available - let update_time = reader - .latest_info() - .await? - .update_instant - .unwrap_or(SystemTime::now()); - - // Record the current system time - let now_time = SystemTime::now(); - - // Populate the result structure with the gathered data - collect.current_account = account; - collect.current_sheet = sheet_name; - collect.is_host_mode = is_host_mode; - collect.in_ref_sheet = is_ref_sheet; - collect.analyzed_result = analyzed; - collect.update_time = update_time; - collect.now_time = now_time; - collect.latest_file_data = latest_file_data; - Ok(collect) -} - -#[exec] -async fn exec( - _input: In, - collect: Collect, -) -> Result<(Box<dyn std::any::Any + Send + 'static>, TypeId), CmdExecuteError> { - let mut wrong_modified_items: HashMap<ModifiedRelativePathBuf, JVStatusWrongModifyReason> = - HashMap::new(); - - let latest_file_data = &collect.latest_file_data; - - // Calculate whether modifications are correc - let modified = &collect.analyzed_result.modified; - for item in modified { - // Get mapping - let Ok(mapping) = collect.local_sheet_data.mapping_data(&item) else { - continue; - }; - - // Check base version - { - let base_version = mapping.version_when_updated().clone(); - let Some(latest_version) = latest_file_data - .file_version(mapping.mapping_vfid()) - .cloned() - else { - continue; - }; - - // Base version dismatch - if base_version != latest_version { - wrong_modified_items.insert( - item.clone(), - JVStatusWrongModifyReason::BaseVersionMismatch { - base_version, - latest_version, - }, - ); - continue; - } - } - - // Check edit right (only check when current is not HOST) - if collect.current_account != VAULT_HOST_NAME { - let holder = latest_file_data.file_holder(mapping.mapping_vfid()); - if holder.is_none() { - wrong_modified_items.insert(item.clone(), JVStatusWrongModifyReason::NoHolder); - continue; - } - - let holder = holder.cloned().unwrap(); - if &collect.current_account != &holder { - wrong_modified_items.insert( - item.clone(), - JVStatusWrongModifyReason::ModifiedButNotHeld { holder: holder }, - ); - } - } - } - - let output = JVStatusOutput { - current_account: collect.current_account, - current_sheet: collect.current_sheet, - is_host_mode: collect.is_host_mode, - in_ref_sheet: collect.in_ref_sheet, - analyzed_result: collect.analyzed_result, - wrong_modified_items: wrong_modified_items, - update_time: collect.update_time, - now_time: collect.now_time, - }; - - cmd_output!(JVStatusOutput => output) -} - -crate::command_template!(); diff --git a/src/cmds/collect/status.rs b/src/cmds/collect/status.rs deleted file mode 100644 index fba86c2..0000000 --- a/src/cmds/collect/status.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::time::SystemTime; - -use just_enough_vcs::lib::data::{ - local::{ - latest_file_data::LatestFileData, local_sheet::LocalSheetData, - workspace_analyzer::AnalyzeResultPure, - }, - member::MemberId, - sheet::SheetName, -}; - -pub struct JVStatusCollect { - pub current_account: MemberId, - pub current_sheet: SheetName, - pub is_host_mode: bool, - pub in_ref_sheet: bool, - pub analyzed_result: AnalyzeResultPure, - pub latest_file_data: LatestFileData, - pub local_sheet_data: LocalSheetData, - pub update_time: SystemTime, - pub now_time: SystemTime, -} - -impl Default for JVStatusCollect { - fn default() -> Self { - Self { - current_account: MemberId::default(), - current_sheet: SheetName::default(), - is_host_mode: false, - in_ref_sheet: false, - analyzed_result: AnalyzeResultPure::default(), - latest_file_data: LatestFileData::default(), - local_sheet_data: LocalSheetData::default(), - update_time: SystemTime::now(), - now_time: SystemTime::now(), - } - } -} diff --git a/src/cmds/out/status.rs b/src/cmds/out/status.rs deleted file mode 100644 index 417c94c..0000000 --- a/src/cmds/out/status.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::{collections::HashMap, time::SystemTime}; - -use just_enough_vcs::lib::data::{ - local::workspace_analyzer::{AnalyzeResultPure, ModifiedRelativePathBuf}, - member::MemberId, - sheet::SheetName, -}; -use serde::Serialize; - -#[derive(Serialize)] -pub struct JVStatusOutput { - pub current_account: MemberId, - pub current_sheet: SheetName, - pub is_host_mode: bool, - pub in_ref_sheet: bool, - pub analyzed_result: AnalyzeResultPure, - pub wrong_modified_items: HashMap<ModifiedRelativePathBuf, JVStatusWrongModifyReason>, - pub update_time: SystemTime, - pub now_time: SystemTime, -} - -#[derive(Serialize)] -pub enum JVStatusWrongModifyReason { - BaseVersionMismatch { - base_version: String, - latest_version: String, - }, - ModifiedButNotHeld { - holder: String, - }, - NoHolder, -} - -impl Default for JVStatusOutput { - fn default() -> Self { - Self { - current_account: MemberId::default(), - current_sheet: SheetName::default(), - is_host_mode: false, - in_ref_sheet: false, - analyzed_result: AnalyzeResultPure::default(), - wrong_modified_items: HashMap::new(), - update_time: SystemTime::now(), - now_time: SystemTime::now(), - } - } -} diff --git a/src/cmds/renderer/status.rs b/src/cmds/renderer/status.rs deleted file mode 100644 index 573e74e..0000000 --- a/src/cmds/renderer/status.rs +++ /dev/null @@ -1,258 +0,0 @@ -use cli_utils::{ - display::{SimpleTable, md}, - env::auto_update_outdate, -}; -use render_system_macros::result_renderer; -use rust_i18n::t; - -use crate::cmds::out::status::JVStatusWrongModifyReason; -use crate::{ - cmds::out::status::JVStatusOutput, - r_println, - systems::{cmd::errors::CmdRenderError, render::renderer::JVRenderResult}, -}; - -enum Mode { - StructuralChangesMode, - ContentChangesMode, - Clean, -} - -#[result_renderer(JVStatusRenderer)] -pub async fn render(data: &JVStatusOutput) -> Result<JVRenderResult, CmdRenderError> { - let mut r = JVRenderResult::default(); - - // Render Header - render_header(&mut r, data); - - // Render Info and Mode - render_info_and_mode(&mut r, data); - - // Render Hint - render_hint(&mut r, data); - - Ok(r) -} - -fn render_header(r: &mut JVRenderResult, data: &JVStatusOutput) { - let account = &data.current_account; - let sheet = &data.current_sheet; - r_println!( - r, - "{}", - md(t!("status.header", account = account, sheet = sheet)) - ); -} - -fn render_info_and_mode(r: &mut JVRenderResult, data: &JVStatusOutput) { - let mut info_erased = String::default(); - let mut info_moved = String::default(); - let mut info_lost = String::default(); - let mut info_created = String::default(); - let mut info_modified = String::default(); - - // Collect erased items - if !data.analyzed_result.erased.is_empty() { - info_erased.push_str(format!("{}\n", md(t!("status.info_display.erased.header"))).as_str()); - for erased in data.analyzed_result.erased.iter() { - info_erased.push_str( - format!( - "{}\n", - md(t!( - "status.info_display.erased.item", - item = erased.display() - )) - ) - .as_str(), - ); - } - } - - // Collect moved items - if !data.analyzed_result.moved.is_empty() { - let mut table = SimpleTable::new(vec![ - format!("{}", md(t!("status.info_display.moved.header"))), - "".to_string(), - ]); - for (_, (from, to)) in data.analyzed_result.moved.iter() { - table.push_item(vec![ - format!( - "{}", - md(t!("status.info_display.moved.left", left = from.display())) - ), - format!( - "{}", - md(t!("status.info_display.moved.right", right = to.display())) - ), - ]); - } - info_moved.push_str(table.to_string().as_str()); - } - - // Collect lost items - if !data.analyzed_result.lost.is_empty() { - info_lost.push_str(format!("{}\n", md(t!("status.info_display.lost.header"))).as_str()); - for lost in data.analyzed_result.lost.iter() { - info_lost.push_str( - format!( - "{}\n", - md(t!("status.info_display.lost.item", item = lost.display())) - ) - .as_str(), - ); - } - } - - // Collect created items - if !data.analyzed_result.created.is_empty() { - info_created - .push_str(format!("{}\n", md(t!("status.info_display.created.header"))).as_str()); - for created in data.analyzed_result.created.iter() { - info_created.push_str( - format!( - "{}\n", - md(t!( - "status.info_display.created.item", - item = created.display() - )) - ) - .as_str(), - ); - } - } - - // Collect modified items - if !data.analyzed_result.modified.is_empty() { - info_modified - .push_str(format!("{}\n", md(t!("status.info_display.modified.header"))).as_str()); - for modified in data.analyzed_result.modified.iter() { - if let Some(reason) = data.wrong_modified_items.get(modified) { - let reason_str = match reason { - JVStatusWrongModifyReason::BaseVersionMismatch { - base_version, - latest_version, - } => md(t!( - "status.info_display.modified.reason.base_version_mismatch", - base_version = base_version, - latest_version = latest_version - )), - JVStatusWrongModifyReason::ModifiedButNotHeld { holder } => md(t!( - "status.info_display.modified.reason.modified_but_not_held", - holder = holder - )), - JVStatusWrongModifyReason::NoHolder => { - md(t!("status.info_display.modified.reason.no_holder")) - } - }; - info_modified.push_str( - format!( - "{}\n", - md(t!( - "status.info_display.modified.item_wrong", - item = modified.display(), - reason = reason_str - )) - ) - .as_str(), - ); - continue; - } - info_modified.push_str( - format!( - "{}\n", - md(t!( - "status.info_display.modified.item", - item = modified.display() - )) - ) - .as_str(), - ); - } - } - - let structural_info = vec![info_erased, info_moved, info_lost].join("\n"); - let content_info = vec![info_created, info_modified].join("\n"); - - let mode = get_mode(data); - match mode { - Mode::StructuralChangesMode => { - r_println!( - r, - "{}", - md(t!("status.current_mode.structural", info = structural_info)) - ); - } - Mode::ContentChangesMode => { - r_println!( - r, - "{}", - md(t!("status.current_mode.content", info = content_info)) - ); - } - Mode::Clean => r_println!(r, "{}", md(t!("status.current_mode.clean"))), - } -} - -fn render_hint(r: &mut JVRenderResult, data: &JVStatusOutput) { - // Outdate Hint - let update_time = &data.update_time; - let now_time = &data.now_time; - let duration_minutes: i64 = (now_time - .duration_since(*update_time) - .unwrap_or_default() - .as_secs() - / 60) as i64; - let outdate_minutes = auto_update_outdate(); - - // Outdated - if duration_minutes > outdate_minutes { - let hours = duration_minutes / 60; - let minutes = duration_minutes % 60; - let seconds = (now_time - .duration_since(*update_time) - .unwrap_or_default() - .as_secs() - % 60) as i64; - - r_println!( - r, - "{}", - md(t!( - "status.hints.outdate", - h = hours, - m = minutes, - s = seconds - )) - ); - } - - let in_ref_sheet = &data.in_ref_sheet; - let is_host_mode = &data.is_host_mode; - - // Readonly - if *in_ref_sheet && !is_host_mode { - r_println!(r, "{}", md(t!("status.hints.readonly"))); - } - - // Host - if *is_host_mode { - r_println!(r, "{}", md(t!("status.hints.host"))); - } -} - -fn get_mode(data: &JVStatusOutput) -> Mode { - let analyzed = &data.analyzed_result; - - // If there are any lost, moved, or erased items, use structural changes mode - if !analyzed.moved.is_empty() || !analyzed.lost.is_empty() || !analyzed.erased.is_empty() { - Mode::StructuralChangesMode - } - // Otherwise, if there are any created or modified items, use content changes mode - else if !analyzed.created.is_empty() || !analyzed.modified.is_empty() { - Mode::ContentChangesMode - } - // Otherwise, it's clean - else { - Mode::Clean - } -} diff --git a/src/systems/cmd.rs b/src/systems/cmd.rs index ebfa4f1..71aa207 100644 --- a/src/systems/cmd.rs +++ b/src/systems/cmd.rs @@ -3,4 +3,3 @@ pub mod cmd_system; pub mod errors; pub mod macros; pub mod processer; -pub mod workspace_reader; diff --git a/src/systems/cmd/macros.rs b/src/systems/cmd/macros.rs index efb14f7..093d178 100644 --- a/src/systems/cmd/macros.rs +++ b/src/systems/cmd/macros.rs @@ -19,7 +19,6 @@ /// systems::cmd::{ /// cmd_system::JVCommandContext, /// errors::{CmdExecuteError, CmdPrepareError}, -/// workspace_reader::LocalWorkspaceReader, /// }, /// }; /// @@ -63,7 +62,6 @@ /// /// /// Collect necessary local information for execution /// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> { -/// let reader = LocalWorkspaceReader::default(); /// todo!() /// } /// @@ -90,7 +88,6 @@ /// systems::cmd::{ /// cmd_system::JVCommandContext, /// errors::{CmdExecuteError, CmdPrepareError}, -/// workspace_reader::LocalWorkspaceReader, /// }, /// }; /// @@ -109,7 +106,6 @@ /// } /// /// async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result<Collect, CmdPrepareError> { -/// let reader = LocalWorkspaceReader::default(); /// todo!() /// } /// diff --git a/src/systems/cmd/workspace_reader.rs b/src/systems/cmd/workspace_reader.rs deleted file mode 100644 index 8b2f642..0000000 --- a/src/systems/cmd/workspace_reader.rs +++ /dev/null @@ -1,378 +0,0 @@ -use std::{collections::HashMap, net::SocketAddr, path::PathBuf}; - -use just_enough_vcs::{ - lib::{ - data::{ - local::{ - LocalWorkspace, - cached_sheet::CachedSheet, - latest_file_data::LatestFileData, - latest_info::LatestInfo, - local_sheet::{LocalSheet, LocalSheetData}, - workspace_analyzer::{AnalyzeResult, AnalyzeResultPure}, - workspace_config::LocalConfig, - }, - member::MemberId, - sheet::{SheetData, SheetName}, - vault::vault_config::VaultUuid, - }, - env::current_local_path, - }, - utils::cfg_file::config::ConfigFile, -}; - -use crate::systems::cmd::errors::CmdPrepareError; - -/// Temporarily enter a directory to execute a block of code, then return to the original directory -macro_rules! entry_dir { - ($path:expr, $block:block) => {{ - let original_dir = std::env::current_dir().unwrap(); - std::env::set_current_dir($path).unwrap(); - let result = $block; - std::env::set_current_dir(original_dir).unwrap(); - result - }}; -} - -#[derive(Default)] -pub struct LocalWorkspaceReader { - cached_sheet: HashMap<SheetName, SheetData>, - current_dir: Option<PathBuf>, - workspace_dir: Option<PathBuf>, - latest_file_data: HashMap<MemberId, LatestFileData>, - latest_info: Option<LatestInfo>, - local_config: Option<LocalConfig>, - local_sheet_data: HashMap<(MemberId, SheetName), LocalSheetData>, - local_workspace: Option<LocalWorkspace>, -} - -impl LocalWorkspaceReader { - // Get the current directory - pub fn current_dir(&mut self) -> Result<&PathBuf, CmdPrepareError> { - if self.current_dir.is_none() { - let current_dir = std::env::current_dir()?; - self.current_dir = Some(current_dir); - } - Ok(self.current_dir.as_ref().unwrap()) - } - - // Get the workspace directory - pub fn workspace_dir(&mut self) -> Result<&PathBuf, CmdPrepareError> { - if self.workspace_dir.is_none() { - let workspace_dir = current_local_path(); - self.workspace_dir = workspace_dir; - return match &self.workspace_dir { - Some(d) => Ok(d), - None => Err(CmdPrepareError::LocalWorkspaceNotFound), - }; - } - Ok(self.workspace_dir.as_ref().unwrap()) - } - - // Get the local configuration - pub async fn local_config(&mut self) -> Result<&LocalConfig, CmdPrepareError> { - if self.local_config.is_none() { - let workspace_dir = self.workspace_dir()?; - let local_config = entry_dir!(workspace_dir, { - LocalConfig::read() - .await - .map_err(|_| CmdPrepareError::LocalConfigNotFound)? - }); - self.local_config = Some(local_config) - } - Ok(self.local_config.as_ref().unwrap()) - } - - // Current account - pub async fn current_account(&mut self) -> Result<MemberId, CmdPrepareError> { - Ok(self.local_config().await?.current_account()) - } - - // Whether it is in host mode - pub async fn is_host_mode(&mut self) -> Result<bool, CmdPrepareError> { - Ok(self.local_config().await?.is_host_mode()) - } - - // Whether the workspace is stained - pub async fn workspace_stained(&mut self) -> Result<bool, CmdPrepareError> { - Ok(self.local_config().await?.stained()) - } - - // Stain UUID - pub async fn stained_uuid(&mut self) -> Result<Option<VaultUuid>, CmdPrepareError> { - Ok(self.local_config().await?.stained_uuid()) - } - - // Upstream address - pub async fn upstream_addr(&mut self) -> Result<SocketAddr, CmdPrepareError> { - Ok(self.local_config().await?.upstream_addr()) - } - - // Currently used sheet - pub async fn sheet_in_use(&mut self) -> Result<&Option<SheetName>, CmdPrepareError> { - Ok(self.local_config().await?.sheet_in_use()) - } - - // Get the sheet name in use, or error if none - pub async fn sheet_name(&mut self) -> Result<SheetName, CmdPrepareError> { - match self.local_config().await?.sheet_in_use() { - Some(name) => Ok(name.clone()), - None => Err(CmdPrepareError::NoSheetInUse), - } - } - - // Current draft folder - pub async fn current_draft_folder(&mut self) -> Result<Option<PathBuf>, CmdPrepareError> { - Ok(self.local_config().await?.current_draft_folder()) - } - - // Get the local workspace - pub async fn local_workspace(&mut self) -> Result<&LocalWorkspace, CmdPrepareError> { - if self.local_workspace.is_none() { - let workspace_dir = self.workspace_dir()?.clone(); - let local_config = self.local_config().await?.clone(); - let Some(local_workspace) = entry_dir!(&workspace_dir, { - LocalWorkspace::init_current_dir(local_config) - }) else { - return Err(CmdPrepareError::LocalWorkspaceNotFound); - }; - self.local_workspace = Some(local_workspace); - } - Ok(self.local_workspace.as_ref().unwrap()) - } - - // Get the latest information - pub async fn latest_info(&mut self) -> Result<&LatestInfo, CmdPrepareError> { - if self.latest_info.is_none() { - let local_dir = self.workspace_dir()?.clone(); - let local_config = self.local_config().await?.clone(); - let latest_info = entry_dir!(&local_dir, { - match LatestInfo::read_from(LatestInfo::latest_info_path( - &local_dir, - &local_config.current_account(), - )) - .await - { - Ok(info) => info, - Err(_) => { - return Err(CmdPrepareError::LatestInfoNotFound); - } - } - }); - self.latest_info = Some(latest_info); - } - Ok(self.latest_info.as_ref().unwrap()) - } - - // Get the latest file data - pub async fn latest_file_data( - &mut self, - account: &MemberId, - ) -> Result<&LatestFileData, CmdPrepareError> { - if !self.latest_file_data.contains_key(account) { - let local_dir = self.workspace_dir()?; - let latest_file_data_path = - match entry_dir!(&local_dir, { LatestFileData::data_path(account) }) { - Ok(p) => p, - Err(_) => return Err(CmdPrepareError::LatestFileDataNotExist(account.clone())), - }; - let latest_file_data = LatestFileData::read_from(&latest_file_data_path).await?; - self.latest_file_data - .insert(account.clone(), latest_file_data); - } - - Ok(self.latest_file_data.get(account).unwrap()) - } - - // Get the cached sheet - pub async fn cached_sheet( - &mut self, - sheet_name: &SheetName, - ) -> Result<&SheetData, CmdPrepareError> { - if !self.cached_sheet.contains_key(sheet_name) { - let workspace_dir = self.workspace_dir()?; - let cached_sheet = entry_dir!(&workspace_dir, { - match CachedSheet::cached_sheet_data(sheet_name).await { - Ok(data) => data, - Err(_) => return Err(CmdPrepareError::CachedSheetNotFound(sheet_name.clone())), - } - }); - self.cached_sheet.insert(sheet_name.clone(), cached_sheet); - } - - Ok(self.cached_sheet.get(sheet_name).unwrap()) - } - - // Get the local sheet data - pub async fn local_sheet_data( - &mut self, - account: &MemberId, - sheet_name: &SheetName, - ) -> Result<&LocalSheetData, CmdPrepareError> { - let key = (account.clone(), sheet_name.clone()); - if !self.local_sheet_data.contains_key(&key) { - let workspace_dir = self.workspace_dir()?.clone(); - let local_workspace = self.local_workspace().await?; - let path = entry_dir!(&workspace_dir, { - local_workspace.local_sheet_path(account, sheet_name) - }); - let local_sheet_data = match LocalSheetData::read_from(path).await { - Ok(data) => data, - Err(_) => { - return Err(CmdPrepareError::LocalSheetNotFound( - account.clone(), - sheet_name.clone(), - )); - } - }; - self.local_sheet_data.insert(key.clone(), local_sheet_data); - } - - Ok(self.local_sheet_data.get(&key).unwrap()) - } - - // Clone and get the local sheet - pub async fn local_sheet_cloned( - &mut self, - account: &MemberId, - sheet_name: &SheetName, - ) -> Result<LocalSheet<'_>, CmdPrepareError> { - let local_sheet_data = self.local_sheet_data(account, sheet_name).await?.clone(); - Ok(LocalSheet::new( - self.local_workspace().await?, - account.clone(), - sheet_name.clone(), - local_sheet_data, - )) - } - - // Analyze local status - pub async fn analyze_local_status(&mut self) -> Result<AnalyzeResultPure, CmdPrepareError> { - let Ok(analyzed) = AnalyzeResult::analyze_local_status(self.local_workspace().await?).await - else { - return Err(CmdPrepareError::LocalStatusAnalyzeFailed); - }; - Ok(analyzed.into()) - } - - // Pop the local configuration (take ownership if cached) - pub async fn pop_local_config(&mut self) -> Result<LocalConfig, CmdPrepareError> { - if let Some(local_config) = self.local_config.take() { - Ok(local_config) - } else { - let workspace_dir = self.workspace_dir()?; - let local_config = entry_dir!(workspace_dir, { - LocalConfig::read() - .await - .map_err(|_| CmdPrepareError::LocalConfigNotFound)? - }); - Ok(local_config) - } - } - - // Pop the local workspace (take ownership if cached) - pub async fn pop_local_workspace(&mut self) -> Result<LocalWorkspace, CmdPrepareError> { - if let Some(local_workspace) = self.local_workspace.take() { - Ok(local_workspace) - } else { - let workspace_dir = self.workspace_dir()?.clone(); - let local_config = self.local_config().await?.clone(); - let Some(local_workspace) = entry_dir!(&workspace_dir, { - LocalWorkspace::init_current_dir(local_config) - }) else { - return Err(CmdPrepareError::LocalWorkspaceNotFound); - }; - Ok(local_workspace) - } - } - - // Pop the latest information (take ownership if cached) - pub async fn pop_latest_info(&mut self) -> Result<LatestInfo, CmdPrepareError> { - if let Some(latest_info) = self.latest_info.take() { - Ok(latest_info) - } else { - let local_dir = self.workspace_dir()?.clone(); - let local_config = self.local_config().await?.clone(); - let latest_info = entry_dir!(&local_dir, { - match LatestInfo::read_from(LatestInfo::latest_info_path( - &local_dir, - &local_config.current_account(), - )) - .await - { - Ok(info) => info, - Err(_) => { - return Err(CmdPrepareError::LatestInfoNotFound); - } - } - }); - Ok(latest_info) - } - } - - // Pop the latest file data for a specific account (take ownership if cached) - pub async fn pop_latest_file_data( - &mut self, - account: &MemberId, - ) -> Result<LatestFileData, CmdPrepareError> { - if let Some(latest_file_data) = self.latest_file_data.remove(account) { - Ok(latest_file_data) - } else { - let local_dir = self.workspace_dir()?; - let latest_file_data_path = - match entry_dir!(&local_dir, { LatestFileData::data_path(account) }) { - Ok(p) => p, - Err(_) => return Err(CmdPrepareError::LatestFileDataNotExist(account.clone())), - }; - let latest_file_data = LatestFileData::read_from(&latest_file_data_path).await?; - Ok(latest_file_data) - } - } - - // Pop the cached sheet for a specific sheet name (take ownership if cached) - pub async fn pop_cached_sheet( - &mut self, - sheet_name: &SheetName, - ) -> Result<SheetData, CmdPrepareError> { - if let Some(cached_sheet) = self.cached_sheet.remove(sheet_name) { - Ok(cached_sheet) - } else { - let workspace_dir = self.workspace_dir()?; - let cached_sheet = entry_dir!(&workspace_dir, { - match CachedSheet::cached_sheet_data(sheet_name).await { - Ok(data) => data, - Err(_) => return Err(CmdPrepareError::CachedSheetNotFound(sheet_name.clone())), - } - }); - Ok(cached_sheet) - } - } - - // Pop the local sheet data for a specific account and sheet name (take ownership if cached) - pub async fn pop_local_sheet_data( - &mut self, - account: &MemberId, - sheet_name: &SheetName, - ) -> Result<LocalSheetData, CmdPrepareError> { - let key = (account.clone(), sheet_name.clone()); - if let Some(local_sheet_data) = self.local_sheet_data.remove(&key) { - Ok(local_sheet_data) - } else { - let workspace_dir = self.workspace_dir()?.clone(); - let local_workspace = self.local_workspace().await?; - let path = entry_dir!(&workspace_dir, { - local_workspace.local_sheet_path(account, sheet_name) - }); - let local_sheet_data = match LocalSheetData::read_from(path).await { - Ok(data) => data, - Err(_) => { - return Err(CmdPrepareError::LocalSheetNotFound( - account.clone(), - sheet_name.clone(), - )); - } - }; - Ok(local_sheet_data) - } - } -} |
