mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 15:26:51 +08:00
Add builders for bucket methods: (#76)
- list buckets - get bucket versioning
This commit is contained in:
parent
6a34d4c677
commit
35954da61d
@ -301,27 +301,6 @@ impl<'a> MakeBucketArgs<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Argument for [list_buckets()](crate::s3::client::Client::list_buckets) API
|
||||
pub struct ListBucketsArgs<'a> {
|
||||
pub extra_headers: Option<&'a Multimap>,
|
||||
pub extra_query_params: Option<&'a Multimap>,
|
||||
}
|
||||
|
||||
impl<'a> ListBucketsArgs<'a> {
|
||||
/// Returns argument for [list_buckets()](crate::s3::client::Client::list_buckets) API
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use minio::s3::args::*;
|
||||
/// let args = ListBucketsArgs::new();
|
||||
/// ```
|
||||
pub fn new() -> ListBucketsArgs<'a> {
|
||||
ListBucketsArgs::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Argument for [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload) API
|
||||
pub struct AbortMultipartUploadArgs<'a> {
|
||||
@ -1767,9 +1746,6 @@ impl<'a> SetBucketTagsArgs<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Argument for [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning) API
|
||||
pub type GetBucketVersioningArgs<'a> = BucketArgs<'a>;
|
||||
|
||||
/// Argument for [set_bucket_versioning()](crate::s3::client::Client::set_bucket_versioning) API
|
||||
pub struct SetBucketVersioningArgs<'a> {
|
||||
pub extra_headers: Option<&'a Multimap>,
|
||||
|
||||
@ -12,8 +12,10 @@
|
||||
|
||||
//! Argument builders for [minio::s3::client::Client](crate::s3::client::Client) APIs
|
||||
|
||||
mod buckets;
|
||||
mod list_objects;
|
||||
mod listen_bucket_notification;
|
||||
|
||||
pub use buckets::*;
|
||||
pub use list_objects::*;
|
||||
pub use listen_bucket_notification::*;
|
||||
|
||||
140
src/s3/builders/buckets.rs
Normal file
140
src/s3/builders/buckets.rs
Normal file
@ -0,0 +1,140 @@
|
||||
use http::Method;
|
||||
|
||||
use crate::s3::{
|
||||
client::Client,
|
||||
error::Error,
|
||||
response::{GetBucketVersioningResponse, ListBucketsResponse},
|
||||
types::{S3Api, S3Request, ToS3Request},
|
||||
utils::{check_bucket_name, merge, Multimap},
|
||||
};
|
||||
|
||||
/// Argument builder for
|
||||
/// [list_buckets()](crate::s3::client::Client::list_buckets) API.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ListBuckets {
|
||||
client: Option<Client>,
|
||||
|
||||
extra_headers: Option<Multimap>,
|
||||
extra_query_params: Option<Multimap>,
|
||||
}
|
||||
|
||||
impl S3Api for ListBuckets {
|
||||
type S3Response = ListBucketsResponse;
|
||||
}
|
||||
|
||||
impl ToS3Request for ListBuckets {
|
||||
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||
let mut headers = Multimap::new();
|
||||
if let Some(v) = &self.extra_headers {
|
||||
headers = v.clone();
|
||||
}
|
||||
let mut query_params = Multimap::new();
|
||||
if let Some(v) = &self.extra_query_params {
|
||||
query_params = v.clone();
|
||||
}
|
||||
|
||||
let req = S3Request::new(
|
||||
self.client.as_ref().ok_or(Error::NoClientProvided)?,
|
||||
Method::GET,
|
||||
)
|
||||
.query_params(query_params)
|
||||
.headers(headers);
|
||||
Ok(req)
|
||||
}
|
||||
}
|
||||
|
||||
impl ListBuckets {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn client(mut self, client: &Client) -> Self {
|
||||
self.client = Some(client.clone());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self {
|
||||
self.extra_headers = extra_headers;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self {
|
||||
self.extra_query_params = extra_query_params;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct BucketCommon {
|
||||
client: Option<Client>,
|
||||
|
||||
extra_headers: Option<Multimap>,
|
||||
extra_query_params: Option<Multimap>,
|
||||
region: Option<String>,
|
||||
bucket: String,
|
||||
}
|
||||
|
||||
impl BucketCommon {
|
||||
pub fn new(bucket_name: &str) -> Self {
|
||||
BucketCommon {
|
||||
bucket: bucket_name.to_owned(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client(mut self, client: &Client) -> Self {
|
||||
self.client = Some(client.clone());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self {
|
||||
self.extra_headers = extra_headers;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self {
|
||||
self.extra_query_params = extra_query_params;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn region(mut self, region: Option<String>) -> Self {
|
||||
self.region = region;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Argument builder for
|
||||
/// [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning)
|
||||
/// API
|
||||
pub type GetBucketVersioning = BucketCommon;
|
||||
|
||||
impl S3Api for GetBucketVersioning {
|
||||
type S3Response = GetBucketVersioningResponse;
|
||||
}
|
||||
|
||||
impl ToS3Request for GetBucketVersioning {
|
||||
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||
check_bucket_name(&self.bucket, true)?;
|
||||
|
||||
let mut headers = Multimap::new();
|
||||
if let Some(v) = &self.extra_headers {
|
||||
merge(&mut headers, v);
|
||||
}
|
||||
|
||||
let mut query_params = Multimap::new();
|
||||
if let Some(v) = &self.extra_query_params {
|
||||
merge(&mut query_params, v);
|
||||
}
|
||||
query_params.insert(String::from("versioning"), String::new());
|
||||
|
||||
let req = S3Request::new(
|
||||
self.client.as_ref().ok_or(Error::NoClientProvided)?,
|
||||
Method::GET,
|
||||
)
|
||||
.region(self.region.as_deref())
|
||||
.bucket(Some(&self.bucket))
|
||||
.query_params(query_params)
|
||||
.headers(headers);
|
||||
Ok(req)
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@ use crate::s3::response::*;
|
||||
use crate::s3::signer::{presign_v4, sign_v4_s3};
|
||||
use crate::s3::sse::SseCustomerKey;
|
||||
use crate::s3::types::{
|
||||
Bucket, DeleteObject, Directive, LifecycleConfig, NotificationConfig, ObjectLockConfig, Part,
|
||||
DeleteObject, Directive, LifecycleConfig, NotificationConfig, ObjectLockConfig, Part,
|
||||
ReplicationConfig, RetentionMode, SseConfig,
|
||||
};
|
||||
use crate::s3::utils::{
|
||||
@ -46,6 +46,8 @@ use xmltree::Element;
|
||||
mod list_objects;
|
||||
mod listen_bucket_notification;
|
||||
|
||||
use super::builders::{GetBucketVersioning, ListBuckets};
|
||||
|
||||
/// Client Builder manufactures a Client using given parameters.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClientBuilder {
|
||||
@ -1846,46 +1848,8 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_bucket_versioning(
|
||||
&self,
|
||||
args: &GetBucketVersioningArgs<'_>,
|
||||
) -> Result<GetBucketVersioningResponse, Error> {
|
||||
let region = self.get_region(args.bucket, args.region).await?;
|
||||
|
||||
let mut headers = Multimap::new();
|
||||
if let Some(v) = &args.extra_headers {
|
||||
merge(&mut headers, v);
|
||||
}
|
||||
|
||||
let mut query_params = Multimap::new();
|
||||
if let Some(v) = &args.extra_query_params {
|
||||
merge(&mut query_params, v);
|
||||
}
|
||||
query_params.insert(String::from("versioning"), String::new());
|
||||
|
||||
let resp = self
|
||||
.execute(
|
||||
Method::GET,
|
||||
®ion,
|
||||
&mut headers,
|
||||
&query_params,
|
||||
Some(args.bucket),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let header_map = resp.headers().clone();
|
||||
let body = resp.bytes().await?;
|
||||
let root = Element::parse(body.reader())?;
|
||||
|
||||
Ok(GetBucketVersioningResponse {
|
||||
headers: header_map.clone(),
|
||||
region: region.clone(),
|
||||
bucket_name: args.bucket.to_string(),
|
||||
status: get_option_text(&root, "Status").map(|v| v == "Enabled"),
|
||||
mfa_delete: get_option_text(&root, "MFADelete").map(|v| v == "Enabled"),
|
||||
})
|
||||
pub fn get_bucket_versioning(&self, bucket: &str) -> GetBucketVersioning {
|
||||
GetBucketVersioning::new(bucket).client(self)
|
||||
}
|
||||
|
||||
pub async fn get_object(&self, args: &GetObjectArgs<'_>) -> Result<reqwest::Response, Error> {
|
||||
@ -2230,49 +2194,8 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_buckets(
|
||||
&self,
|
||||
args: &ListBucketsArgs<'_>,
|
||||
) -> Result<ListBucketsResponse, Error> {
|
||||
let mut headers = Multimap::new();
|
||||
if let Some(v) = &args.extra_headers {
|
||||
merge(&mut headers, v);
|
||||
}
|
||||
let mut query_params = &Multimap::new();
|
||||
if let Some(v) = &args.extra_query_params {
|
||||
query_params = v;
|
||||
}
|
||||
let resp = self
|
||||
.execute(
|
||||
Method::GET,
|
||||
&String::from("us-east-1"),
|
||||
&mut headers,
|
||||
query_params,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let header_map = resp.headers().clone();
|
||||
let body = resp.bytes().await?;
|
||||
let mut root = Element::parse(body.reader())?;
|
||||
let buckets = root
|
||||
.get_mut_child("Buckets")
|
||||
.ok_or(Error::XmlError(String::from("<Buckets> tag not found")))?;
|
||||
|
||||
let mut bucket_list: Vec<Bucket> = Vec::new();
|
||||
while let Some(b) = buckets.take_child("Bucket") {
|
||||
let bucket = b;
|
||||
bucket_list.push(Bucket {
|
||||
name: get_text(&bucket, "Name")?,
|
||||
creation_date: from_iso8601utc(&get_text(&bucket, "CreationDate")?)?,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(ListBucketsResponse {
|
||||
headers: header_map.clone(),
|
||||
buckets: bucket_list,
|
||||
})
|
||||
pub fn list_buckets(&self) -> ListBuckets {
|
||||
ListBuckets::new().client(self)
|
||||
}
|
||||
|
||||
pub async fn make_bucket(
|
||||
|
||||
@ -24,28 +24,23 @@ use xmltree::Element;
|
||||
|
||||
use crate::s3::error::Error;
|
||||
use crate::s3::types::{
|
||||
parse_legal_hold, Bucket, LifecycleConfig, NotificationConfig, ObjectLockConfig,
|
||||
ReplicationConfig, RetentionMode, SelectProgress, SseConfig,
|
||||
parse_legal_hold, LifecycleConfig, NotificationConfig, ObjectLockConfig, ReplicationConfig,
|
||||
RetentionMode, SelectProgress, SseConfig,
|
||||
};
|
||||
use crate::s3::utils::{
|
||||
copy_slice, crc32, from_http_header_value, from_iso8601utc, get_text, uint32, UtcTime,
|
||||
};
|
||||
|
||||
mod buckets;
|
||||
mod list_objects;
|
||||
mod listen_bucket_notification;
|
||||
|
||||
pub use buckets::{GetBucketVersioningResponse, ListBucketsResponse};
|
||||
pub use list_objects::{
|
||||
ListObjectVersionsResponse, ListObjectsResponse, ListObjectsV1Response, ListObjectsV2Response,
|
||||
};
|
||||
pub use listen_bucket_notification::ListenBucketNotificationResponse;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Response of [list_buckets()](crate::s3::client::Client::list_buckets) API
|
||||
pub struct ListBucketsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub buckets: Vec<Bucket>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Base response for bucket operation
|
||||
pub struct BucketResponse {
|
||||
@ -675,16 +670,6 @@ pub struct GetBucketTagsResponse {
|
||||
/// Response of [set_bucket_tags()](crate::s3::client::Client::set_bucket_tags) API
|
||||
pub type SetBucketTagsResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning) API
|
||||
pub struct GetBucketVersioningResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
pub bucket_name: String,
|
||||
pub status: Option<bool>,
|
||||
pub mfa_delete: Option<bool>,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_versioning()](crate::s3::client::Client::set_bucket_versioning) API
|
||||
pub type SetBucketVersioningResponse = BucketResponse;
|
||||
|
||||
|
||||
78
src/s3/response/buckets.rs
Normal file
78
src/s3/response/buckets.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use async_trait::async_trait;
|
||||
use bytes::Buf;
|
||||
use http::HeaderMap;
|
||||
use xmltree::Element;
|
||||
|
||||
use crate::s3::{
|
||||
error::Error,
|
||||
types::{Bucket, FromS3Response, S3Request},
|
||||
utils::{from_iso8601utc, get_option_text, get_text},
|
||||
};
|
||||
|
||||
/// Response of [list_buckets()](crate::s3::client::Client::list_buckets) API
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ListBucketsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub buckets: Vec<Bucket>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl FromS3Response for ListBucketsResponse {
|
||||
async fn from_s3response<'a>(
|
||||
_req: S3Request<'a>,
|
||||
resp: reqwest::Response,
|
||||
) -> Result<Self, Error> {
|
||||
let header_map = resp.headers().clone();
|
||||
let body = resp.bytes().await?;
|
||||
let mut root = Element::parse(body.reader())?;
|
||||
let buckets = root
|
||||
.get_mut_child("Buckets")
|
||||
.ok_or(Error::XmlError(String::from("<Buckets> tag not found")))?;
|
||||
|
||||
let mut bucket_list: Vec<Bucket> = Vec::new();
|
||||
while let Some(b) = buckets.take_child("Bucket") {
|
||||
let bucket = b;
|
||||
bucket_list.push(Bucket {
|
||||
name: get_text(&bucket, "Name")?,
|
||||
creation_date: from_iso8601utc(&get_text(&bucket, "CreationDate")?)?,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(ListBucketsResponse {
|
||||
headers: header_map.clone(),
|
||||
buckets: bucket_list,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Response of
|
||||
/// [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning)
|
||||
/// API
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GetBucketVersioningResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
pub bucket: String,
|
||||
pub status: Option<bool>,
|
||||
pub mfa_delete: Option<bool>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl FromS3Response for GetBucketVersioningResponse {
|
||||
async fn from_s3response<'a>(
|
||||
req: S3Request<'a>,
|
||||
resp: reqwest::Response,
|
||||
) -> Result<Self, Error> {
|
||||
let headers = resp.headers().clone();
|
||||
let body = resp.bytes().await?;
|
||||
let root = Element::parse(body.reader())?;
|
||||
|
||||
Ok(GetBucketVersioningResponse {
|
||||
headers,
|
||||
region: req.get_computed_region(),
|
||||
bucket: req.bucket.unwrap().to_string(),
|
||||
status: get_option_text(&root, "Status").map(|v| v == "Enabled"),
|
||||
mfa_delete: get_option_text(&root, "MFADelete").map(|v| v == "Enabled"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -163,11 +163,7 @@ impl ClientTest {
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
let resp = self
|
||||
.client
|
||||
.list_buckets(&ListBucketsArgs::new())
|
||||
.await
|
||||
.unwrap();
|
||||
let resp = self.client.list_buckets().send().await.unwrap();
|
||||
for bucket in resp.buckets.iter() {
|
||||
if names.contains(&bucket.name) {
|
||||
count += 1;
|
||||
@ -1016,7 +1012,8 @@ impl ClientTest {
|
||||
|
||||
let resp = self
|
||||
.client
|
||||
.get_bucket_versioning(&GetBucketVersioningArgs::new(&bucket_name).unwrap())
|
||||
.get_bucket_versioning(&bucket_name)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(match resp.status {
|
||||
@ -1031,7 +1028,8 @@ impl ClientTest {
|
||||
|
||||
let resp = self
|
||||
.client
|
||||
.get_bucket_versioning(&GetBucketVersioningArgs::new(&bucket_name).unwrap())
|
||||
.get_bucket_versioning(&bucket_name)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user