xt_oss/oss/entities/
version.rs

1use super::{bucket::Owner, StorageClass};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct CommonPrefixes {
7    #[serde(rename = "Prefix")]
8    pub prefix: String,
9}
10
11/// 保存版本控制状态的容器
12#[derive(Debug,Clone, Serialize, Deserialize)]
13pub enum VersioningStatus {
14    /// 开启版本控制状态
15    Enabled,
16    /// 暂停版本控制状态
17    Suspended,
18}
19
20impl fmt::Display for VersioningStatus {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        write!(
23            f,
24            "{}",
25            match self {
26                Self::Enabled => "Enabled",
27                Self::Suspended => "Suspended",
28            }
29        )
30    }
31}
32
33#[derive(Debug,Clone, Serialize, Deserialize, Default)]
34pub struct VersioningConfiguration {
35    #[serde(rename = "Status", skip_serializing_if = "Option::is_none")]
36    pub status: Option<VersioningStatus>,
37}
38
39#[derive(Debug,Clone, Serialize, Deserialize, Default)]
40pub struct DeleteMarker {
41    #[serde(rename = "Key")]
42    pub key: String,
43    #[serde(rename = "VersionId")]
44    pub version_id: String,
45    #[serde(rename = "IsLatest")]
46    pub is_latest: String,
47    #[serde(rename = "LastModified")]
48    pub last_modified: String,
49    #[serde(rename = "Owner")]
50    pub owner: Owner,
51    // #[serde(rename = "Size")]
52    // pub size: Option<u64>,
53}
54
55/*
56 <DeleteMarker>
57    <Key>tmp/test.text</Key>
58    <VersionId>CAEQ2AEYgYDAo5qWtesYIiBmNjY4N2QyNjZlZjY0NjQ0YmNiMzM3YWQwNWQzN2Q2Yw--</VersionId>
59    <IsLatest>true</IsLatest>
60    <LastModified>2024-02-03T04:47:34.000Z</LastModified>
61    <Owner>
62      <ID>1508492296054765</ID>
63      <DisplayName>1508492296054765</DisplayName>
64    </Owner>
65  </DeleteMarker>
66*/
67
68#[derive(Debug, Clone, Serialize, Deserialize, Default)]
69pub struct Version {
70    #[serde(rename = "Key")]
71    pub key: String,
72    #[serde(rename = "VersionId")]
73    pub version_id: String,
74    #[serde(rename = "IsLatest")]
75    pub is_latest: bool,
76    #[serde(rename = "LastModified")]
77    pub last_modified: String,
78    #[serde(rename = "ETag", skip_serializing_if = "Option::is_none")]
79    pub etag: Option<String>,
80    #[serde(rename = "Type", skip_serializing_if = "Option::is_none")]
81    pub r#type: Option<String>,
82    #[serde(rename = "Size", skip_serializing_if = "Option::is_none")]
83    pub size: Option<u64>,
84    #[serde(rename = "StorageClass", skip_serializing_if = "Option::is_none")]
85    pub storage_class: Option<StorageClass>,
86    #[serde(rename = "Owner")]
87    pub owner: Owner,
88    #[serde(rename = "RestoreInfo")]
89    pub restore_info: Option<String>,
90}
91
92#[derive(Debug,Clone, Serialize, Deserialize)]
93pub enum Item {
94    Version(Version),
95    DeleteMarker(DeleteMarker),
96}
97
98#[derive(Debug,Clone, Serialize, Deserialize, Default)]
99pub struct ListVersionsResult {
100    #[serde(rename = "CommonPrefixes")]
101    pub common_prefixes: Option<Vec<CommonPrefixes>>,
102    #[serde(rename = "Delimiter")]
103    pub delimiter: Option<String>,
104    #[serde(rename = "EncodingType")]
105    pub encoding_type: Option<String>,
106    #[serde(rename = "IsTruncated")]
107    pub is_truncated: bool,
108    #[serde(rename = "KeyMarker")]
109    pub key_marker: String,
110    #[serde(rename = "VersionIdMarker")]
111    pub version_id_marker: Option<String>,
112    #[serde(rename = "NextKeyMarker")]
113    pub next_key_marker: Option<String>,
114    #[serde(rename = "NextVersionIdMarker")]
115    pub next_version_id_marker: Option<String>,
116    #[serde(rename = "MaxKeys")]
117    pub max_keys: u64,
118    #[serde(rename = "Name")]
119    pub name: String,
120    #[serde(rename = "Owner")]
121    pub owner: Option<Owner>,
122    #[serde(rename = "Prefix")]
123    pub prefix: String,
124    #[serde(rename = "$value", skip_serializing_if = "Option::is_none")]
125    pub items: Option<Vec<Item>>,
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131    #[test]
132    fn list_versions_result_1() {
133        let xml_content = r#"<ListVersionsResult>
134<Name>examplebucket-1250000000</Name>
135<Prefix/>
136<KeyMarker/>
137<VersionIdMarker/>
138<MaxKeys>1000</MaxKeys>
139<IsTruncated>false</IsTruncated>
140<Version>
141    <Key>example-object-1.jpg</Key>
142    <VersionId/>
143    <IsLatest>true</IsLatest>
144    <LastModified>2019-08-5T12:03:10.000Z</LastModified>
145    <ETag>5B3C1A2E053D763E1B669CC607C5A0FE1****</ETag>
146    <Size>20</Size>
147    <StorageClass>Standard</StorageClass>
148    <Owner>
149        <ID>1250000000</ID>
150        <DisplayName>1250000000</DisplayName>
151    </Owner>
152</Version>
153<Version>
154    <Key>example-object-2.jpg</Key>
155    <VersionId/>
156    <IsLatest>true</IsLatest>
157    <LastModified>2019-08-9T12:03:09.000Z</LastModified>
158    <ETag>5B3C1A2E053D763E1B002CC607C5A0FE1****</ETag>
159    <Size>20</Size>
160    <StorageClass>Standard</StorageClass>
161    <Owner>
162        <ID>1250000000</ID>
163        <DisplayName>1250000000</DisplayName>
164    </Owner>
165</Version>
166<Version>
167    <Key>example-object-3.jpg</Key>
168    <VersionId/>
169    <IsLatest>true</IsLatest>
170    <LastModified>2019-08-10T12:03:08.000Z</LastModified>
171    <ETag>4B3F1A2E053D763E1B002CC607C5AGTRF****</ETag>
172    <Size>20</Size>
173    <StorageClass>Standard</StorageClass>
174    <Owner>
175        <ID>1250000000</ID>
176        <DisplayName>1250000000</DisplayName>
177    </Owner>
178</Version>
179</ListVersionsResult>"#;
180
181        let object = quick_xml::de::from_str::<ListVersionsResult>(xml_content).unwrap();
182        assert_eq!(1000, object.max_keys);
183    }
184
185    #[test]
186    fn list_versions_result_2() {
187        let xml_content = r#"<?xml version="1.0" encoding="UTF-8"?>
188<ListVersionsResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com">
189    <Name>oss-example</Name>
190    <Prefix></Prefix>
191    <KeyMarker>example</KeyMarker>
192    <VersionIdMarker>CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1****</VersionIdMarker>
193    <MaxKeys>100</MaxKeys>
194    <Delimiter></Delimiter>
195    <IsTruncated>false</IsTruncated>
196    <DeleteMarker>
197        <Key>example</Key>
198        <VersionId>CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****</VersionId>
199        <IsLatest>false</IsLatest>
200        <LastModified>2019-04-09T07:27:28.000Z</LastModified>
201        <Owner>
202            <ID>1234512528586****</ID>
203            <DisplayName>12345125285864390</DisplayName>
204        </Owner>
205    </DeleteMarker>
206    <Version>
207        <Key>example</Key>
208        <VersionId>CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN****</VersionId>
209        <IsLatest>false</IsLatest>
210        <LastModified>2019-04-09T07:27:28.000Z</LastModified>
211        <ETag>"250F8A0AE989679A22926A875F0A2****"</ETag>
212        <Type>Normal</Type>
213        <Size>93731</Size>
214        <StorageClass>Standard</StorageClass>
215        <Owner>
216            <ID>1234512528586****</ID>
217            <DisplayName>12345125285864390</DisplayName>
218        </Owner>
219    </Version>
220    <Version>
221        <Key>pic.jpg</Key>
222        <VersionId>CAEQMxiBgMCZov2D0BYiIDY4MDllOTc2YmY5MjQxMzdiOGI3OTlhNTU0ODIx****</VersionId>
223        <IsLatest>true</IsLatest>
224        <LastModified>2019-04-09T07:27:28.000Z</LastModified>
225        <ETag>"3663F7B0B9D3153F884C821E7CF4****"</ETag>
226        <Type>Normal</Type>
227        <Size>574768</Size>
228        <StorageClass>Standard</StorageClass>
229        <Owner>
230            <ID>1234512528586****</ID>
231            <DisplayName>12345125285864390</DisplayName>
232        </Owner>
233    </Version>
234</ListVersionsResult>"#;
235
236        let object: ListVersionsResult = quick_xml::de::from_str(xml_content).unwrap();
237        let left = "CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1****";
238        let right = object.version_id_marker.unwrap();
239        assert_eq!(left, right);
240    }
241
242    #[test]
243    fn list_versions_result_3() {
244        let xml_content = r#"<ListVersionsResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com">
245<Name>oss-example</Name>
246<Prefix></Prefix>
247<KeyMarker>example</KeyMarker>
248<VersionIdMarker>CAEQMxiBgICbof2D0BYiIGRhZjgwMzJiMjA3MjQ0ODE5MWYxZDYwMzJlZjU1****</VersionIdMarker>
249<MaxKeys>100</MaxKeys>
250<Delimiter></Delimiter>
251<IsTruncated>false</IsTruncated>
252<Version>
253    <Key>exampleobject1.txt</Key>
254    <VersionId>CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****</VersionId>
255    <IsLatest>false</IsLatest>
256    <LastModified>2019-04-09T07:27:28.000Z</LastModified>
257    <Owner>
258        <ID>1234512528586****</ID>
259        <DisplayName>12345125285864390</DisplayName>
260    </Owner>
261    </Version>
262<Version>
263    <Key>exampleobject2.txt</Key>
264    <VersionId>CAEQMxiBgMDNoP2D0BYiIDE3MWUxNzgxZDQxNTRiODI5OGYwZGMwNGY3MzZjN****</VersionId>
265    <IsLatest>false</IsLatest>
266    <LastModified>2019-04-09T07:27:28.000Z</LastModified>
267    <ETag>"250F8A0AE989679A22926A875F0A2****"</ETag>
268    <Type>Normal</Type>
269    <Size>93731</Size>
270    <StorageClass>Standard</StorageClass>
271    <RestoreInfo>ongoing-request="true"</RestoreInfo>
272    <Owner>
273        <ID>1234512528586****</ID>
274        <DisplayName>12345125285864390</DisplayName>
275    </Owner>
276    </Version>
277<Version>
278    <Key>exampleobject3.txt</Key>
279    <VersionId>CAEQMxiBgMCZov2D0BYiIDY4MDllOTc2YmY5MjQxMzdiOGI3OTlhNTU0ODIx****</VersionId>
280    <IsLatest>true</IsLatest>
281    <LastModified>2019-04-09T07:27:28.000Z</LastModified>
282    <ETag>"3663F7B0B9D3153F884C821E7CF4****"</ETag>
283    <Type>Normal</Type>
284    <Size>574768</Size>
285    <StorageClass>Standard</StorageClass>
286    <RestoreInfo>ongoing-request="false", expiry-date="Thr, 24 Mon 2020 12:40:33 GMT"</RestoreInfo>
287    <Owner>
288        <ID>1234512528586****</ID>
289        <DisplayName>12345125285864390</DisplayName>
290    </Owner>
291    </Version>
292</ListVersionsResult>"#;
293
294        let object: ListVersionsResult = quick_xml::de::from_str(xml_content).unwrap();
295
296        assert_eq!("oss-example", object.name);
297    }
298
299    #[test]
300    fn list_versions_result_4() {
301        let xml_content = r#"<?xml version="1.0" encoding="UTF-8"?>
302<ListVersionsResult>
303  <Name>xuetube-dev</Name>
304  <Prefix>course/video</Prefix>
305  <KeyMarker></KeyMarker>
306  <VersionIdMarker></VersionIdMarker>
307  <MaxKeys>20</MaxKeys>
308  <Delimiter>/</Delimiter>
309  <IsTruncated>false</IsTruncated>
310  <CommonPrefixes>
311    <Prefix>course/video/</Prefix>
312  </CommonPrefixes>
313</ListVersionsResult>"#;
314
315        let obj: ListVersionsResult = quick_xml::de::from_str(&xml_content).unwrap();
316        assert_eq!("xuetube-dev", obj.name);
317    }
318
319    #[test]
320    fn list_versions_result_5() {
321        let xml_content = r#"<?xml version="1.0" encoding="UTF-8"?>
322    <ListVersionsResult>
323      <Name>xtoss-ex1</Name>
324      <Prefix></Prefix>
325      <KeyMarker></KeyMarker>
326      <VersionIdMarker></VersionIdMarker>
327      <MaxKeys>100</MaxKeys>
328      <Delimiter></Delimiter>
329      <IsTruncated>false</IsTruncated>
330      <DeleteMarker>
331        <Key>tmp/test.text</Key>
332        <VersionId>CAEQ2AEYgYDAo5qWtesYIiBmNjY4N2QyNjZlZjY0NjQ0YmNiMzM3YWQwNWQzN2Q2Yw--</VersionId>
333        <IsLatest>true</IsLatest>
334        <LastModified>2024-02-03T04:47:34.000Z</LastModified>
335        <Owner>
336          <ID>1508492296054765</ID>
337          <DisplayName>1508492296054765</DisplayName>
338        </Owner>
339      </DeleteMarker>
340      <Version>
341        <Key>tmp/test.text</Key>
342        <VersionId>CAEQ2AEYgYDAs7WTtesYIiAxOTMxYmI3OTgxNzA0ZmM3YTNkZWE5NWYyODFhYWQxOQ--</VersionId>
343        <IsLatest>false</IsLatest>
344        <LastModified>2024-02-03T04:46:03.000Z</LastModified>
345        <ETag>"C8B0FF27A844D2EECD81669DBAA544EB"</ETag>
346        <Type>Normal</Type>
347        <Size>12</Size>
348        <StorageClass>Archive</StorageClass>
349        <Owner>
350          <ID>1508492296054765</ID>
351          <DisplayName>1508492296054765</DisplayName>
352        </Owner>
353      </Version>
354      <DeleteMarker>
355        <Key>tmp/test.txt</Key>
356        <VersionId>CAEQ2AEYgYCAqMC8t.sYIiAyY2RkMWY1MTQ0NGU0ZDhjOGQ4NzFmN2JkMWM2NDk5OQ--</VersionId>
357        <IsLatest>true</IsLatest>
358        <LastModified>2024-02-03T07:28:18.000Z</LastModified>
359        <Owner>
360          <ID>1508492296054765</ID>
361          <DisplayName>1508492296054765</DisplayName>
362        </Owner>
363      </DeleteMarker>
364      <Version>
365        <Key>tmp/test.text</Key>
366        <VersionId>CAEQ2AEYgYDAuu.RtesYIiA1NTAxODRkOGE2ODk0MTNkYWFkZDJhZTMyZjZlMDEzZg--</VersionId>
367        <IsLatest>false</IsLatest>
368        <LastModified>2024-02-03T04:45:12.000Z</LastModified>
369        <ETag>"5EB63BBBE01EEED093CB22BB8F5ACDC3"</ETag>
370        <Type>Normal</Type>
371        <Size>11</Size>
372        <StorageClass>Archive</StorageClass>
373        <Owner>
374          <ID>1508492296054765</ID>
375          <DisplayName>1508492296054765</DisplayName>
376        </Owner>
377      </Version>
378      <Version>
379        <Key>tmp/test.txt</Key>
380        <VersionId>CAEQ2AEYgYCA1v6ot.sYIiBmZjU2NTQwOGEwZDc0MTMyYTU5ZjhlMmUyNGYwMjc3NA--</VersionId>
381        <IsLatest>false</IsLatest>
382        <LastModified>2024-02-03T07:17:39.000Z</LastModified>
383        <ETag>"FC3FF98E8C6A0D3087D515C0473F8677"</ETag>
384        <Type>Normal</Type>
385        <Size>12</Size>
386        <StorageClass>Archive</StorageClass>
387        <Owner>
388          <ID>1508492296054765</ID>
389          <DisplayName>1508492296054765</DisplayName>
390        </Owner>
391      </Version>
392      <Version>
393        <Key>tmp/test.txt</Key>
394        <VersionId>CAEQ2AEYgYCAur2ot.sYIiBmM2M5MDBjNDE0OWE0OGVmYTYwN2Q1OWIyMGNlZDQ3Ng--</VersionId>
395        <IsLatest>false</IsLatest>
396        <LastModified>2024-02-03T07:17:22.000Z</LastModified>
397        <ETag>"5EB63BBBE01EEED093CB22BB8F5ACDC3"</ETag>
398        <Type>Normal</Type>
399        <Size>11</Size>
400        <StorageClass>Archive</StorageClass>
401        <Owner>
402          <ID>1508492296054765</ID>
403          <DisplayName>1508492296054765</DisplayName>
404        </Owner>
405      </Version>
406      <Version>
407        <Key>tmp/test.txt</Key>
408        <VersionId>CAEQ2AEYgYDA_66nt.sYIiA5NTUzMjE0YzcwZGE0N2MyYTUxY2QxNmY1MGIxNjgzMQ--</VersionId>
409        <IsLatest>false</IsLatest>
410        <LastModified>2024-02-03T07:16:45.000Z</LastModified>
411        <ETag>"5EB63BBBE01EEED093CB22BB8F5ACDC3"</ETag>
412        <Type>Normal</Type>
413        <Size>11</Size>
414        <StorageClass>Archive</StorageClass>
415        <Owner>
416          <ID>1508492296054765</ID>
417          <DisplayName>1508492296054765</DisplayName>
418        </Owner>
419      </Version>
420      <Version>
421        <Key>tmp/test.txt</Key>
422        <VersionId>CAEQ2AEYgYDA0eOXtesYIiA3MDc1YzU3MjUwYmI0NTYwYjM2NmI4YmY5NWNjOWQxYQ--</VersionId>
423        <IsLatest>false</IsLatest>
424        <LastModified>2024-02-03T04:48:26.000Z</LastModified>
425        <ETag>"5EB63BBBE01EEED093CB22BB8F5ACDC3"</ETag>
426        <Type>Normal</Type>
427        <Size>11</Size>
428        <StorageClass>Archive</StorageClass>
429        <Owner>
430          <ID>1508492296054765</ID>
431          <DisplayName>1508492296054765</DisplayName>
432        </Owner>
433      </Version>
434      <Version>
435        <Key>tmp/test.txt</Key>
436        <VersionId>CAEQ2AEYgYDA4N2WtesYIiA4MDQ2ZjQzNDZmZTA0MjU1OTA3MjFlNjNiNmFhNDE5Yw--</VersionId>
437        <IsLatest>false</IsLatest>
438        <LastModified>2024-02-03T04:47:52.000Z</LastModified>
439        <ETag>"C8B0FF27A844D2EECD81669DBAA544EB"</ETag>
440        <Type>Normal</Type>
441        <Size>12</Size>
442        <StorageClass>Archive</StorageClass>
443        <Owner>
444          <ID>1508492296054765</ID>
445          <DisplayName>1508492296054765</DisplayName>
446        </Owner>
447      </Version>
448    </ListVersionsResult>"#;
449        let obj: ListVersionsResult = quick_xml::de::from_str(&xml_content).unwrap();
450        assert_eq!("xtoss-ex1", obj.name);
451    }
452}