aboutsummaryrefslogtreecommitdiff
path: root/actions/src/remote_actions/mapping_manage/share_mapping.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-01-12 05:12:10 +0800
committer魏曹先生 <1992414357@qq.com>2026-01-12 05:36:40 +0800
commite3f4b8188515eeec149eec0405b51e1b57f6e7bb (patch)
treedf80e7289621c39c9d32befbe9bf85a2e129eefb /actions/src/remote_actions/mapping_manage/share_mapping.rs
parentdd8cbe7e863b3fec594696c15c5e009f172749f5 (diff)
Rename and reorganize remote actions modules
Diffstat (limited to 'actions/src/remote_actions/mapping_manage/share_mapping.rs')
-rw-r--r--actions/src/remote_actions/mapping_manage/share_mapping.rs135
1 files changed, 135 insertions, 0 deletions
diff --git a/actions/src/remote_actions/mapping_manage/share_mapping.rs b/actions/src/remote_actions/mapping_manage/share_mapping.rs
new file mode 100644
index 0000000..5c77e53
--- /dev/null
+++ b/actions/src/remote_actions/mapping_manage/share_mapping.rs
@@ -0,0 +1,135 @@
+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::workspace_analyzer::FromRelativePathBuf, sheet::SheetName},
+};
+
+use crate::{
+ remote_actions::{
+ auth_member, check_connection_instance, get_current_sheet_name, try_get_vault,
+ },
+ write_and_return,
+};
+
+#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
+pub struct ShareMappingArguments {
+ pub mappings: Vec<FromRelativePathBuf>,
+ pub description: String,
+ // None = current sheet,
+ // Some(sheet_name) = other ref(public) sheet
+ pub from_sheet: Option<SheetName>,
+ pub to_sheet: SheetName,
+}
+
+#[derive(Serialize, Deserialize, Default)]
+pub enum ShareMappingActionResult {
+ Success,
+
+ // Fail
+ AuthorizeFailed(String),
+ TargetSheetNotFound(SheetName),
+ TargetIsSelf,
+ MappingNotFound(FromRelativePathBuf),
+
+ #[default]
+ Unknown,
+}
+
+#[action_gen]
+pub async fn share_mapping_action(
+ ctx: ActionContext,
+ args: ShareMappingArguments,
+) -> Result<ShareMappingActionResult, 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(ShareMappingActionResult::AuthorizeFailed(e.to_string()));
+ }
+ };
+
+ // Check sheet
+ let sheet_name = args.from_sheet.unwrap_or(
+ get_current_sheet_name(&ctx, instance, &member_id, true)
+ .await?
+ .0,
+ );
+
+ if ctx.is_proc_on_remote() {
+ let vault = try_get_vault(&ctx)?;
+ let sheet = vault.sheet(&sheet_name).await?;
+
+ // Tip: Because sheet_name may specify a sheet that does not belong to the user,
+ // a secondary verification is required.
+
+ // Check if the sheet holder is Some and matches the member_id or is the host
+ let Some(holder) = sheet.holder() else {
+ // If there's no holder, the sheet cannot be shared from
+ write_and_return!(
+ instance,
+ ShareMappingActionResult::AuthorizeFailed("Sheet has no holder".to_string())
+ );
+ };
+
+ // Verify the holder is either the current member or the host
+ if holder != &member_id && holder != VAULT_HOST_NAME {
+ write_and_return!(
+ instance,
+ ShareMappingActionResult::AuthorizeFailed(
+ "Not sheet holder or ref sheet".to_string()
+ )
+ );
+ }
+
+ let to_sheet_name = args.to_sheet;
+
+ // Verify target sheet exists
+ if !vault.sheet_names()?.contains(&to_sheet_name) {
+ // Does not exist
+ write_and_return!(
+ instance,
+ ShareMappingActionResult::TargetSheetNotFound(to_sheet_name.clone())
+ );
+ }
+
+ // Verify sheet is not self
+ if sheet_name == to_sheet_name {
+ // Is self
+ write_and_return!(instance, ShareMappingActionResult::TargetIsSelf);
+ }
+
+ // Verify all mappings are correct
+ for mapping in args.mappings.iter() {
+ if !sheet.mapping().contains_key(mapping) {
+ // If any mapping is invalid, indicate failure
+ write_and_return!(
+ instance,
+ ShareMappingActionResult::MappingNotFound(mapping.clone())
+ );
+ }
+ }
+
+ // Execute sharing logic
+ sheet
+ .share_mappings(&to_sheet_name, args.mappings, &member_id, args.description)
+ .await?;
+
+ // Sharing successful
+ write_and_return!(instance, ShareMappingActionResult::Success);
+ }
+
+ if ctx.is_proc_on_local() {
+ let result = instance
+ .lock()
+ .await
+ .read::<ShareMappingActionResult>()
+ .await?;
+ return Ok(result);
+ }
+
+ Ok(ShareMappingActionResult::Success)
+}