summaryrefslogtreecommitdiff
path: root/legacy_actions/src/remote_actions/sheet_manage
diff options
context:
space:
mode:
Diffstat (limited to 'legacy_actions/src/remote_actions/sheet_manage')
-rw-r--r--legacy_actions/src/remote_actions/sheet_manage/drop_sheet.rs123
-rw-r--r--legacy_actions/src/remote_actions/sheet_manage/make_sheet.rs98
2 files changed, 221 insertions, 0 deletions
diff --git a/legacy_actions/src/remote_actions/sheet_manage/drop_sheet.rs b/legacy_actions/src/remote_actions/sheet_manage/drop_sheet.rs
new file mode 100644
index 0000000..e21f3dd
--- /dev/null
+++ b/legacy_actions/src/remote_actions/sheet_manage/drop_sheet.rs
@@ -0,0 +1,123 @@
+use std::io::ErrorKind;
+
+use action_system::{action::ActionContext, macros::action_gen};
+use serde::{Deserialize, Serialize};
+use tcp_connection::error::TcpTargetError;
+use vcs_data::data::{local::modified_status::sign_vault_modified, sheet::SheetName};
+
+use crate::{
+ remote_actions::{
+ auth_member, check_connection_instance, try_get_local_workspace, try_get_vault,
+ },
+ write_and_return,
+};
+
+#[derive(Default, Serialize, Deserialize)]
+pub enum DropSheetActionResult {
+ Success,
+
+ // Fail
+ SheetInUse,
+ AuthorizeFailed(String),
+ SheetNotExists,
+ SheetDropFailed(String),
+ NoHolder,
+ NotOwner,
+
+ #[default]
+ Unknown,
+}
+
+#[action_gen]
+pub async fn drop_sheet_action(
+ ctx: ActionContext,
+ sheet_name: SheetName,
+) -> Result<DropSheetActionResult, TcpTargetError> {
+ let instance = check_connection_instance(&ctx)?;
+
+ // Auth Member
+ let (member_id, is_host_mode) = match auth_member(&ctx, instance).await {
+ Ok(id) => id,
+ Err(e) => {
+ return Ok(DropSheetActionResult::AuthorizeFailed(e.to_string()));
+ }
+ };
+
+ // Check sheet in use on local
+ if ctx.is_proc_on_local() {
+ let local_workspace = try_get_local_workspace(&ctx)?;
+ if let Some(sheet) = local_workspace.config().lock().await.sheet_in_use() {
+ if sheet == &sheet_name {
+ instance.lock().await.write(false).await?;
+ return Ok(DropSheetActionResult::SheetInUse);
+ }
+ instance.lock().await.write(true).await?;
+ } else {
+ instance.lock().await.write(true).await?;
+ }
+ }
+
+ if ctx.is_proc_on_remote() {
+ // Check if client sheet is in use
+ let sheet_in_use = instance.lock().await.read::<bool>().await?;
+ if !sheet_in_use {
+ return Ok(DropSheetActionResult::SheetInUse);
+ }
+
+ let vault = try_get_vault(&ctx)?;
+
+ // Check if the sheet exists
+ let mut sheet = match vault.sheet(&sheet_name).await {
+ Ok(sheet) => sheet,
+ Err(e) => {
+ if e.kind() == ErrorKind::NotFound {
+ write_and_return!(instance, DropSheetActionResult::SheetNotExists);
+ } else {
+ write_and_return!(
+ instance,
+ DropSheetActionResult::SheetDropFailed(e.to_string())
+ );
+ }
+ }
+ };
+
+ // Get the sheet's holder
+ let Some(holder) = sheet.holder() else {
+ write_and_return!(instance, DropSheetActionResult::NoHolder);
+ };
+
+ // Verify that the sheet holder is either the current user or the host
+ // All sheets belong to the host
+ if holder != &member_id && !is_host_mode {
+ write_and_return!(instance, DropSheetActionResult::NotOwner);
+ }
+
+ // Drop the sheet
+ sheet.forget_holder();
+ match sheet.persist().await {
+ Ok(_) => {
+ write_and_return!(instance, DropSheetActionResult::Success);
+ }
+ Err(e) => {
+ write_and_return!(
+ instance,
+ DropSheetActionResult::SheetDropFailed(e.to_string())
+ );
+ }
+ }
+ }
+
+ if ctx.is_proc_on_local() {
+ let result = instance
+ .lock()
+ .await
+ .read::<DropSheetActionResult>()
+ .await?;
+ if matches!(result, DropSheetActionResult::Success) {
+ sign_vault_modified(true).await;
+ }
+ return Ok(result);
+ }
+
+ Err(TcpTargetError::NoResult("No result.".to_string()))
+}
diff --git a/legacy_actions/src/remote_actions/sheet_manage/make_sheet.rs b/legacy_actions/src/remote_actions/sheet_manage/make_sheet.rs
new file mode 100644
index 0000000..a323413
--- /dev/null
+++ b/legacy_actions/src/remote_actions/sheet_manage/make_sheet.rs
@@ -0,0 +1,98 @@
+use action_system::{action::ActionContext, macros::action_gen};
+use serde::{Deserialize, Serialize};
+use tcp_connection::error::TcpTargetError;
+use vcs_data::{
+ constants::VAULT_HOST_NAME,
+ data::{local::modified_status::sign_vault_modified, sheet::SheetName},
+};
+
+use crate::{
+ remote_actions::{auth_member, check_connection_instance, try_get_vault},
+ write_and_return,
+};
+
+#[derive(Default, Serialize, Deserialize)]
+pub enum MakeSheetActionResult {
+ Success,
+ SuccessRestore,
+
+ // Fail
+ AuthorizeFailed(String),
+ SheetAlreadyExists,
+ SheetCreationFailed(String),
+
+ #[default]
+ Unknown,
+}
+
+/// Build a sheet with context
+#[action_gen]
+pub async fn make_sheet_action(
+ ctx: ActionContext,
+ sheet_name: SheetName,
+) -> Result<MakeSheetActionResult, TcpTargetError> {
+ let instance = check_connection_instance(&ctx)?;
+
+ // Auth Member
+ let (member_id, is_host_mode) = match auth_member(&ctx, instance).await {
+ Ok(id) => id,
+ Err(e) => return Ok(MakeSheetActionResult::AuthorizeFailed(e.to_string())),
+ };
+
+ if ctx.is_proc_on_remote() {
+ let vault = try_get_vault(&ctx)?;
+ let holder = if is_host_mode {
+ VAULT_HOST_NAME.to_string()
+ } else {
+ member_id
+ };
+
+ // Check if the sheet already exists
+ if let Ok(mut sheet) = vault.sheet(&sheet_name).await {
+ // If the sheet has no holder, assign it to the current member (restore operation)
+ if sheet.holder().is_none() {
+ sheet.set_holder(holder.clone());
+ match sheet.persist().await {
+ Ok(_) => {
+ write_and_return!(instance, MakeSheetActionResult::SuccessRestore);
+ }
+ Err(e) => {
+ write_and_return!(
+ instance,
+ MakeSheetActionResult::SheetCreationFailed(e.to_string())
+ );
+ }
+ }
+ } else {
+ write_and_return!(instance, MakeSheetActionResult::SheetAlreadyExists);
+ }
+ } else {
+ // Create the sheet
+ match vault.create_sheet(&sheet_name, &holder).await {
+ Ok(_) => {
+ write_and_return!(instance, MakeSheetActionResult::Success);
+ }
+ Err(e) => {
+ write_and_return!(
+ instance,
+ MakeSheetActionResult::SheetCreationFailed(e.to_string())
+ );
+ }
+ }
+ }
+ }
+
+ if ctx.is_proc_on_local() {
+ let result = instance
+ .lock()
+ .await
+ .read::<MakeSheetActionResult>()
+ .await?;
+ if matches!(result, MakeSheetActionResult::Success) {
+ sign_vault_modified(true).await;
+ }
+ return Ok(result);
+ }
+
+ Err(TcpTargetError::NoResult("No result.".to_string()))
+}