1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::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
15pub struct DocumentBlockService {
17 config: Config,
18}
19
20impl DocumentBlockService {
21 pub fn new(config: Config) -> Self {
22 Self { config }
23 }
24
25 pub async fn create(
31 &self,
32 document_id: impl Into<String>,
33 request: CreateBlockRequest,
34 option: Option<RequestOption>,
35 ) -> SDKResult<BaseResponse<CreateBlockRespData>> {
36 let api_req = ApiRequest {
37 http_method: Method::POST,
38 api_path: format!("/open-apis/docx/v1/documents/{}/blocks", document_id.into()),
39 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
40 body: serde_json::to_vec(&request)?,
41 ..Default::default()
42 };
43
44 let api_resp = Transport::request(api_req, &self.config, option).await?;
45 Ok(api_resp)
46 }
47
48 pub async fn get(
54 &self,
55 document_id: impl Into<String>,
56 block_id: impl Into<String>,
57 option: Option<RequestOption>,
58 ) -> SDKResult<BaseResponse<GetBlockRespData>> {
59 let api_req = ApiRequest {
60 http_method: Method::GET,
61 api_path: format!(
62 "/open-apis/docx/v1/documents/{}/blocks/{}",
63 document_id.into(),
64 block_id.into()
65 ),
66 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
67 ..Default::default()
68 };
69
70 let api_resp = Transport::request(api_req, &self.config, option).await?;
71 Ok(api_resp)
72 }
73
74 pub async fn patch(
80 &self,
81 document_id: impl Into<String>,
82 block_id: impl Into<String>,
83 request: PatchBlockRequest,
84 option: Option<RequestOption>,
85 ) -> SDKResult<BaseResponse<PatchBlockRespData>> {
86 let api_req = ApiRequest {
87 http_method: Method::PATCH,
88 api_path: format!(
89 "/open-apis/docx/v1/documents/{}/blocks/{}",
90 document_id.into(),
91 block_id.into()
92 ),
93 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
94 body: serde_json::to_vec(&request)?,
95 ..Default::default()
96 };
97
98 let api_resp = Transport::request(api_req, &self.config, option).await?;
99 Ok(api_resp)
100 }
101
102 pub async fn batch_update(
108 &self,
109 document_id: impl Into<String>,
110 request: BatchUpdateBlockRequest,
111 option: Option<RequestOption>,
112 ) -> SDKResult<BaseResponse<BatchUpdateBlockRespData>> {
113 let mut api_req = ApiRequest {
114 http_method: Method::PATCH,
115 api_path: format!(
116 "/open-apis/docx/v1/documents/{}/blocks/batch_update",
117 document_id.into()
118 ),
119 ..Default::default()
120 };
121 api_req.supported_access_token_types = vec![AccessTokenType::User, AccessTokenType::Tenant];
122 api_req.body = serde_json::to_vec(&request)?;
123
124 let api_resp = Transport::request(api_req, &self.config, option).await?;
125 Ok(api_resp)
126 }
127
128 pub async fn batch_delete(
134 &self,
135 document_id: impl Into<String>,
136 request: BatchDeleteBlockRequest,
137 option: Option<RequestOption>,
138 ) -> SDKResult<BaseResponse<BatchDeleteBlockRespData>> {
139 let mut api_req = ApiRequest {
140 http_method: Method::DELETE,
141 api_path: format!(
142 "/open-apis/docx/v1/documents/{}/blocks/batch_delete",
143 document_id.into()
144 ),
145 ..Default::default()
146 };
147 api_req.supported_access_token_types = vec![AccessTokenType::User, AccessTokenType::Tenant];
148 api_req.body = serde_json::to_vec(&request)?;
149
150 let api_resp = Transport::request(api_req, &self.config, option).await?;
151 Ok(api_resp)
152 }
153
154 pub async fn list_children(
160 &self,
161 document_id: impl Into<String>,
162 block_id: impl Into<String>,
163 request: ListChildrenRequest,
164 option: Option<RequestOption>,
165 ) -> SDKResult<BaseResponse<ListChildrenRespData>> {
166 let mut api_req = ApiRequest {
167 http_method: Method::GET,
168 api_path: format!(
169 "/open-apis/docx/v1/documents/{}/blocks/{}/children",
170 document_id.into(),
171 block_id.into()
172 ),
173 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
174 ..Default::default()
175 };
176
177 if let Some(page_size) = request.page_size {
179 api_req
180 .query_params
181 .insert("page_size".to_string(), page_size.to_string());
182 }
183 if let Some(page_token) = request.page_token {
184 api_req
185 .query_params
186 .insert("page_token".to_string(), page_token);
187 }
188
189 let api_resp = Transport::request(api_req, &self.config, option).await?;
190 Ok(api_resp)
191 }
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize, Default)]
198pub struct CreateBlockRequest {
199 pub parent_id: String,
201 pub index: Option<i32>,
203 pub blocks: Vec<BlockData>,
205}
206
207impl CreateBlockRequest {
208 pub fn builder() -> CreateBlockRequestBuilder {
209 CreateBlockRequestBuilder::default()
210 }
211
212 pub fn new(parent_id: impl Into<String>, blocks: Vec<BlockData>) -> Self {
213 Self {
214 parent_id: parent_id.into(),
215 index: None,
216 blocks,
217 }
218 }
219
220 pub fn with_index(mut self, index: i32) -> Self {
221 self.index = Some(index);
222 self
223 }
224}
225
226#[derive(Default)]
228pub struct CreateBlockRequestBuilder {
229 request: CreateBlockRequest,
230 document_id: String,
231}
232
233impl CreateBlockRequestBuilder {
234 pub fn document_id(mut self, document_id: impl Into<String>) -> Self {
235 self.document_id = document_id.into();
236 self
237 }
238
239 pub fn parent_id(mut self, parent_id: impl Into<String>) -> Self {
240 self.request.parent_id = parent_id.into();
241 self
242 }
243
244 pub fn index(mut self, index: i32) -> Self {
245 self.request.index = Some(index);
246 self
247 }
248
249 pub fn blocks(mut self, blocks: Vec<BlockData>) -> Self {
250 self.request.blocks = blocks;
251 self
252 }
253
254 pub fn add_block(mut self, block: BlockData) -> Self {
255 self.request.blocks.push(block);
256 self
257 }
258
259 pub fn build(self) -> (String, CreateBlockRequest) {
260 (self.document_id, self.request)
261 }
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct BlockData {
267 pub block_type: i32,
269 pub block: Value,
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct CreateBlockRespData {
276 pub blocks: Vec<BlockInfo>,
278 pub document_revision_id: i64,
280}
281
282impl ApiResponseTrait for CreateBlockRespData {
283 fn data_format() -> ResponseFormat {
284 ResponseFormat::Data
285 }
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct BlockInfo {
291 pub block_id: String,
293 pub parent_id: String,
295 pub children: Vec<String>,
297 pub block_type: i32,
299 pub index: i32,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize)]
305pub struct GetBlockRespData {
306 pub block: DetailedBlock,
308}
309
310impl ApiResponseTrait for GetBlockRespData {
311 fn data_format() -> ResponseFormat {
312 ResponseFormat::Data
313 }
314}
315
316#[derive(Debug, Clone, Serialize, Deserialize)]
318pub struct DetailedBlock {
319 pub block_id: String,
321 pub parent_id: String,
323 pub children: Vec<String>,
325 pub block_type: i32,
327 pub index: i32,
329 pub block: Value,
331}
332
333#[derive(Debug, Clone, Serialize, Deserialize)]
335pub struct PatchBlockRequest {
336 pub block: Value,
338}
339
340impl PatchBlockRequest {
341 pub fn new(block: Value) -> Self {
342 Self { block }
343 }
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize)]
348pub struct PatchBlockRespData {
349 pub block: DetailedBlock,
351 pub document_revision_id: i64,
353}
354
355impl ApiResponseTrait for PatchBlockRespData {
356 fn data_format() -> ResponseFormat {
357 ResponseFormat::Data
358 }
359}
360
361#[derive(Debug, Clone, Serialize, Deserialize, Default)]
363pub struct BatchUpdateBlockRequest {
364 pub requests: Vec<UpdateBlockItem>,
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize)]
370pub struct UpdateBlockItem {
371 pub block_id: String,
373 pub block: Value,
375}
376
377impl BatchUpdateBlockRequest {
378 pub fn builder() -> BatchUpdateBlockRequestBuilder {
379 BatchUpdateBlockRequestBuilder::default()
380 }
381
382 pub fn new(requests: Vec<UpdateBlockItem>) -> Self {
383 Self { requests }
384 }
385}
386
387#[derive(Default)]
389pub struct BatchUpdateBlockRequestBuilder {
390 request: BatchUpdateBlockRequest,
391 document_id: String,
392}
393
394impl BatchUpdateBlockRequestBuilder {
395 pub fn document_id(mut self, document_id: impl Into<String>) -> Self {
396 self.document_id = document_id.into();
397 self
398 }
399
400 pub fn requests(mut self, requests: Vec<UpdateBlockItem>) -> Self {
401 self.request.requests = requests;
402 self
403 }
404
405 pub fn add_request(mut self, block_id: impl Into<String>, block: Value) -> Self {
406 self.request.requests.push(UpdateBlockItem {
407 block_id: block_id.into(),
408 block,
409 });
410 self
411 }
412
413 pub fn build(self) -> (String, BatchUpdateBlockRequest) {
414 (self.document_id, self.request)
415 }
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct BatchUpdateBlockRespData {
421 pub blocks: Vec<DetailedBlock>,
423 pub document_revision_id: i64,
425}
426
427impl ApiResponseTrait for BatchUpdateBlockRespData {
428 fn data_format() -> ResponseFormat {
429 ResponseFormat::Data
430 }
431}
432
433#[derive(Debug, Clone, Serialize, Deserialize, Default)]
435pub struct BatchDeleteBlockRequest {
436 pub block_ids: Vec<String>,
438}
439
440impl BatchDeleteBlockRequest {
441 pub fn builder() -> BatchDeleteBlockRequestBuilder {
442 BatchDeleteBlockRequestBuilder::default()
443 }
444
445 pub fn new(block_ids: Vec<String>) -> Self {
446 Self { block_ids }
447 }
448}
449
450#[derive(Default)]
452pub struct BatchDeleteBlockRequestBuilder {
453 request: BatchDeleteBlockRequest,
454 document_id: String,
455}
456
457impl BatchDeleteBlockRequestBuilder {
458 pub fn document_id(mut self, document_id: impl Into<String>) -> Self {
459 self.document_id = document_id.into();
460 self
461 }
462
463 pub fn block_ids(mut self, block_ids: Vec<String>) -> Self {
464 self.request.block_ids = block_ids;
465 self
466 }
467
468 pub fn add_block_id(mut self, block_id: impl Into<String>) -> Self {
469 self.request.block_ids.push(block_id.into());
470 self
471 }
472
473 pub fn build(self) -> (String, BatchDeleteBlockRequest) {
474 (self.document_id, self.request)
475 }
476}
477
478#[derive(Debug, Clone, Serialize, Deserialize)]
480pub struct BatchDeleteBlockRespData {
481 pub document_revision_id: i64,
483}
484
485impl ApiResponseTrait for BatchDeleteBlockRespData {
486 fn data_format() -> ResponseFormat {
487 ResponseFormat::Data
488 }
489}
490
491#[derive(Debug, Clone, Serialize, Deserialize)]
493pub struct ListChildrenRequest {
494 pub page_size: Option<i32>,
496 pub page_token: Option<String>,
498}
499
500impl ListChildrenRequest {
501 pub fn new() -> Self {
502 Self {
503 page_size: None,
504 page_token: None,
505 }
506 }
507
508 pub fn with_page_size(mut self, page_size: i32) -> Self {
509 self.page_size = Some(page_size);
510 self
511 }
512
513 pub fn with_page_token(mut self, page_token: impl Into<String>) -> Self {
514 self.page_token = Some(page_token.into());
515 self
516 }
517}
518
519impl Default for ListChildrenRequest {
520 fn default() -> Self {
521 Self::new()
522 }
523}
524
525#[derive(Debug, Clone, Serialize, Deserialize)]
527pub struct ListChildrenRespData {
528 pub items: Vec<DetailedBlock>,
530 pub has_more: bool,
532 pub page_token: Option<String>,
534}
535
536impl ApiResponseTrait for ListChildrenRespData {
537 fn data_format() -> ResponseFormat {
538 ResponseFormat::Data
539 }
540}
541
542macro_rules! impl_execute_with_path {
546 ($builder:ty, $response:ty, $method:ident) => {
547 impl $builder {
548 pub async fn execute(
550 self,
551 service: &DocumentBlockService,
552 option: Option<RequestOption>,
553 ) -> SDKResult<$response> {
554 let (document_id, request) = self.build();
555 service.$method(document_id, request, option).await
556 }
557
558 pub async fn execute_with_options(
560 self,
561 service: &DocumentBlockService,
562 option: RequestOption,
563 ) -> SDKResult<$response> {
564 self.execute(service, Some(option)).await
565 }
566 }
567 };
568}
569
570impl_execute_with_path!(
571 CreateBlockRequestBuilder,
572 BaseResponse<CreateBlockRespData>,
573 create
574);
575
576impl_execute_with_path!(
577 BatchUpdateBlockRequestBuilder,
578 BaseResponse<BatchUpdateBlockRespData>,
579 batch_update
580);
581
582impl_execute_with_path!(
583 BatchDeleteBlockRequestBuilder,
584 BaseResponse<BatchDeleteBlockRespData>,
585 batch_delete
586);