move parsing into list_folders

This commit is contained in:
grimhilt
2023-06-17 01:20:00 +02:00
parent b911ad8606
commit ea2b0772af
2 changed files with 117 additions and 68 deletions

View File

@@ -1,8 +1,31 @@
use crate::services::api::{ApiBuilder, ApiError};
use xml::reader::{EventReader, XmlEvent};
use std::io::Cursor;
use reqwest::{Method, IntoUrl, Response, Error};
pub struct FolderContent {
pub href: Option<String>,
}
impl Clone for FolderContent {
fn clone(&self) -> Self {
FolderContent {
href: self.href.clone(),
}
}
}
impl FolderContent {
fn new() -> Self {
FolderContent {
href: None,
}
}
}
pub struct ListFolders {
api_builder: ApiBuilder,
xml_balises: Vec<String>,
}
impl ListFolders {
@@ -10,14 +33,20 @@ impl ListFolders {
ListFolders {
api_builder: ApiBuilder::new()
.set_request(Method::from_bytes(b"PROPFIND").unwrap(), url),
xml_balises: vec![],
}
}
pub fn gethref(&mut self) -> &mut ListFolders {
self.xml_balises.push(String::from("href"));
self
}
pub async fn send(&mut self) -> Result<Response, Error> {
self.api_builder.send().await
}
pub async fn send_with_err(mut self) -> Result<String, ApiError> {
pub async fn send_with_err(&mut self) -> Result<String, ApiError> {
let res = self.send().await.map_err(ApiError::RequestError)?;
if res.status().is_success() {
let body = res.text().await.map_err(ApiError::EmptyError)?;
@@ -27,22 +56,59 @@ impl ListFolders {
}
}
pub async fn send_with_res(self) -> String {
pub async fn send_with_res(&mut self) -> Result<Vec<FolderContent>, ApiError> {
match self.send_with_err().await {
Ok(body) => body,
Err(ApiError::IncorrectRequest(err)) => {
eprintln!("fatal: {}", err.status());
std::process::exit(1);
},
Err(ApiError::EmptyError(_)) => {
eprintln!("Failed to get body");
String::from("")
}
Err(ApiError::RequestError(err)) => {
eprintln!("fatal: {}", err);
std::process::exit(1);
},
_ => todo!(),
Ok(body) => Ok(self.parse(body)),
Err(err) => Err(err),
}
}
pub fn parse(&self, xml: String) -> Vec<FolderContent> {
let cursor = Cursor::new(xml);
let parser = EventReader::new(cursor);
let mut should_get = false;
let mut values: Vec<FolderContent> = vec![];
let mut iter = self.xml_balises.iter();
let mut val = iter.next();
let mut content = FolderContent::new();
for event in parser {
match event {
Ok(XmlEvent::StartElement { name, .. }) => {
if let Some(v) = val.clone() {
should_get = &name.local_name == v;
} else {
// end of balises to get then start over for next object
values.push(content.clone());
iter = self.xml_balises.iter();
val = iter.next();
content = FolderContent::new();
if let Some(v) = val.clone() {
should_get = &name.local_name == v;
}
}
}
Ok(XmlEvent::Characters(text)) => {
if !text.trim().is_empty() && should_get {
match val.unwrap().as_str() {
"href" => content.href = Some(text),
_ => (),
}
val = iter.next()
}
}
Ok(XmlEvent::EndElement { .. }) => {
should_get = false;
}
Err(e) => {
eprintln!("Error: {}", e);
break;
}
_ => {}
}
}
values
}
}