xt_oss/oss/entities/
bucket.rs

1use super::{acl::AccessControlList, object::Object, oss, DataRedundancyType, StorageClass};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Default, Clone)]
5pub struct CreateBucketConfiguration {
6    #[serde(rename = "StorageClass", skip_serializing_if = "Option::is_none")]
7    pub storage_class: Option<StorageClass>,
8    #[serde(
9        rename = "data_redundancy_type",
10        skip_serializing_if = "Option::is_none"
11    )]
12    pub data_redundancy_type: Option<DataRedundancyType>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize, Default)]
16pub struct Owner {
17    #[serde(rename = "ID")]
18    pub id: String,
19    #[serde(rename = "DisplayName")]
20    pub display_name: String,
21}
22
23/// Bucket所在的地域
24#[derive(Debug, Serialize, Deserialize, Clone)]
25#[serde(rename = "$value")]
26pub struct LocationConstraint(pub String);
27
28#[derive(Debug, Serialize, Deserialize, Default, Clone)]
29pub struct BucketPolicy {
30    #[serde(rename(deserialize = "LogBucket"))]
31    pub log_bucket: String,
32    #[serde(rename(deserialize = "LogPrefix"))]
33    pub log_prefix: String,
34}
35
36#[derive(Debug, Serialize, Deserialize, Default, Clone)]
37pub struct Bucket {
38    #[serde(rename = "AccessMonitor")]
39    pub access_monitor: Option<String>,
40    #[serde(rename = "CreationDate")]
41    pub creation_date: String,
42    #[serde(rename = "ExtranetEndpoint")]
43    pub extranet_endpoint: String,
44    #[serde(rename = "IntranetEndpoint")]
45    pub intranet_endpoint: String,
46    #[serde(rename = "Location")]
47    pub location: String,
48    #[serde(rename = "StorageClass")]
49    pub storage_class: StorageClass,
50    #[serde(rename = "TransferAcceleration")]
51    pub transfer_acceleration: Option<String>,
52    #[serde(rename = "CrossRegionReplication")]
53    pub cross_region_replication: Option<String>,
54    #[serde(rename = "Name")]
55    pub name: String,
56    #[serde(rename = "ResourceGroupId")]
57    pub resource_group_id: Option<String>,
58    #[serde(rename = "Owner")]
59    pub owner: Option<Owner>,
60    #[serde(rename = "AccessControlList")]
61    pub access_control_list: Option<AccessControlList>,
62    #[serde(rename = "Comment")]
63    pub comment: Option<String>,
64    #[serde(rename = "BucketPolicy")]
65    pub bucket_policy: Option<BucketPolicy>,
66}
67
68#[derive(Debug, Serialize, Deserialize, Default, Clone)]
69pub struct BucketInfo {
70    #[serde(rename(deserialize = "Bucket"))]
71    pub bucket: Bucket,
72}
73
74#[derive(Debug, Serialize, Deserialize, Default, Clone)]
75pub struct Buckets {
76    #[serde(rename(deserialize = "Bucket"))]
77    pub bucket: Option<Vec<Bucket>>,
78}
79
80#[derive(Debug, Serialize, Deserialize, Default, Clone)]
81pub struct ListAllMyBucketsResult {
82    #[serde(rename(deserialize = "Owner"))]
83    pub owner: Owner,
84    #[serde(rename(deserialize = "Buckets"))]
85    pub buckets: Buckets,
86}
87
88impl From<oss::Bytes> for ListAllMyBucketsResult {
89    fn from(data: oss::Bytes) -> Self {
90        let content = String::from_utf8_lossy(&data);
91        quick_xml::de::from_str::<Self>(&content).unwrap()
92    }
93}
94
95#[derive(Debug, Default, Serialize, Deserialize, Clone)]
96pub struct BucketStat {
97    /// Bucket的总存储量,单位字节。
98    #[serde(rename(deserialize = "Storage"))]
99    pub storage: u64,
100    /// Bucket中总的Object数量
101    #[serde(rename(deserialize = "ObjectCount"))]
102    pub object_count: u64,
103    #[serde(rename(deserialize = "MultipartUploadCount"))]
104    pub multipart_upload_count: u64,
105    #[serde(rename(deserialize = "LiveChannelCount"))]
106    pub live_channel_count: u64,
107    #[serde(rename(deserialize = "LastModifiedTime"))]
108    pub last_modified_time: u64,
109    #[serde(rename(deserialize = "StandardStorage"))]
110    pub standard_storage: u64,
111    #[serde(rename(deserialize = "StandardObjectCount"))]
112    pub standard_object_count: u64,
113    #[serde(rename(deserialize = "InfrequentAccessStorage"))]
114    pub infrequent_access_storage: u64,
115    #[serde(rename(deserialize = "InfrequentAccessRealStorage"))]
116    pub infrequent_access_real_storage: u64,
117    #[serde(rename(deserialize = "InfrequentAccessObjectCount"))]
118    pub infrequent_access_object_count: u64,
119    #[serde(rename(deserialize = "ArchiveStorage"))]
120    pub archive_storage: u64,
121    #[serde(rename(deserialize = "ArchiveRealStorage"))]
122    pub archive_real_storage: u64,
123    #[serde(rename(deserialize = "ArchiveObjectCount"))]
124    pub archive_object_count: u64,
125    #[serde(rename(deserialize = "ColdArchiveStorage"))]
126    pub cold_archive_storage: u64,
127    #[serde(rename(deserialize = "ColdArchiveRealStorage"))]
128    pub cold_archive_real_storage: u64,
129    #[serde(rename(deserialize = "ColdArchiveObjectCount"))]
130    pub cold_archive_object_count: u64,
131}
132
133#[derive(Debug, Serialize, Deserialize, Clone)]
134pub struct ListBucketResult2 {
135    #[serde(rename = "Name")]
136    pub name: String,
137    #[serde(rename = "Prefix")]
138    pub prefix: String,
139    #[serde(rename = "MaxKeys")]
140    pub max_keys: i32,
141    #[serde(rename = "EncodingType")]
142    pub encoding_type: Option<String>,
143    #[serde(rename = "IsTruncated")]
144    pub is_truncated: bool,
145    #[serde(rename = "KeyCount")]
146    pub key_count: Option<u32>,
147    #[serde(rename = "NextContinuationToken")]
148    pub next_continuation_token: Option<String>,
149    #[serde(rename = "Contents")]
150    pub contents: Option<Vec<Object>>,
151    #[serde(rename = "CommonPrefixes")]
152    pub common_prefixes: Option<Vec<CommonPrefixes>>
153}
154
155#[derive(Debug, Serialize, Deserialize, Clone, Default)]
156pub struct CommonPrefixes {
157    #[serde(rename = "Prefix")]
158    pub prefix: String,
159}
160
161#[derive(Debug, Serialize, Deserialize, Clone)]
162pub struct Contents {
163    #[serde(rename = "Key")]
164    pub key: String,
165    #[serde(rename = "LastModified")]
166    pub last_modified: String,
167    #[serde(rename = "ETag")]
168    pub etag: String,
169    #[serde(rename = "Type")]
170    pub r#type: String,
171    #[serde(rename = "Size")]
172    pub size: i32,
173    #[serde(rename = "StorageClass")]
174    pub storage_class: StorageClass,
175    #[serde(rename = "Owner")]
176    pub owner: Option<Owner>,
177}
178
179#[derive(Debug, Serialize, Deserialize, Clone)]
180pub struct ListBucketResult {
181    #[serde(rename = "Name")]
182    pub name: String,
183    #[serde(rename = "Prefix")]
184    pub prefix: String,
185    #[serde(rename = "Marker")]
186    pub marker: String,
187    #[serde(rename = "MaxKeys")]
188    pub max_keys: i32,
189    #[serde(rename = "Delimiter")]
190    pub delimiter: String,
191    #[serde(rename = "IsTruncated")]
192    pub is_truncated: bool,
193    #[serde(rename = "NextMarker")]
194    pub next_marker: Option<String>,
195    #[serde(rename = "Contents")]
196    pub contents: Option<Vec<Contents>>,
197    #[serde(rename = "CommonPrefixes")]
198    pub common_prefixes: Option<Vec<CommonPrefixes>>,
199}
200
201#[cfg(test)]
202pub mod test {
203
204    use super::*;
205
206    #[test]
207    fn bucket() {
208        // include!()
209        let xml = r#"
210<ListAllMyBucketsResult>
211<Owner>
212    <ID>512**</ID>
213    <DisplayName>51264</DisplayName>
214</Owner>
215<Buckets>
216    <Bucket>
217        <CreationDate>2014-02-17T18:12:43.000Z</CreationDate>
218        <ExtranetEndpoint>oss-cn-shanghai.aliyuncs.com</ExtranetEndpoint>
219        <IntranetEndpoint>oss-cn-shanghai-internal.aliyuncs.com</IntranetEndpoint>
220        <Location>oss-cn-shanghai</Location>
221        <Name>app-base-oss</Name>
222        <Region>cn-shanghai</Region>
223        <StorageClass>Standard</StorageClass>
224    </Bucket>
225    <Bucket>
226        <CreationDate>2014-02-25T11:21:04.000Z</CreationDate>
227        <ExtranetEndpoint>oss-cn-hangzhou.aliyuncs.com</ExtranetEndpoint>
228        <IntranetEndpoint>oss-cn-hangzhou-internal.aliyuncs.com</IntranetEndpoint>
229        <Location>oss-cn-hangzhou</Location>
230        <Name>mybucket</Name>
231        <Region>cn-hangzhou</Region>
232        <StorageClass>IA</StorageClass>
233    </Bucket>
234</Buckets>
235</ListAllMyBucketsResult>
236"#;
237        let obj: ListAllMyBucketsResult = quick_xml::de::from_str(xml).unwrap();
238        let left = "2014-02-17T18:12:43.000Z";
239        let right = &obj.buckets.bucket.unwrap()[0].creation_date;
240        assert_eq!(left, right);
241    }
242
243    #[test]
244    pub fn list_object_v2() {
245        let xml_content = r#"<?xml version="1.0" encoding="UTF-8"?>
246    <ListBucketResult>
247      <Name>xtoss-ex11</Name>
248      <Prefix></Prefix>
249      <MaxKeys>5</MaxKeys>
250      <Delimiter></Delimiter>
251      <IsTruncated>true</IsTruncated>
252      <NextContinuationToken>ChlpbWFnZXMvSlBHSW1hZ2VfMm1ibWIuanBnEAA-</NextContinuationToken>
253      <Contents>
254        <Key>excel/Spreadsheet-1000-rows.xls</Key>
255        <LastModified>2024-02-09T12:11:40.000Z</LastModified>
256        <ETag>"B6DF06A19E3A3AF4F39EBD2E14C64F28"</ETag>
257        <Type>Normal</Type>
258        <Size>217088</Size>
259        <StorageClass>Standard</StorageClass>
260      </Contents>
261      <Contents>
262        <Key>excel/Spreadsheet-5000-rows.xls</Key>
263        <LastModified>2024-02-09T12:11:39.000Z</LastModified>
264        <ETag>"F97C47A00070BC0B945268A26FC8C14A"</ETag>
265        <Type>Normal</Type>
266        <Size>925696</Size>
267        <StorageClass>Standard</StorageClass>
268      </Contents>
269      <Contents>
270        <Key>images/JPGImage_100kbmb.jpg</Key>
271        <LastModified>2024-02-09T12:11:39.000Z</LastModified>
272        <ETag>"12EA14D362611F6CCAB9C66CA0A3FAEF"</ETag>
273        <Type>Normal</Type>
274        <Size>102796</Size>
275        <StorageClass>Standard</StorageClass>
276      </Contents>
277      <Contents>
278        <Key>images/JPGImage_15mbmb.jpg</Key>
279        <LastModified>2024-02-09T12:11:31.000Z</LastModified>
280        <ETag>"AD9D4461988B2D82D53F0DA31CAFEAA5"</ETag>
281        <Type>Normal</Type>
282        <Size>15882755</Size>
283        <StorageClass>Standard</StorageClass>
284      </Contents>
285      <Contents>
286        <Key>images/JPGImage_2mbmb.jpg</Key>
287        <LastModified>2024-02-09T12:11:39.000Z</LastModified>
288        <ETag>"EA5EFC10C2873F1713FDB368E4D25DD7"</ETag>
289        <Type>Normal</Type>
290        <Size>2101546</Size>
291        <StorageClass>Standard</StorageClass>
292      </Contents>
293      <KeyCount>5</KeyCount>
294    </ListBucketResult>"#;
295
296        let entity: ListBucketResult2 = quick_xml::de::from_str(&xml_content).unwrap();
297        let left = "excel/Spreadsheet-1000-rows.xls";
298        let right = &entity.contents.unwrap()[0].key;
299        assert_eq!(&left, &right);
300    }
301}