From 9ea1d01c27a69c36c40c6a4d4830a7f21a02c525 Mon Sep 17 00:00:00 2001 From: grimhilt Date: Sat, 21 Oct 2023 21:47:48 +0200 Subject: [PATCH] add trait ApiCall --- src/services/api.rs | 125 ++++++++++++++++++++++++++------ src/services/api_call.rs | 13 ++++ src/services/auth.rs | 2 - src/services/copy.rs | 30 +++----- src/services/create_folder.rs | 24 ++---- src/services/delete_path.rs | 30 ++------ src/services/download_files.rs | 28 +++---- src/services/downloader.rs | 3 +- src/services/login.rs | 60 ++++++--------- src/services/move.rs | 31 +++----- src/services/req_props.rs | 49 +++++-------- src/services/request_manager.rs | 73 +++++++++++++++++++ src/services/upload_file.rs | 34 +++------ 13 files changed, 292 insertions(+), 210 deletions(-) create mode 100644 src/services/api_call.rs delete mode 100644 src/services/auth.rs create mode 100644 src/services/request_manager.rs diff --git a/src/services/api.rs b/src/services/api.rs index cf551b3..042c7d1 100644 --- a/src/services/api.rs +++ b/src/services/api.rs @@ -1,4 +1,7 @@ use std::env; +use lazy_static::lazy_static; +use std::sync::Mutex; +use std::path::PathBuf; use dotenv::dotenv; use reqwest::Client; use reqwest::RequestBuilder; @@ -8,6 +11,14 @@ use reqwest::header::{HeaderValue, CONTENT_TYPE, HeaderMap, IntoHeaderName}; use crate::utils::api::ApiProps; use crate::commands::config; use crate::commands::clone::get_url_props; +use crate::services::request_manager::get_request_manager; +use crate::services::api_call::ApiCall; + +use super::login::Login; + +lazy_static! { + static ref HTTP_TOKEN: Mutex = Mutex::new(String::new()); +} #[derive(Debug)] pub enum ApiError { @@ -20,7 +31,9 @@ pub enum ApiError { pub struct ApiBuilder { client: Client, request: Option, - headers: Option + headers: Option, + auth_set: bool, + host: Option, } impl ApiBuilder { @@ -29,24 +42,14 @@ impl ApiBuilder { client: Client::new(), request: None, headers: None, + auth_set: false, + host: None, } } pub fn set_url(&mut self, method: Method, url: &str) -> &mut ApiBuilder { - let remote = match config::get("remote") { - Some(r) => r, - None => { - eprintln!("fatal: unable to find a remote"); - std::process::exit(1); - } - }; - - let (host, _, _) = get_url_props(&remote); - let mut u = String::from(host); - u.push_str(url); - self.request = Some(self.client.request(method, u)); + self.request = Some(self.client.request(method, url)); self - } pub fn build_request(&mut self, method: Method, path: &str) -> &mut ApiBuilder { @@ -58,6 +61,7 @@ impl ApiBuilder { } }; let (host, username, root) = get_url_props(&remote); + self.host = Some(host.clone()); let mut url = String::from(host); url.push_str("/remote.php/dav/files/"); url.push_str(username.unwrap()); @@ -71,6 +75,7 @@ impl ApiBuilder { } pub fn set_req(&mut self, meth: Method, p: &str, api_props: &ApiProps) -> &mut ApiBuilder { + self.host = Some(api_props.clone().host.clone()); let mut url = String::from(&api_props.host); url.push_str("/remote.php/dav/files/"); url.push_str("/"); @@ -84,20 +89,41 @@ impl ApiBuilder { self } - fn set_auth(&mut self) -> &mut ApiBuilder { - // todo if not exist - dotenv().ok(); - let password = env::var("PASSWORD").unwrap(); - let username = env::var("USERNAME").unwrap(); + pub fn set_basic_auth(&mut self, login: String, pwd: String) -> &mut ApiBuilder { match self.request.take() { None => { eprintln!("fatal: incorrect request"); std::process::exit(1); }, Some(req) => { - self.request = Some(req.basic_auth(username, Some(password))); + self.request = Some(req.basic_auth(login, Some(pwd))); } } + self.auth_set = true; + self + } + + fn set_auth(&mut self) -> &mut ApiBuilder { + // check .config + //let config_file = PathBuf::from("~/.nextsync/config"); + //if config_file.exists() { + // + //} else { + // let res = Login::new() + // .set_host(self.host.clone()) + // .ask_auth() + // .send_with_err(); + + // if let Err(err) = res { + // eprintln!("fatal: authentification failed"); + // std::process::exit(1); + // } + + //} + //// todo if not exist + //dotenv().ok(); + //let password = env::var("PASSWORD").unwrap(); + //let username = env::var("USERNAME").unwrap(); self } @@ -148,8 +174,63 @@ impl ApiBuilder { self } - pub async fn send(&mut self) -> Result { - self.set_auth(); + pub fn send(&mut self, need_text: bool) -> Result, ApiError> { + let mut request_manager = get_request_manager().lock().unwrap(); + let request_manager = request_manager.as_mut().unwrap(); + if !self.host.is_none() + { + request_manager.set_host(self.host.clone().unwrap()); + } + + if !self.auth_set { + //self.set_auth(); + self.set_header("TOKEN", HeaderValue::from_str(&request_manager.get_token()).unwrap()); + } + + + tokio::runtime::Runtime::new().unwrap().block_on(async { + let res = match self.request.take() { + None => { + eprintln!("fatal: incorrect request"); + std::process::exit(1); + }, + Some(req) => { + if let Some(headers) = &self.headers { + req.headers(headers.clone()) + .send().await.map_err(ApiError::RequestError)? + } else { + req.send().await.map_err(ApiError::RequestError)? + } + }, + }; + + if res.status().is_success() { + if need_text { + let body = res.text().await.map_err(|err| ApiError::EmptyError(err))?; + Ok(Some(body)) + } else { + Ok(None) + } + } else { + Err(ApiError::IncorrectRequest(res)) + } + }) + } + + pub async fn old_send(&mut self) -> Result { + let mut request_manager = get_request_manager().lock().unwrap(); + let request_manager = request_manager.as_mut().unwrap(); + if !self.host.is_none() + { + request_manager.set_host(self.host.clone().unwrap()); + } + + if !self.auth_set { + //self.set_auth(); + self.set_header("TOKEN", HeaderValue::from_str(&request_manager.get_token()).unwrap()); + } + + match self.request.take() { None => { eprintln!("fatal: incorrect request"); diff --git a/src/services/api_call.rs b/src/services/api_call.rs new file mode 100644 index 0000000..fc1d45f --- /dev/null +++ b/src/services/api_call.rs @@ -0,0 +1,13 @@ +use crate::services::api::ApiError; + +pub trait ApiCall { + fn new() -> Self where Self: Sized { + unimplemented!() + } + fn set_url(&mut self, url: &str) -> &mut Self { + self + } + fn send(&mut self) -> Result, ApiError> { + unimplemented!() + } +} diff --git a/src/services/auth.rs b/src/services/auth.rs deleted file mode 100644 index 139597f..0000000 --- a/src/services/auth.rs +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/services/copy.rs b/src/services/copy.rs index 541b9f0..38093d3 100644 --- a/src/services/copy.rs +++ b/src/services/copy.rs @@ -1,20 +1,27 @@ -use reqwest::{Method, Response, Error, header::HeaderValue}; +use reqwest::{Method, header::HeaderValue}; use crate::services::api::{ApiBuilder, ApiError}; use crate::clone::get_url_props; use crate::commands::config; +use crate::services::api_call::ApiCall; pub struct Copy { api_builder: ApiBuilder, } -impl Copy { - pub fn new() -> Self { +impl ApiCall for Copy { + fn new() -> Self { Copy { api_builder: ApiBuilder::new(), } } - pub fn set_url(&mut self, url: &str, destination: &str) -> &mut Copy { + fn send(&mut self) -> Result, ApiError> { + self.api_builder.send(true) + } +} + +impl Copy { + pub fn set_url_copy(&mut self, url: &str, destination: &str) -> &mut Copy { self.api_builder.build_request(Method::from_bytes(b"COPY").unwrap(), url); let remote = match config::get("remote") { @@ -37,25 +44,10 @@ impl Copy { self } - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - pub fn _overwrite(&mut self, overwrite: bool) -> &mut Copy { self.api_builder.set_header("Overwrite", HeaderValue::from_str({ if overwrite { "T" } else { "F" } }).unwrap()); self } - - pub fn send_with_err(&mut self) -> Result<(), ApiError> { - let res = tokio::runtime::Runtime::new().unwrap().block_on(async { - self.send().await - }).map_err(ApiError::RequestError)?; - if res.status().is_success() { - Ok(()) - } else { - Err(ApiError::IncorrectRequest(res)) - } - } } diff --git a/src/services/create_folder.rs b/src/services/create_folder.rs index 5de28e3..435fbc2 100644 --- a/src/services/create_folder.rs +++ b/src/services/create_folder.rs @@ -1,34 +1,24 @@ -use reqwest::{Method, Response, Error}; +use reqwest::Method; use crate::services::api::{ApiBuilder, ApiError}; +use crate::services::api_call::ApiCall; pub struct CreateFolder { api_builder: ApiBuilder, } -impl CreateFolder { - pub fn new() -> Self { +impl ApiCall for CreateFolder { + fn new() -> Self { CreateFolder { api_builder: ApiBuilder::new(), } } - pub fn set_url(&mut self, url: &str) -> &mut CreateFolder { + fn set_url(&mut self, url: &str) -> &mut CreateFolder { self.api_builder.build_request(Method::from_bytes(b"MKCOL").unwrap(), url); self } - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - - pub fn send_with_err(&mut self) -> Result<(), ApiError> { - let res = tokio::runtime::Runtime::new().unwrap().block_on(async { - self.send().await - }).map_err(ApiError::RequestError)?; - if res.status().is_success() { - Ok(()) - } else { - Err(ApiError::IncorrectRequest(res)) - } + fn send(&mut self) -> Result, ApiError> { + self.api_builder.send(false) } } diff --git a/src/services/delete_path.rs b/src/services/delete_path.rs index 54091a4..c7d2807 100644 --- a/src/services/delete_path.rs +++ b/src/services/delete_path.rs @@ -1,38 +1,24 @@ -use reqwest::{Method, Response, Error}; +use reqwest::Method; use crate::services::api::{ApiBuilder, ApiError}; +use crate::services::api_call::ApiCall; pub struct DeletePath { api_builder: ApiBuilder, } -impl DeletePath { - pub fn new() -> Self { +impl ApiCall for DeletePath { + fn new() -> Self { DeletePath { api_builder: ApiBuilder::new(), } } - pub fn set_url(&mut self, url: &str) -> &mut DeletePath { + fn set_url(&mut self, url: &str) -> &mut DeletePath { self.api_builder.build_request(Method::DELETE, url); self } - - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - - pub fn send_with_err(&mut self) -> Result { - let res = tokio::runtime::Runtime::new().unwrap().block_on(async { - self.send().await - }).map_err(ApiError::RequestError)?; - - if res.status().is_success() { - let body = tokio::runtime::Runtime::new().unwrap().block_on(async { - res.text().await - }).map_err(ApiError::EmptyError)?; - Ok(body) - } else { - Err(ApiError::IncorrectRequest(res)) - } + + fn send(&mut self) -> Result, ApiError> { + self.api_builder.send(true) } } diff --git a/src/services/download_files.rs b/src/services/download_files.rs index 397fc87..0481c2f 100644 --- a/src/services/download_files.rs +++ b/src/services/download_files.rs @@ -6,38 +6,32 @@ use std::io::{self, Write}; use reqwest::{Method, Response, Error}; use crate::utils::api::ApiProps; use crate::services::api::{ApiBuilder, ApiError}; +use crate::services::api_call::ApiCall; pub struct DownloadFiles { api_builder: ApiBuilder, relative_ps: String, } -impl DownloadFiles { - pub fn new() -> Self { +impl ApiCall for DownloadFiles { + fn new() -> Self { DownloadFiles { api_builder: ApiBuilder::new(), relative_ps: String::new(), } } +} - pub fn set_url(&mut self, relative_ps: &str, api_props: &ApiProps) -> &mut DownloadFiles { +impl DownloadFiles { + // todo make it beautiful + pub fn set_url_download(&mut self, relative_ps: &str, api_props: &ApiProps) -> &mut DownloadFiles { self.relative_ps = relative_ps.to_string(); self.api_builder.set_req(Method::GET, relative_ps, api_props); self } - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - - pub async fn _send_with_err(mut self) -> Result, ApiError> { - let res = self.send().await.map_err(ApiError::RequestError)?; - if res.status().is_success() { - let body = res.bytes().await.map_err(ApiError::EmptyError)?; - Ok(body.to_vec()) - } else { - Err(ApiError::IncorrectRequest(res)) - } + pub async fn send_download(&mut self) -> Result { + self.api_builder.old_send().await } pub fn save_stream(&mut self, ref_p: PathBuf, callback: Option) -> Result<(), ApiError> { @@ -45,7 +39,7 @@ impl DownloadFiles { let mut file = File::create(abs_p).unwrap(); tokio::runtime::Runtime::new().unwrap().block_on(async { - let res = self.send().await.map_err(ApiError::RequestError)?; + let res = self.send_download().await.map_err(ApiError::RequestError)?; if res.status().is_success() { let mut stream = res.bytes_stream(); @@ -70,7 +64,7 @@ impl DownloadFiles { pub fn save(&mut self, ref_p: PathBuf) -> Result<(), ApiError> { tokio::runtime::Runtime::new().unwrap().block_on(async { let p = ref_p.join(PathBuf::from(self.relative_ps.clone())); - let res = self.send().await.map_err(ApiError::RequestError)?; + let res = self.send_download().await.map_err(ApiError::RequestError)?; if res.status().is_success() { let body = res.bytes().await.map_err(ApiError::EmptyError)?; match Self::write_file(p, &body.to_vec()) { diff --git a/src/services/downloader.rs b/src/services/downloader.rs index e9a6266..18c7cba 100644 --- a/src/services/downloader.rs +++ b/src/services/downloader.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use indicatif::{ProgressBar, MultiProgress, ProgressStyle, HumanBytes}; use crate::utils::api::ApiProps; +use crate::services::api_call::ApiCall; use crate::services::api::ApiError; use crate::services::download_files::DownloadFiles; use crate::services::req_props::ObjProps; @@ -106,7 +107,7 @@ impl Downloader { for file in self.files.clone() { let relative_s = &file.clone().relative_s.unwrap(); let mut download = DownloadFiles::new(); - download.set_url(&relative_s, &self.api_props.clone().unwrap()); + download.set_url_download(&relative_s, &self.api_props.clone().unwrap()); let should_use_stream = { if let Some(size) = file.contentlength { diff --git a/src/services/login.rs b/src/services/login.rs index 35ec1f9..058b155 100644 --- a/src/services/login.rs +++ b/src/services/login.rs @@ -2,10 +2,9 @@ use std::io; use std::io::Cursor; use std::io::prelude::*; use xml::reader::{EventReader, XmlEvent}; -use reqwest::{Response, Error, header::HeaderValue, Method}; +use reqwest::{header::HeaderValue, Method}; use rpassword; use crate::services::api_call::ApiCall; - use crate::services::api::{ApiBuilder, ApiError}; pub struct Login { @@ -16,7 +15,7 @@ pub struct Login { } impl ApiCall for Login { - pub fn new() -> Self { + fn new() -> Self { Login { api_builder: ApiBuilder::new(), login: String::new(), @@ -25,21 +24,7 @@ impl ApiCall for Login { } } - pub fn ask_auth(&mut self) -> &mut Login { - println!("Please enter your username/email: "); - let stdin = io::stdin(); - self.login = stdin.lock().lines().next().unwrap().unwrap(); - println!("Please enter your password: "); - self.password = rpassword::read_password().unwrap(); - self - } - - pub fn set_host(&mut self, host: Option) -> &mut Login { - self.host = host; - self - } - - pub async fn send(&mut self) -> Result { + fn send(&mut self) -> Result, ApiError> { let url = match self.host.clone() { Some(h) => { @@ -54,28 +39,29 @@ impl ApiCall for Login { self.api_builder.set_url(Method::GET, &url); self.api_builder.set_header("OCS-APIRequest", HeaderValue::from_str("true").unwrap()); self.api_builder.set_basic_auth(self.login.clone(), self.password.clone()); - self.api_builder.send().await + self.api_builder.send(true) } - - pub async fn send_with_err(&mut self) -> Result { - match self.send().await { - Err(res) => Err(ApiError::RequestError(res)), - Ok(res) if res.status().is_success() => { - let body = res - .text() - .await - .map_err(|err| ApiError::EmptyError(err))?; - Ok(body) - }, - Ok(res) => { - Err(ApiError::IncorrectRequest(res)) - } - } +} + +impl Login { + pub fn ask_auth(&mut self) -> &mut Login { + println!("Please enter your username/email: "); + let stdin = io::stdin(); + self.login = stdin.lock().lines().next().unwrap().unwrap(); + println!("Please enter your password: "); + self.password = rpassword::read_password().unwrap(); + self } - pub async fn send_login(&mut self) -> Result { - match self.send_with_err().await { - Ok(body) => Ok(self.parse(body)), + pub fn set_host(&mut self, host: Option) -> &mut Login { + self.host = host; + self + } + + pub fn send_login(&mut self) -> Result { + match self.send() { + Ok(Some(body)) => Ok(self.parse(body)), + Ok(None) => Err(ApiError::Unexpected(String::from("Empty after tested"))), Err(err) => Err(err), } } diff --git a/src/services/move.rs b/src/services/move.rs index b91b64f..ab6a76a 100644 --- a/src/services/move.rs +++ b/src/services/move.rs @@ -1,20 +1,28 @@ -use reqwest::{Method, Response, Error, header::HeaderValue}; +use reqwest::{Method, header::HeaderValue}; use crate::services::api::{ApiBuilder, ApiError}; use crate::clone::get_url_props; use crate::commands::config; +use crate::services::api_call::ApiCall; pub struct Move { api_builder: ApiBuilder, } -impl Move { - pub fn new() -> Self { +impl ApiCall for Move { + fn new() -> Self { Move { api_builder: ApiBuilder::new(), } } - pub fn set_url(&mut self, url: &str, destination: &str) -> &mut Move { + + fn send(&mut self) -> Result, ApiError> { + self.api_builder.send(false) + } +} + +impl Move { + pub fn set_url_move(&mut self, url: &str, destination: &str) -> &mut Move { self.api_builder.build_request(Method::from_bytes(b"MOVE").unwrap(), url); let remote = match config::get("remote") { @@ -37,25 +45,10 @@ impl Move { self } - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - pub fn _overwrite(&mut self, overwrite: bool) -> &mut Move { self.api_builder.set_header("Overwrite", HeaderValue::from_str({ if overwrite { "T" } else { "F" } }).unwrap()); self } - - pub fn send_with_err(&mut self) -> Result<(), ApiError> { - let res = tokio::runtime::Runtime::new().unwrap().block_on(async { - self.send().await - }).map_err(ApiError::RequestError)?; - if res.status().is_success() { - Ok(()) - } else { - Err(ApiError::IncorrectRequest(res)) - } - } } diff --git a/src/services/req_props.rs b/src/services/req_props.rs index 73f124e..a293ea6 100644 --- a/src/services/req_props.rs +++ b/src/services/req_props.rs @@ -1,6 +1,6 @@ use std::io::Cursor; use chrono::{Utc, DateTime}; -use reqwest::{Method, Response, Error}; +use reqwest::Method; use xml::reader::{EventReader, XmlEvent}; use reqwest::header::HeaderValue; use crate::commands::clone::get_url_props; @@ -8,6 +8,7 @@ use crate::commands::config; use crate::utils::time::parse_timestamp; use crate::utils::api::{get_relative_s, ApiProps}; use crate::services::api::{ApiBuilder, ApiError}; +use crate::services::api_call::ApiCall; #[derive(Debug)] pub struct ObjProps { @@ -55,8 +56,8 @@ pub struct ReqProps { api_props: Option } -impl ReqProps { - pub fn new() -> Self { +impl ApiCall for ReqProps { + fn new() -> Self { ReqProps { api_builder: ApiBuilder::new(), xml_balises: vec![], @@ -65,7 +66,7 @@ impl ReqProps { } } - pub fn set_url(&mut self, url: &str) -> &mut ReqProps { + fn set_url(&mut self, url: &str) -> &mut ReqProps { let remote = match config::get("remote") { Some(r) => r, None => { @@ -83,6 +84,13 @@ impl ReqProps { self } + fn send(&mut self) -> Result, ApiError> { + self.validate_xml(); + self.api_builder.send(true) + } +} + +impl ReqProps { pub fn set_request(&mut self, p: &str, api_props: &ApiProps) -> &mut ReqProps { self.api_props = Some(api_props.clone()); self.api_builder.set_req(Method::from_bytes(b"PROPFIND").unwrap(), p, api_props); @@ -145,32 +153,10 @@ impl ReqProps { self } - pub async fn send(&mut self) -> Result { - self.validate_xml(); - self.api_builder.send().await - } - - pub fn send_with_err(&mut self) -> Result { - tokio::runtime::Runtime::new().unwrap().block_on(async { - match self.send().await { - Err(res) => Err(ApiError::RequestError(res)), - Ok(res) if res.status().is_success() => { - let body = res - .text() - .await - .map_err(|err| ApiError::EmptyError(err))?; - Ok(body) - }, - Ok(res) => { - Err(ApiError::IncorrectRequest(res)) - } - } - }) - } - pub fn send_req_multiple(&mut self) -> Result, ApiError> { - match self.send_with_err() { - Ok(body) => Ok(self.parse(body, true)), + match self.send() { + Ok(Some(body)) => Ok(self.parse(body, true)), + Ok(None) => Err(ApiError::Unexpected(String::from("Empty after tested"))), Err(err) => Err(err), } } @@ -178,12 +164,13 @@ impl ReqProps { pub fn send_req_single(&mut self) -> Result { // set depth to 0 as we only need one element self.set_depth("0"); - match self.send_with_err() { - Ok(body) => { + match self.send() { + Ok(Some(body)) => { let objs = self.parse(body, false); let obj = objs[0].clone(); Ok(obj) }, + Ok(None) => Err(ApiError::Unexpected(String::from("Empty after tested"))), Err(err) => Err(err), } } diff --git a/src/services/request_manager.rs b/src/services/request_manager.rs new file mode 100644 index 0000000..f968c62 --- /dev/null +++ b/src/services/request_manager.rs @@ -0,0 +1,73 @@ +use lazy_static::lazy_static; +use std::sync::Mutex; + +use crate::services::login::Login; +use crate::commands::config; +use crate::commands::clone::get_url_props; +use crate::services::api_call::ApiCall; + +lazy_static! { + static ref REQUEST_MANAGER: Mutex> = Mutex::new(None); +} + +pub fn get_request_manager() -> &'static Mutex> { + if REQUEST_MANAGER.lock().unwrap().is_none() { + *REQUEST_MANAGER.lock().unwrap() = Some(RequestManager::new()); + } + &REQUEST_MANAGER +} + +pub struct RequestManager { + token: Option, + host: Option, +} + +impl RequestManager { + pub fn new() -> Self { + RequestManager { + token: None, + host: None, + } + } + + pub fn set_host(&mut self, host: String) { + self.host = Some(host); + } + + pub fn get_host(&mut self) -> String + { + if self.host.is_none() + { + let remote = match config::get("remote") { + Some(r) => r, + None => { + // todo ask user instead + eprintln!("fatal: unable to find a remote"); + std::process::exit(1); + } + }; + let (host, _, _) = get_url_props(&remote); + self.host = Some(host.clone()); + // todo ask user + } + self.host.clone().unwrap() + } + + pub fn get_token(&mut self) -> String { + if self.token.is_none() { + // todo check in config + let get_token = Login::new() + .ask_auth() + .set_host(Some(self.get_host())) + .send_login(); + // todo deal with error cases + self.token = Some(get_token.unwrap()); + } + self.token.clone().unwrap() + } + + pub fn create_request() + { + + } +} diff --git a/src/services/upload_file.rs b/src/services/upload_file.rs index fced9a5..1f2eb09 100644 --- a/src/services/upload_file.rs +++ b/src/services/upload_file.rs @@ -1,25 +1,32 @@ use std::fs::File; use std::io::Read; use std::path::PathBuf; -use reqwest::{Method, Response, Error}; +use reqwest::Method; use crate::services::api::{ApiBuilder, ApiError}; +use crate::services::api_call::ApiCall; pub struct UploadFile { api_builder: ApiBuilder, } -impl UploadFile { - pub fn new() -> Self { +impl ApiCall for UploadFile { + fn new() -> Self { UploadFile { api_builder: ApiBuilder::new(), } } - pub fn set_url(&mut self, url: &str) -> &mut UploadFile { + fn set_url(&mut self, url: &str) -> &mut UploadFile { self.api_builder.build_request(Method::PUT, url); self } + fn send(&mut self) -> Result, ApiError> { + self.api_builder.send(true) + } +} + +impl UploadFile { pub fn set_file(&mut self, path: PathBuf) -> &mut UploadFile { // todo large file // todo small files @@ -29,23 +36,4 @@ impl UploadFile { self.api_builder.set_body(buffer); self } - - pub async fn send(&mut self) -> Result { - self.api_builder.send().await - } - - pub fn send_with_err(&mut self) -> Result { - let res = tokio::runtime::Runtime::new().unwrap().block_on(async { - self.send().await - }).map_err(ApiError::RequestError)?; - - if res.status().is_success() { - let body = tokio::runtime::Runtime::new().unwrap().block_on(async { - res.text().await - }).map_err(ApiError::EmptyError)?; - Ok(body) - } else { - Err(ApiError::IncorrectRequest(res)) - } - } }