open_lark/service/cloud_docs/comments/
delete_reply.rs1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 core::{
6 api_req::ApiRequest,
7 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8 config::Config,
9 constants::AccessTokenType,
10 http::Transport,
11 req_option::RequestOption,
12 SDKResult,
13 },
14 impl_executable_builder_owned,
15};
16
17#[derive(Debug, Serialize, Default, Clone)]
19pub struct DeleteReplyRequest {
20 #[serde(skip)]
21 api_request: ApiRequest,
22 #[serde(skip)]
24 file_token: String,
25 #[serde(skip)]
27 file_type: String,
28 #[serde(skip)]
30 comment_id: String,
31 #[serde(skip)]
33 reply_id: String,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 user_id_type: Option<String>,
37}
38
39impl DeleteReplyRequest {
40 pub fn builder() -> DeleteReplyRequestBuilder {
41 DeleteReplyRequestBuilder::default()
42 }
43
44 pub fn new(
45 file_token: impl ToString,
46 file_type: impl ToString,
47 comment_id: impl ToString,
48 reply_id: impl ToString,
49 ) -> Self {
50 Self {
51 file_token: file_token.to_string(),
52 file_type: file_type.to_string(),
53 comment_id: comment_id.to_string(),
54 reply_id: reply_id.to_string(),
55 ..Default::default()
56 }
57 }
58}
59
60#[derive(Default)]
61pub struct DeleteReplyRequestBuilder {
62 request: DeleteReplyRequest,
63}
64
65impl DeleteReplyRequestBuilder {
66 pub fn file_token(mut self, file_token: impl ToString) -> Self {
68 self.request.file_token = file_token.to_string();
69 self
70 }
71
72 pub fn file_type(mut self, file_type: impl ToString) -> Self {
74 self.request.file_type = file_type.to_string();
75 self
76 }
77
78 pub fn with_doc_type(mut self) -> Self {
80 self.request.file_type = "doc".to_string();
81 self
82 }
83
84 pub fn with_docx_type(mut self) -> Self {
86 self.request.file_type = "docx".to_string();
87 self
88 }
89
90 pub fn with_sheet_type(mut self) -> Self {
92 self.request.file_type = "sheet".to_string();
93 self
94 }
95
96 pub fn with_bitable_type(mut self) -> Self {
98 self.request.file_type = "bitable".to_string();
99 self
100 }
101
102 pub fn comment_id(mut self, comment_id: impl ToString) -> Self {
104 self.request.comment_id = comment_id.to_string();
105 self
106 }
107
108 pub fn reply_id(mut self, reply_id: impl ToString) -> Self {
110 self.request.reply_id = reply_id.to_string();
111 self
112 }
113
114 pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
116 self.request.user_id_type = Some(user_id_type.to_string());
117 self
118 }
119
120 pub fn with_open_id(mut self) -> Self {
122 self.request.user_id_type = Some("open_id".to_string());
123 self
124 }
125
126 pub fn with_user_id(mut self) -> Self {
128 self.request.user_id_type = Some("user_id".to_string());
129 self
130 }
131
132 pub fn with_union_id(mut self) -> Self {
134 self.request.user_id_type = Some("union_id".to_string());
135 self
136 }
137
138 pub fn build(mut self) -> DeleteReplyRequest {
139 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
140 self.request
141 }
142}
143
144#[derive(Debug, Deserialize)]
146pub struct DeletedReply {
147 pub reply_id: String,
149 pub comment_id: String,
151 pub delete_time: Option<i64>,
153 pub deleter_user_id: Option<String>,
155}
156
157impl_executable_builder_owned!(
159 DeleteReplyRequestBuilder,
160 super::CommentsService,
161 DeleteReplyRequest,
162 BaseResponse<DeleteReplyResponse>,
163 delete_reply
164);
165
166#[derive(Debug, Deserialize)]
168pub struct DeleteReplyResponse {
169 pub reply: DeletedReply,
171}
172
173impl ApiResponseTrait for DeleteReplyResponse {
174 fn data_format() -> ResponseFormat {
175 ResponseFormat::Data
176 }
177}
178
179pub async fn delete_reply(
181 request: DeleteReplyRequest,
182 config: &Config,
183 option: Option<RequestOption>,
184) -> SDKResult<BaseResponse<DeleteReplyResponse>> {
185 let mut api_req = request.api_request;
186 api_req.http_method = Method::DELETE;
187 api_req.api_path = format!(
188 "/open-apis/comment/v1/comments/{}/replies/{}?file_type={}&file_token={}",
189 request.comment_id, request.reply_id, request.file_type, request.file_token
190 );
191
192 if let Some(user_id_type) = request.user_id_type {
194 api_req.api_path = format!("{}&user_id_type={}", api_req.api_path, user_id_type);
195 }
196
197 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
198
199 let api_resp = Transport::request(api_req, config, option).await?;
200 Ok(api_resp)
201}
202
203impl DeletedReply {
204 pub fn has_delete_time(&self) -> bool {
206 self.delete_time.is_some()
207 }
208
209 pub fn has_deleter(&self) -> bool {
211 self.deleter_user_id.is_some()
212 }
213
214 pub fn delete_time_formatted(&self) -> Option<String> {
216 self.delete_time
217 .map(|timestamp| format!("删除时间: {timestamp}"))
218 }
219
220 pub fn summary(&self) -> String {
222 let delete_info = if let Some(time) = self.delete_time {
223 format!("删除时间: {time}")
224 } else {
225 "删除时间: 未知".to_string()
226 };
227
228 let deleter_info = if let Some(deleter) = &self.deleter_user_id {
229 format!("删除者: {deleter}")
230 } else {
231 "删除者: 未知".to_string()
232 };
233
234 format!(
235 "回复ID: {}, 评论ID: {}, {}, {}",
236 self.reply_id, self.comment_id, delete_info, deleter_info
237 )
238 }
239}
240
241impl DeleteReplyResponse {
242 pub fn reply_id(&self) -> &str {
244 &self.reply.reply_id
245 }
246
247 pub fn comment_id(&self) -> &str {
249 &self.reply.comment_id
250 }
251
252 pub fn delete_time(&self) -> Option<i64> {
254 self.reply.delete_time
255 }
256
257 pub fn deleter_user_id(&self) -> Option<&str> {
259 self.reply.deleter_user_id.as_deref()
260 }
261
262 pub fn is_deleted(&self) -> bool {
264 true
266 }
267
268 pub fn success_summary(&self) -> String {
270 format!(
271 "回复删除成功 - 回复ID: {}, 评论ID: {}",
272 self.reply_id(),
273 self.comment_id()
274 )
275 }
276
277 pub fn detailed_info(&self) -> String {
279 self.reply.summary()
280 }
281}
282
283#[cfg(test)]
284mod tests {
285 use super::*;
286
287 #[test]
288 fn test_delete_reply_request_builder() {
289 let request = DeleteReplyRequest::builder()
290 .file_token("doccnxxxxxx")
291 .with_doc_type()
292 .comment_id("comment123")
293 .reply_id("reply456")
294 .with_open_id()
295 .build();
296
297 assert_eq!(request.file_token, "doccnxxxxxx");
298 assert_eq!(request.file_type, "doc");
299 assert_eq!(request.comment_id, "comment123");
300 assert_eq!(request.reply_id, "reply456");
301 assert_eq!(request.user_id_type, Some("open_id".to_string()));
302 }
303
304 #[test]
305 fn test_delete_reply_new() {
306 let request = DeleteReplyRequest::new("doccnxxxxxx", "doc", "comment123", "reply456");
307 assert_eq!(request.file_token, "doccnxxxxxx");
308 assert_eq!(request.file_type, "doc");
309 assert_eq!(request.comment_id, "comment123");
310 assert_eq!(request.reply_id, "reply456");
311 }
312}