1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use super::{wrap_internal_error, ReqContext, S3Handler};
use crate::dto::{ListBucketsError, ListBucketsOutput, ListBucketsRequest};
use crate::errors::{S3Error, S3Result};
use crate::output::S3Output;
use crate::storage::S3Storage;
use crate::utils::{ResponseExt, XmlWriterExt};
use crate::{async_trait, Method, Response};
pub struct Handler;
#[async_trait]
impl S3Handler for Handler {
fn is_match(&self, ctx: &'_ ReqContext<'_>) -> bool {
bool_try!(ctx.req.method() == Method::GET);
ctx.path.is_root()
}
async fn handle(
&self,
ctx: &mut ReqContext<'_>,
storage: &(dyn S3Storage + Send + Sync),
) -> S3Result<Response> {
let input = extract(ctx)?;
let output = storage.list_buckets(input).await;
output.try_into_response()
}
}
fn extract(_: &mut ReqContext<'_>) -> S3Result<ListBucketsRequest> {
Ok(ListBucketsRequest)
}
impl S3Output for ListBucketsOutput {
#[allow(clippy::shadow_unrelated)]
fn try_into_response(self) -> S3Result<Response> {
wrap_internal_error(|res| {
res.set_xml_body(4096, |w| {
w.stack("ListAllMyBucketsResult", |w| {
w.opt_stack("Buckets", self.buckets, |w, buckets| {
for bucket in buckets {
w.stack("Bucket", |w| {
w.opt_element("CreationDate", bucket.creation_date)?;
w.opt_element("Name", bucket.name)
})?;
}
Ok(())
})?;
w.opt_stack("Owner", self.owner, |w, owner| {
w.opt_element("DisplayName", owner.display_name)?;
w.opt_element("ID", owner.id)
})?;
Ok(())
})
})
})
}
}
impl From<ListBucketsError> for S3Error {
fn from(e: ListBucketsError) -> Self {
match e {}
}
}