mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 23:36:52 +08:00
Add list_buckets api (#1)
This commit is contained in:
parent
a7c29a57c3
commit
36a3b3c155
15
src/main.rs
15
src/main.rs
@ -2,6 +2,7 @@ mod minio;
|
|||||||
|
|
||||||
use futures::{future::Future, stream::Stream};
|
use futures::{future::Future, stream::Stream};
|
||||||
use hyper::rt;
|
use hyper::rt;
|
||||||
|
use minio::BucketInfo;
|
||||||
|
|
||||||
fn get_local_default_server() -> minio::Client {
|
fn get_local_default_server() -> minio::Client {
|
||||||
match minio::Client::new("http://localhost:9000") {
|
match minio::Client::new("http://localhost:9000") {
|
||||||
@ -48,8 +49,22 @@ fn main() {
|
|||||||
.map(|c| println!("get obj res: {:?}", c))
|
.map(|c| println!("get obj res: {:?}", c))
|
||||||
.map_err(|c| println!("err res: {:?}", c));
|
.map_err(|c| println!("err res: {:?}", c));
|
||||||
|
|
||||||
|
let list_buckets_req = c
|
||||||
|
.list_buckets()
|
||||||
|
.map(|buckets| {
|
||||||
|
println!(
|
||||||
|
"{:?}",
|
||||||
|
buckets
|
||||||
|
.iter()
|
||||||
|
.map(|bucket: &BucketInfo| bucket.name.clone())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map_err(|err| println!("{:?}", err));
|
||||||
|
|
||||||
del_req
|
del_req
|
||||||
.join5(make_bucket_req, region_req, buc_exists_req, download_req)
|
.join5(make_bucket_req, region_req, buc_exists_req, download_req)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
|
.then(|_| list_buckets_req)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/minio.rs
23
src/minio.rs
@ -20,6 +20,8 @@ use time::Tm;
|
|||||||
|
|
||||||
use types::{Err, GetObjectResp, Region};
|
use types::{Err, GetObjectResp, Region};
|
||||||
|
|
||||||
|
pub use types::BucketInfo;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Credentials {
|
pub struct Credentials {
|
||||||
access_key: String,
|
access_key: String,
|
||||||
@ -289,6 +291,27 @@ impl Client {
|
|||||||
self.signed_req_future(s3_req, xml_body_res)
|
self.signed_req_future(s3_req, xml_body_res)
|
||||||
.and_then(|_| future::ok(()))
|
.and_then(|_| future::ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_buckets(&self) -> impl Future<Item = Vec<BucketInfo>, Error = Err> {
|
||||||
|
let s3_req = S3Req {
|
||||||
|
method: Method::GET,
|
||||||
|
bucket: None,
|
||||||
|
object: None,
|
||||||
|
query: HashMap::new(),
|
||||||
|
headers: HeaderMap::new(),
|
||||||
|
body: Body::empty(),
|
||||||
|
ts: time::now_utc(),
|
||||||
|
};
|
||||||
|
self.signed_req_future(s3_req, Ok(Body::empty()))
|
||||||
|
.and_then(|resp| {
|
||||||
|
// Read the whole body for list buckets response.
|
||||||
|
resp.into_body()
|
||||||
|
.concat2()
|
||||||
|
.map_err(|err| Err::HyperErr(err))
|
||||||
|
.and_then(move |chunk| b2s(chunk.into_bytes()))
|
||||||
|
.and_then(|s| xml::parse_bucket_list(s))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_req_future(
|
fn run_req_future(
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use hyper::header::{
|
|||||||
use hyper::{body::Body, Response};
|
use hyper::{body::Body, Response};
|
||||||
use roxmltree;
|
use roxmltree;
|
||||||
use std::string;
|
use std::string;
|
||||||
|
use time::{strptime, Tm};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Region(String);
|
pub struct Region(String);
|
||||||
@ -29,11 +30,13 @@ impl Region {
|
|||||||
pub enum Err {
|
pub enum Err {
|
||||||
InvalidUrl(String),
|
InvalidUrl(String),
|
||||||
InvalidEnv(String),
|
InvalidEnv(String),
|
||||||
|
InvalidTmFmt(String),
|
||||||
HttpErr(http::Error),
|
HttpErr(http::Error),
|
||||||
HyperErr(hyper::Error),
|
HyperErr(hyper::Error),
|
||||||
FailStatusCodeErr(hyper::StatusCode, Bytes),
|
FailStatusCodeErr(hyper::StatusCode, Bytes),
|
||||||
Utf8DecodingErr(string::FromUtf8Error),
|
Utf8DecodingErr(string::FromUtf8Error),
|
||||||
XmlParseErr(roxmltree::Error),
|
XmlParseErr(roxmltree::Error),
|
||||||
|
InvalidXmlResponseErr(String),
|
||||||
MissingRequiredParams,
|
MissingRequiredParams,
|
||||||
RawSvcErr(hyper::StatusCode, Response<Body>),
|
RawSvcErr(hyper::StatusCode, Response<Body>),
|
||||||
XmlWriteErr(String),
|
XmlWriteErr(String),
|
||||||
@ -97,3 +100,22 @@ fn extract_user_meta(h: &HeaderMap) -> Vec<(String, String)> {
|
|||||||
.map(|(k, v)| (k.to_string(), v.unwrap_or("").to_string()))
|
.map(|(k, v)| (k.to_string(), v.unwrap_or("").to_string()))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BucketInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub created_time: Tm,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BucketInfo {
|
||||||
|
pub fn new(name: &str, time_str: &str) -> Result<BucketInfo, String> {
|
||||||
|
strptime(time_str, "%Y-%m-%dT%H:%M:%S.%Z")
|
||||||
|
.and_then(|ctime| {
|
||||||
|
Ok(BucketInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
created_time: ctime,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.or_else(|err| Err(format!("{:?}", err)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::minio::types::{Err, Region};
|
use crate::minio::types::{BucketInfo, Err, Region};
|
||||||
use crate::minio::woxml;
|
use crate::minio::woxml;
|
||||||
use hyper::body::Body;
|
use hyper::body::Body;
|
||||||
use roxmltree;
|
use roxmltree;
|
||||||
@ -18,6 +18,39 @@ pub fn parse_bucket_location(s: String) -> Result<Region, Err> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_bucket_list(s: String) -> Result<Vec<BucketInfo>, Err> {
|
||||||
|
let res = roxmltree::Document::parse(&s);
|
||||||
|
match res {
|
||||||
|
Ok(doc) => {
|
||||||
|
let mut bucket_infos: Vec<BucketInfo> = Vec::new();
|
||||||
|
let bucket_nodes = doc
|
||||||
|
.root_element()
|
||||||
|
.descendants()
|
||||||
|
.filter(|node| node.has_tag_name("Bucket"));
|
||||||
|
for bucket in bucket_nodes {
|
||||||
|
let bucket_names = bucket.children().filter(|node| node.has_tag_name("Name"));
|
||||||
|
let bucket_ctimes = bucket
|
||||||
|
.children()
|
||||||
|
.filter(|node| node.has_tag_name("CreationDate"));
|
||||||
|
for (name_node, ctime_node) in bucket_names.zip(bucket_ctimes) {
|
||||||
|
let name = name_node.text().ok_or(Err::InvalidXmlResponseErr(
|
||||||
|
"Missing name in list buckets XML response ".to_string(),
|
||||||
|
))?;
|
||||||
|
let ctime = ctime_node.text().ok_or(Err::InvalidXmlResponseErr(
|
||||||
|
"Missing creation date in list buckets XML response".to_string(),
|
||||||
|
))?;
|
||||||
|
match BucketInfo::new(name, ctime) {
|
||||||
|
Ok(bucket_info) => bucket_infos.push(bucket_info),
|
||||||
|
Err(err) => return Err(Err::InvalidTmFmt(format!("{:?}", err))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(bucket_infos)
|
||||||
|
}
|
||||||
|
Err(err) => Err(Err::XmlParseErr(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_mk_bucket_body() -> Result<Body, Err> {
|
pub fn get_mk_bucket_body() -> Result<Body, Err> {
|
||||||
let lc_node = woxml::XmlNode::new("LocationConstraint").text("us-east-1");
|
let lc_node = woxml::XmlNode::new("LocationConstraint").text("us-east-1");
|
||||||
let mk_bucket_xml = woxml::XmlNode::new("CreateBucketConfiguration")
|
let mk_bucket_xml = woxml::XmlNode::new("CreateBucketConfiguration")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user