use reqwest::Client;
use api::data::{Error as DataError, OwnedData};
use api::nonce::{request_nonce, NonceError};
use api::request::{ensure_success, ResponseError};
use api::url::UrlBuilder;
use file::remote_file::RemoteFile;
pub struct Delete<'a> {
file: &'a RemoteFile,
nonce: Vec<u8>,
}
impl<'a> Delete<'a> {
pub fn new(file: &'a RemoteFile, nonce: Option<Vec<u8>>) -> Self {
Self {
file,
nonce: nonce.unwrap_or_default(),
}
}
pub fn invoke(mut self, client: &Client) -> Result<(), Error> {
if self.nonce.is_empty() {
self.nonce = self.fetch_auth_nonce(client)?;
}
let data = OwnedData::from(DeleteData::new(), &self.file)
.map_err(|err| PrepareError::DeleteData(DeleteDataError::Owned(err)))?;
self.request_delete(client, &data)
}
fn fetch_auth_nonce(&self, client: &Client) -> Result<Vec<u8>, Error> {
request_nonce(client, UrlBuilder::download(self.file, false)).map_err(|err| err.into())
}
fn request_delete(&self, client: &Client, data: &OwnedData<DeleteData>) -> Result<(), Error> {
let url = UrlBuilder::api_delete(self.file);
let response = client
.post(url)
.json(&data)
.send()
.map_err(|_| DeleteError::Request)?;
ensure_success(&response).map_err(|err| err.into())
}
}
#[derive(Debug, Serialize, Default)]
pub struct DeleteData {}
impl DeleteData {
pub fn new() -> Self {
DeleteData::default()
}
}
#[derive(Fail, Debug)]
pub enum Error {
#[fail(display = "failed to prepare the action")]
Prepare(#[cause] PrepareError),
#[fail(display = "the file has expired or did never exist")]
Expired,
#[fail(display = "failed to send the file deletion request")]
Delete(#[cause] DeleteError),
}
impl From<NonceError> for Error {
fn from(err: NonceError) -> Error {
match err {
NonceError::Expired => Error::Expired,
err => Error::Prepare(PrepareError::Auth(err)),
}
}
}
impl From<PrepareError> for Error {
fn from(err: PrepareError) -> Error {
Error::Prepare(err)
}
}
impl From<DeleteError> for Error {
fn from(err: DeleteError) -> Error {
Error::Delete(err)
}
}
#[derive(Debug, Fail)]
pub enum DeleteDataError {
#[fail(display = "")]
Owned(#[cause] DataError),
}
#[derive(Fail, Debug)]
pub enum PrepareError {
#[fail(display = "failed to authenticate")]
Auth(#[cause] NonceError),
#[fail(display = "invalid parameters")]
DeleteData(#[cause] DeleteDataError),
}
#[derive(Fail, Debug)]
pub enum DeleteError {
#[fail(display = "failed to send file deletion request")]
Request,
#[fail(display = "bad response from server while deleting file")]
Response(#[cause] ResponseError),
}
impl From<ResponseError> for Error {
fn from(err: ResponseError) -> Self {
match err {
ResponseError::Expired => Error::Expired,
err => Error::Delete(DeleteError::Response(err)),
}
}
}