aliyun_oss_rs/bucket/
del_objects.rs

1use crate::{
2    Error,
3    error::normal_error,
4    request::{Oss, OssRequest},
5};
6use base64::{Engine, engine::general_purpose};
7use bytes::Bytes;
8use http::Method;
9use http_body_util::Full;
10use md5::{Digest, Md5};
11use std::collections::HashSet;
12
13/// Delete multiple files
14///
15/// When deleting, OSS does not check whether the file exists; a valid request always succeeds
16///
17/// See the [Alibaba Cloud documentation](https://help.aliyun.com/document_detail/31983.html) for details
18pub struct DelObjects {
19    req: OssRequest,
20    objects: HashSet<String>,
21}
22impl DelObjects {
23    pub(super) fn new(oss: Oss, files: Vec<impl ToString>) -> Self {
24        let mut req = OssRequest::new(oss, Method::POST);
25        req.insert_query("delete", "");
26        let len = files.len();
27        if len == 0 {
28            DelObjects {
29                req,
30                objects: HashSet::new(),
31            }
32        } else {
33            let mut objects = HashSet::with_capacity(len);
34            for object in files {
35                objects.insert(object.to_string());
36            }
37            DelObjects { req, objects }
38        }
39    }
40    /// Add files to delete
41    ///
42    pub fn add_files(mut self, files: Vec<impl ToString>) -> Self {
43        let len = files.len();
44        if len == 0 {
45            self
46        } else {
47            self.objects.reserve(len);
48            for object in files {
49                self.objects.insert(object.to_string());
50            }
51            self
52        }
53    }
54    /// Send the request
55    ///
56    pub async fn send(mut self) -> Result<(), Error> {
57        // Generate body
58        let body = format!(
59            "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Delete><Quiet>true</Quiet>{}</Delete>",
60            self.objects
61                .iter()
62                .map(|v| format!("<Object><Key>{}</Key></Object>", v))
63                .collect::<Vec<_>>()
64                .join("")
65        );
66        // Calculate body length
67        let body_len = body.len();
68        // Calculate body MD5
69        let mut hasher = Md5::new();
70        hasher.update(&body);
71        let result = hasher.finalize();
72        let body_md5 = general_purpose::STANDARD.encode(&result);
73        // Insert body content
74        self.req.set_body(Full::new(Bytes::from(body)));
75        // Insert header content
76        self.req.insert_header("Content-Length", body_len);
77        self.req.insert_header("Content-MD5", body_md5);
78        // Build the HTTP request
79        let response = self.req.send_to_oss()?.await?;
80        // Parse the response
81        let status_code = response.status();
82        match status_code {
83            code if code.is_success() => Ok(()),
84            _ => Err(normal_error(response).await),
85        }
86    }
87}