summaryrefslogtreecommitdiff
path: root/actions/src/registry/client_registry.rs
blob: a1bccae7d6c26f81b4b1a85fd734d8a7d23ebe65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::sync::Arc;

use action_system::{action::ActionContext, action_pool::ActionPool};
use cfg_file::config::ConfigFile;
use tcp_connection::error::TcpTargetError;
use vcs_data::data::{
    local::{LocalWorkspace, workspace_config::LocalConfig},
    user::UserDirectory,
};

use crate::{
    connection::protocol::RemoteActionInvoke,
    remote_actions::{
        content_manage::track::register_track_file_action,
        edit_right_manage::change_virtual_file_edit_right::register_change_virtual_file_edit_right_action,
        mapping_manage::{
            edit_mapping::register_edit_mapping_action,
            merge_share_mapping::register_merge_share_mapping_action,
            share_mapping::register_share_mapping_action,
        },
        sheet_manage::{
            drop_sheet::register_drop_sheet_action, make_sheet::register_make_sheet_action,
        },
        workspace_manage::{
            set_upstream_vault::register_set_upstream_vault_action,
            update_to_latest_info::register_update_to_latest_info_action,
        },
    },
};

fn register_actions(pool: &mut ActionPool) {
    // Pool register here

    // Local Actions
    register_set_upstream_vault_action(pool);
    register_update_to_latest_info_action(pool);

    // Sheet Actions
    register_make_sheet_action(pool);
    register_drop_sheet_action(pool);
    register_edit_mapping_action(pool);

    // Share / Merge Share Actions
    register_share_mapping_action(pool);
    register_merge_share_mapping_action(pool);

    // Track Action
    register_track_file_action(pool);

    // User Actions
    register_change_virtual_file_edit_right_action(pool);
}

pub fn client_action_pool() -> ActionPool {
    // Create pool
    let mut pool = ActionPool::new();

    // Register actions
    register_actions(&mut pool);

    // Add process events
    pool.set_on_proc_begin(|ctx, args| Box::pin(on_proc_begin(ctx, args)));

    // Return
    pool
}

async fn on_proc_begin(
    ctx: &mut ActionContext,
    _args: &(dyn std::any::Any + Send + Sync),
) -> Result<(), TcpTargetError> {
    // Is ctx remote
    let is_remote = ctx.is_remote_action();

    // Action name and arguments
    let action_name = ctx.action_name().to_string();
    let action_args_json = ctx.action_args_json().clone();

    // Insert LocalWorkspace Arc
    let Ok(local_config) = LocalConfig::read().await else {
        return Err(TcpTargetError::NotFound(
            "The current directory does not have a local workspace".to_string(),
        ));
    };
    let local_workspace = match LocalWorkspace::init_current_dir(local_config) {
        Some(workspace) => workspace,
        None => {
            return Err(TcpTargetError::NotFound(
                "Failed to initialize local workspace.".to_string(),
            ));
        }
    };
    let local_workspace_arc = Arc::new(local_workspace);
    ctx.insert_arc_data(local_workspace_arc);

    // Insert UserDirectory Arc
    let Some(user_directory) = UserDirectory::current_cfg_dir() else {
        return Err(TcpTargetError::NotFound(
            "The user directory does not exist.".to_string(),
        ));
    };

    let user_directory_arc = Arc::new(user_directory);
    ctx.insert_arc_data(user_directory_arc);

    // Get instance
    let Some(instance) = ctx.instance() else {
        return Err(TcpTargetError::Unsupported(
            "Missing ConnectionInstance in current context, this ActionPool does not support this call"
                .to_string()));
    };

    // If it's remote, invoke action at server
    if is_remote {
        // Build protocol message
        let msg = RemoteActionInvoke {
            action_name,
            action_args_json,
        };

        // Send
        let mut instance = instance.lock().await;
        instance.write_msgpack(&msg).await?;
    }

    // Return OK, wait for client to execute Action locally
    Ok(())
}