huaweicloud_sdk_rust_obs/
bucket.rs1use std::collections::HashMap;
2
3use crate::{
4 client::Client,
5 error::{status_to_response, ObsError},
6 model::bucket::{
7 copy_object::CopyObjectResult, create_bucket::CreateBucketRequest,
8 list_bucket::ListAllMyBucketsResult, list_object::ListBucketResult,
9 location::Location,
10 },
11 object::ObjectTrait,
12};
13use reqwest::Method;
14
15#[async_trait::async_trait]
16pub trait BucketTrait {
17 async fn list_buckets(&self) -> Result<ListAllMyBucketsResult, ObsError>;
28 async fn create_bucket<S1, S2>(&self, name: S1, location: Option<S2>) -> Result<(), ObsError>
45 where
46 S1: AsRef<str> + Send,
47 S2: AsRef<str> + Send;
48
49 async fn list_objects<S1>(
68 &self,
69 name: S1,
70 prefix: Option<&str>,
71 marker: Option<&str>,
72 max_keys: Option<usize>,
73 ) -> Result<ListBucketResult, ObsError>
74 where
75 S1: AsRef<str> + Send;
76
77 async fn bucket_location<S1>(&self, name: S1) -> Result<Location, ObsError>
79 where
80 S1: AsRef<str> + Send;
81}
82
83pub struct Bucket<'a> {
84 name: &'a str,
85 client: &'a Client,
86}
87
88impl<'a> Bucket<'a> {
89 pub fn new(name: &'a str, client: &'a Client) -> Self {
90 Self { name, client }
91 }
92
93 pub async fn put_object<S>(&self, key: S, object: &[u8]) -> Result<(), ObsError>
94 where
95 S: AsRef<str> + Send,
96 {
97 self.client
98 .put_object(self.name, key.as_ref(), object)
99 .await
100 }
101
102 pub async fn copy_object<S1, S2>(&self, src: S1, dest: S2) -> Result<CopyObjectResult, ObsError>
103 where
104 S1: AsRef<str> + Send,
105 S2: AsRef<str> + Send,
106 {
107 self.client.copy_object(self.name, src, dest).await
108 }
109
110 pub async fn list_objects(
111 &self,
112 prefix: Option<&str>,
113 marker: Option<&str>,
114 max_keys: Option<usize>,
115 ) -> Result<ListBucketResult, ObsError> {
116 self.client
117 .list_objects(self.name, prefix, marker, max_keys)
118 .await
119 }
120
121 pub async fn location(&self) -> Result<Location, ObsError> {
122 self.client.bucket_location(self.name).await
123 }
124}
125
126#[async_trait::async_trait]
127impl BucketTrait for Client {
128 async fn list_buckets(&self) -> Result<ListAllMyBucketsResult, ObsError> {
129 let resp = self
130 .do_action_without_bucket_name(Method::GET, "", None, None, None::<String>)
131 .await?;
132 let status = resp.status();
133 let text = resp.text().await?;
134 status_to_response::<ListAllMyBucketsResult>(status, text)
135 }
136
137 async fn create_bucket<S1, S2>(&self, name: S1, location: Option<S2>) -> Result<(), ObsError>
138 where
139 S1: AsRef<str> + Send,
140 S2: AsRef<str> + Send,
141 {
142 let body = if let Some(loc) = location {
143 let xml = CreateBucketRequest::new(loc.as_ref());
144 serde_xml_rs::to_string(&xml)?
145 } else {
146 String::new()
147 };
148
149 let _res = self
150 .do_action(Method::PUT, name, "", None, None, Some(body))
151 .await?;
152
153 Ok(())
154 }
155
156 async fn list_objects<S1>(
157 &self,
158 name: S1,
159 prefix: Option<&str>,
160 marker: Option<&str>,
161 max_keys: Option<usize>,
162 ) -> Result<ListBucketResult, ObsError>
163 where
164 S1: AsRef<str> + Send,
165 {
166 let mut params = HashMap::new();
167 params.insert("delimiter".into(), "/".to_string());
168
169 if let Some(m) = marker {
170 params.insert("marker".into(), m.into());
171 }
172
173 if let Some(mk) = max_keys {
174 params.insert("max-keys".into(), mk.to_string());
175 }
176
177 if let Some(p) = prefix {
178 params.insert("prefix".into(), p.into());
179 }
180
181 let resp = self
182 .do_action(Method::GET, name, "", None, Some(params), None::<String>)
183 .await?;
184 let status = resp.status();
185 let text = resp.text().await?;
186 status_to_response::<ListBucketResult>(status, text)
188 }
189
190 async fn bucket_location<S1>(&self, name: S1) -> Result<Location, ObsError>
191 where
192 S1: AsRef<str> + Send,
193 {
194 let mut params = HashMap::new();
195 params.insert("location".to_string(), "".to_string());
196
197 let resp = self
198 .do_action(
199 Method::GET,
200 name,
201 "",
202 None,
203 Some(params),
204 None::<String>,
205 )
206 .await?;
207 let status = resp.status();
208 let text = resp.text().await?;
209
210 status_to_response::<Location>(status, text)
211 }
212}