aliyun_oss_rs/object/
multipart_complete_upload.rs

1use crate::{
2    error::{Error, normal_error},
3    request::{Oss, OssRequest},
4};
5use bytes::Bytes;
6use http::Method;
7use http_body_util::Full;
8
9/// Complete the multipart upload
10///
11/// See the [Alibaba Cloud documentation](https://help.aliyun.com/document_detail/31995.html) for details
12pub struct CompleteUpload<'a> {
13    req: OssRequest,
14    parts: Vec<(&'a str, &'a str)>,
15}
16impl<'a> CompleteUpload<'a> {
17    pub(super) fn new(oss: Oss, upload_id: impl ToString) -> Self {
18        let mut req = OssRequest::new(oss, Method::POST);
19        req.insert_query("uploadId", upload_id);
20        CompleteUpload {
21            req,
22            parts: Vec::new(),
23        }
24    }
25    /// Add part information
26    ///
27    /// Data structure: (PartNumber, ETag)
28    pub fn add_parts(mut self, parts: Vec<(&'a str, &'a str)>) -> Self {
29        self.parts.extend(parts);
30        self
31    }
32    /// Complete the multipart upload
33    ///
34    pub async fn send(mut self) -> Result<(), Error> {
35        // Build body
36        let body = format!(
37            "<CompleteMultipartUpload>{}</CompleteMultipartUpload>",
38            self.parts
39                .iter()
40                .map(|(part_num, e_tag)| format!(
41                    "<Part><PartNumber>{}</PartNumber><ETag>{}</ETag></Part>",
42                    part_num, e_tag
43                ))
44                .collect::<Vec<_>>()
45                .join("")
46        );
47        let body_len = body.len();
48        self.req.set_body(Full::new(Bytes::from(body)));
49        self.req.insert_header("Content-Length", body_len);
50        // Upload file
51        let response = self.req.send_to_oss()?.await?;
52        // Parse the response
53        let status_code = response.status();
54        match status_code {
55            code if code.is_success() => Ok(()),
56            _ => Err(normal_error(response).await),
57        }
58    }
59}