use std::collections::HashMap;
use reqwest::header::{HeaderMap, DATE};
use quick_xml::{Reader, events::Event};
use super::oss::OSS;
use super::auth::*;
use super::errors::Error;
#[derive(Clone, Debug)]
pub struct ListBuckets {
prefix: String,
marker: String,
max_keys: String,
is_truncated: bool,
next_marker: String,
id: String,
display_name: String,
buckets: Vec<Bucket>
}
impl ListBuckets {
pub fn new(
prefix: String,
marker: String,
max_keys: String,
is_truncated: bool,
next_marker: String,
id: String,
display_name: String,
buckets: Vec<Bucket>
) -> Self {
ListBuckets {
prefix,
marker,
max_keys,
is_truncated,
next_marker,
id,
display_name,
buckets
}
}
pub fn prefix(&self) -> &str {
&self.prefix
}
pub fn marker(&self) -> &str {
&self.marker
}
pub fn max_keys(&self) -> &str {
&self.max_keys
}
pub fn is_truncated(&self) -> bool {
self.is_truncated
}
pub fn next_marker(&self) -> &str {
&self.next_marker
}
pub fn id(&self) -> &str {
&self.id
}
pub fn display_name(&self) -> &str {
&self.display_name
}
pub fn buckets(&self) -> &Vec<Bucket> {
&self.buckets
}
}
#[derive(Clone, Debug)]
pub struct Bucket {
name: String,
create_date: String,
location: String,
extranet_endpoint: String,
intranet_endpoint: String,
storage_class: String,
}
impl Bucket {
pub fn new(
name: String,
create_date: String,
location: String,
extranet_endpoint: String,
intranet_endpoint: String,
storage_class: String,
) -> Self {
Bucket {
name,
create_date,
location,
extranet_endpoint,
intranet_endpoint,
storage_class,
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn create_data(&self) -> &str {
&self.create_date
}
pub fn location(&self) -> &str {
&self.location
}
pub fn extranet_endpoint(&self) -> &str {
&self.extranet_endpoint
}
pub fn intranet_endpoint(&self) -> &str {
&self.intranet_endpoint
}
pub fn storage_class(&self) -> &str {
&self.storage_class
}
}
pub trait ServiceAPI {
fn list_bucket(
&self,
resources: Option<HashMap<String, Option<String>>>,
) -> Result<ListBuckets, Error>;
}
impl<'a> ServiceAPI for OSS<'a> {
fn list_bucket(
&self,
resources: Option<HashMap<String, Option<String>>>,
) -> Result<ListBuckets, Error> {
let resources_str = if let Some(r) = resources {
self.get_resources_str(r)
} else {
String::new()
};
let host = self.endpoint();
let date = self.date();
let mut headers = HeaderMap::new();
headers.insert(DATE, date.parse()?);
let authorization = self.oss_sign(
"GET",
self.key_id(),
self.key_secret(),
"",
"",
&resources_str,
&headers,
);
headers.insert("Authorization", authorization.parse()?);
let mut resp = self.client.get(host).headers(headers).send()?;
let xml_str = resp.text()?;
let mut result = Vec::new();
let mut reader = Reader::from_str(xml_str.as_str());
reader.trim_text(true);
let mut buf = Vec::new();
let mut prefix = String::new();
let mut marker = String::new();
let mut max_keys = String::new();
let mut is_truncated = false;
let mut next_marker = String::new();
let mut id = String::new();
let mut display_name = String::new();
let mut name = String::new();
let mut location = String::new();
let mut create_date = String::new();
let mut extranet_endpoint = String::new();
let mut intranet_endpoint = String::new();
let mut storage_class = String::new();
let list_buckets;
loop {
match reader.read_event(&mut buf) {
Ok(Event::Start(ref e)) => match e.name() {
b"Prefix" => prefix = reader.read_text(e.name(), &mut Vec::new())?,
b"Marker" => marker = reader.read_text(e.name(), &mut Vec::new())?,
b"MaxKeys" => max_keys = reader.read_text(e.name(), &mut Vec::new())?,
b"IsTruncated" => is_truncated = reader.read_text(e.name(), &mut Vec::new())? == "true",
b"NextMarker" => next_marker = reader.read_text(e.name(), &mut Vec::new())?,
b"ID" => id = reader.read_text(e.name(), &mut Vec::new())?,
b"DisplayName" => display_name = reader.read_text(e.name(), &mut Vec::new())?,
b"Bucket" => {
name = String::new();
location = String::new();
create_date = String::new();
extranet_endpoint = String::new();
intranet_endpoint = String::new();
storage_class = String::new();
},
b"Name" => name = reader.read_text(e.name(), &mut Vec::new())?,
b"CreationDate" => create_date = reader.read_text(e.name(), &mut Vec::new())?,
b"ExtranetEndpoint" => extranet_endpoint = reader.read_text(e.name(), &mut Vec::new())?,
b"IntranetEndpoint" => intranet_endpoint = reader.read_text(e.name(), &mut Vec::new())?,
b"Location" => location = reader.read_text(e.name(), &mut Vec::new())?,
b"StorageClass" => storage_class = reader.read_text(e.name(), &mut Vec::new())?,
_ => (),
},
Ok(Event::End(ref e)) if e.name() == b"Bucket" => {
let bucket = Bucket::new(
name.clone(),
create_date.clone(),
location.clone(),
extranet_endpoint.clone(),
intranet_endpoint.clone(),
storage_class.clone(),
);
result.push(bucket);
}
Ok(Event::Eof) => {
list_buckets = ListBuckets::new(
prefix,
marker,
max_keys,
is_truncated,
next_marker,
id,
display_name,
result
);
break
},
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
_ => (),
}
buf.clear();
}
Ok(list_buckets)
}
}