open_lark/service/cloud_docs/wiki/v2/space_node/
move.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::core::{
5    api_req::ApiRequest,
6    api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
7    config::Config,
8    constants::AccessTokenType,
9    endpoints::{cloud_docs::*, EndpointBuilder},
10    http::Transport,
11    req_option::RequestOption,
12    SDKResult,
13};
14
15/// 移动知识空间节点请求
16#[derive(Debug, Serialize, Default)]
17pub struct MoveSpaceNodeRequest {
18    #[serde(skip)]
19    api_request: ApiRequest,
20    /// 知识空间id
21    #[serde(skip)]
22    space_id: String,
23    /// 节点token
24    #[serde(skip)]
25    node_token: String,
26    /// 目标父节点token,移动到根目录时可以为空
27    #[serde(skip_serializing_if = "Option::is_none")]
28    target_parent_token: Option<String>,
29    /// 目标位置,移动到目标父节点的指定位置,不填时追加到末尾
30    #[serde(skip_serializing_if = "Option::is_none")]
31    target_prev_token: Option<String>,
32}
33
34impl MoveSpaceNodeRequest {
35    pub fn builder() -> MoveSpaceNodeRequestBuilder {
36        MoveSpaceNodeRequestBuilder::default()
37    }
38
39    pub fn new(space_id: impl ToString, node_token: impl ToString) -> Self {
40        Self {
41            space_id: space_id.to_string(),
42            node_token: node_token.to_string(),
43            ..Default::default()
44        }
45    }
46}
47
48#[derive(Default)]
49pub struct MoveSpaceNodeRequestBuilder {
50    request: MoveSpaceNodeRequest,
51}
52
53impl MoveSpaceNodeRequestBuilder {
54    /// 知识空间id
55    pub fn space_id(mut self, space_id: impl ToString) -> Self {
56        self.request.space_id = space_id.to_string();
57        self
58    }
59
60    /// 要移动的节点token
61    pub fn node_token(mut self, node_token: impl ToString) -> Self {
62        self.request.node_token = node_token.to_string();
63        self
64    }
65
66    /// 目标父节点token
67    pub fn target_parent_token(mut self, target_parent_token: impl ToString) -> Self {
68        self.request.target_parent_token = Some(target_parent_token.to_string());
69        self
70    }
71
72    /// 移动到根目录
73    pub fn move_to_root(mut self) -> Self {
74        self.request.target_parent_token = None;
75        self
76    }
77
78    /// 目标位置,移动到指定节点之后
79    pub fn target_prev_token(mut self, target_prev_token: impl ToString) -> Self {
80        self.request.target_prev_token = Some(target_prev_token.to_string());
81        self
82    }
83
84    /// 追加到末尾
85    pub fn append_to_end(mut self) -> Self {
86        self.request.target_prev_token = None;
87        self
88    }
89
90    pub fn build(mut self) -> MoveSpaceNodeRequest {
91        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
92        self.request
93    }
94}
95
96/// 移动后的节点信息
97#[derive(Debug, Deserialize)]
98pub struct MovedNode {
99    /// 知识空间id
100    pub space_id: String,
101    /// 节点token
102    pub node_token: String,
103    /// 文档类型
104    pub obj_type: String,
105    /// 父节点token
106    pub parent_node_token: Option<String>,
107    /// 节点类型
108    pub node_type: Option<String>,
109    /// 原始文档token
110    pub obj_token: Option<String>,
111    /// 文档标题
112    pub title: Option<String>,
113}
114
115/// 移动知识空间节点响应
116#[derive(Debug, Deserialize)]
117pub struct MoveSpaceNodeResponse {
118    /// 移动后的节点信息
119    pub node: MovedNode,
120}
121
122impl ApiResponseTrait for MoveSpaceNodeResponse {
123    fn data_format() -> ResponseFormat {
124        ResponseFormat::Data
125    }
126}
127
128/// 移动知识空间节点
129pub async fn move_space_node(
130    request: MoveSpaceNodeRequest,
131    config: &Config,
132    option: Option<RequestOption>,
133) -> SDKResult<BaseResponse<MoveSpaceNodeResponse>> {
134    let mut api_req = request.api_request;
135    api_req.http_method = Method::POST;
136    api_req.api_path = {
137        let mut path =
138            EndpointBuilder::replace_param(WIKI_V2_SPACE_NODE_MOVE, "space_id", &request.space_id);
139        path = EndpointBuilder::replace_param(&path, "node_token", &request.node_token);
140        path
141    };
142    api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
143
144    let api_resp = Transport::request(api_req, config, option).await?;
145    Ok(api_resp)
146}
147
148#[cfg(test)]
149#[allow(unused_variables, unused_unsafe)]
150mod tests {
151    use super::*;
152
153    #[test]
154    fn test_move_space_node_request_builder() {
155        let request = MoveSpaceNodeRequest::builder()
156            .space_id("spcxxxxxx")
157            .node_token("wikcnxxxxxx")
158            .target_parent_token("wikcnyyyyyyy")
159            .target_prev_token("wikcnzzzzzzz")
160            .build();
161
162        assert_eq!(request.space_id, "spcxxxxxx");
163        assert_eq!(request.node_token, "wikcnxxxxxx");
164        assert_eq!(
165            request.target_parent_token,
166            Some("wikcnyyyyyyy".to_string())
167        );
168        assert_eq!(request.target_prev_token, Some("wikcnzzzzzzz".to_string()));
169    }
170
171    #[test]
172    fn test_move_to_root() {
173        let request = MoveSpaceNodeRequest::builder()
174            .space_id("spcxxxxxx")
175            .node_token("wikcnxxxxxx")
176            .move_to_root()
177            .append_to_end()
178            .build();
179
180        assert_eq!(request.space_id, "spcxxxxxx");
181        assert_eq!(request.node_token, "wikcnxxxxxx");
182        assert_eq!(request.target_parent_token, None);
183        assert_eq!(request.target_prev_token, None);
184    }
185}