aliyun_oss_rs/client/
list_buckets.rs

1use crate::common::body_to_bytes;
2use crate::{
3    Error,
4    common::StorageClass,
5    error::normal_error,
6    request::{Oss, OssRequest},
7};
8use http::Method;
9use serde_derive::Deserialize;
10
11// Return value
12/// Basic bucket information
13#[derive(Debug, Deserialize)]
14#[serde(rename_all = "PascalCase")]
15pub struct BucketBase {
16    /// Bucket name
17    pub name: String,
18    /// Region
19    pub region: String,
20    /// Region identifier in OSS
21    pub location: String,
22    /// Public endpoint
23    pub extranet_endpoint: String,
24    /// Internal endpoint
25    pub intranet_endpoint: String,
26    /// Storage class
27    pub storage_class: StorageClass,
28}
29#[derive(Debug, Deserialize)]
30#[serde(rename_all = "PascalCase")]
31pub(crate) struct Buckets {
32    pub bucket: Option<Vec<BucketBase>>,
33}
34
35// Result set of bucket list query
36#[derive(Debug, Deserialize)]
37#[serde(rename_all = "PascalCase")]
38pub(crate) struct ListAllMyBucketsResult {
39    /// If a single query does not list all buckets, next_marker can be used for the next query
40    pub next_marker: Option<String>,
41    /// Bucket list
42    pub buckets: Buckets,
43}
44
45/// Result set of bucket list query
46#[derive(Debug, Deserialize)]
47#[serde(rename_all = "PascalCase")]
48pub struct ListAllMyBuckets {
49    /// If a single query does not list all buckets, next_marker can be used for the next query
50    pub next_marker: Option<String>,
51    /// Bucket list
52    pub buckets: Option<Vec<BucketBase>>,
53}
54
55/// List buckets
56///
57/// Filters can be set via the `set_` methods. See the [Alibaba Cloud documentation](https://help.aliyun.com/document_detail/31957.html) for details
58///
59/// ```ignore
60/// let client = OssClient::new("AccessKey ID","AccessKey Secret","oss-cn-beijing.aliyuncs.com");
61/// let buckets = client.list_buckets().set_prefix("rust").send().await;
62/// println!("{:#?}", buckets);
63/// ```
64///
65pub struct ListBuckets {
66    req: OssRequest,
67}
68
69impl ListBuckets {
70    pub(super) fn new(oss: Oss) -> Self {
71        ListBuckets {
72            req: OssRequest::new(oss, Method::GET),
73        }
74    }
75
76    /// Limit the returned bucket names to those starting with prefix. Without setting, no prefix filtering is applied.
77    ///
78    /// Prefix requirements:
79    /// - Cannot be empty and must not exceed 63 bytes
80    /// - May contain only lowercase letters, numbers, and hyphens, and cannot start with a hyphen
81    ///
82    pub fn set_prefix(mut self, prefix: impl ToString) -> Self {
83        self.req.insert_query("prefix", prefix);
84        self
85    }
86    /// Start returning results from the first key alphabetically after marker. If not set, return from the beginning.
87    pub fn set_marker(mut self, marker: impl ToString) -> Self {
88        self.req.insert_query("marker", marker);
89        self
90    }
91    /// Limit the maximum number of buckets returned. Range: 1-1000, default: 100
92    pub fn set_max_keys(mut self, max_keys: u32) -> Self {
93        self.req.insert_query("max-keys", max_keys);
94        self
95    }
96    /// Specify the resource group ID
97    pub fn set_group_id(mut self, group_id: impl ToString) -> Self {
98        self.req.insert_header("x-oss-resource-group-id", group_id);
99        self
100    }
101    /// Specify the endpoint from which to initiate the query; this does not limit the region of buckets
102    ///
103    /// Defaults to oss.aliyuncs.com. If inaccessible, set an endpoint you can reach
104    pub fn set_endpoint(mut self, endpoint: impl ToString) -> Self {
105        self.req.set_endpoint(endpoint);
106        self
107    }
108    /// Send the request
109    pub async fn send(self) -> Result<ListAllMyBuckets, Error> {
110        // Build the HTTP request
111        let response = self.req.send_to_oss()?.await?;
112        // Parse the response
113        let status_code = response.status();
114        match status_code {
115            code if code.is_success() => {
116                let response_bytes = body_to_bytes(response.into_body())
117                    .await
118                    .map_err(|_| Error::OssInvalidResponse(None))?;
119                let result: ListAllMyBucketsResult = serde_xml_rs::from_reader(&*response_bytes)
120                    .map_err(|_| Error::OssInvalidResponse(Some(response_bytes)))?;
121                Ok(ListAllMyBuckets {
122                    next_marker: result.next_marker,
123                    buckets: result.buckets.bucket,
124                })
125            }
126            _ => Err(normal_error(response).await),
127        }
128    }
129}