use crate::s3::error::{Error, ValidationErr};
use crate::s3::response_traits::{HasBucket, HasIsDeleteMarker, HasRegion, HasVersion};
use crate::s3::types::S3Request;
use crate::s3::utils::{get_text_default, get_text_option, get_text_result};
use crate::{impl_from_s3response, impl_has_s3fields};
use bytes::{Buf, Bytes};
use http::HeaderMap;
use xmltree::Element;
#[derive(Clone, Debug)]
pub struct DeleteObjectResponse {
request: S3Request,
headers: HeaderMap,
body: Bytes,
}
impl_from_s3response!(DeleteObjectResponse);
impl_has_s3fields!(DeleteObjectResponse);
impl HasBucket for DeleteObjectResponse {}
impl HasRegion for DeleteObjectResponse {}
impl HasVersion for DeleteObjectResponse {}
impl HasIsDeleteMarker for DeleteObjectResponse {}
#[derive(Clone, Debug)]
pub struct DeleteError {
pub code: String,
pub message: String,
pub object_name: String,
pub version_id: Option<String>,
}
#[derive(Clone, Debug)]
pub struct DeletedObject {
pub name: String,
pub version_id: Option<String>,
pub delete_marker: bool,
pub delete_marker_version_id: Option<String>,
}
#[derive(Clone, Debug)]
pub enum DeleteResult {
Deleted(DeletedObject),
Error(DeleteError),
}
impl From<DeleteResult> for Result<DeletedObject, DeleteError> {
fn from(result: DeleteResult) -> Self {
match result {
DeleteResult::Deleted(obj) => Ok(obj),
DeleteResult::Error(err) => Err(err),
}
}
}
impl DeleteResult {
pub fn is_deleted(&self) -> bool {
matches!(self, DeleteResult::Deleted(_))
}
pub fn is_error(&self) -> bool {
matches!(self, DeleteResult::Error(_))
}
}
#[derive(Clone, Debug)]
pub struct DeleteObjectsResponse {
request: S3Request,
pub(crate) headers: HeaderMap,
body: Bytes,
}
impl_from_s3response!(DeleteObjectsResponse);
impl_has_s3fields!(DeleteObjectsResponse);
impl HasBucket for DeleteObjectsResponse {}
impl HasRegion for DeleteObjectsResponse {}
impl DeleteObjectsResponse {
pub fn result(&self) -> Result<Vec<DeleteResult>, Error> {
let root = Element::parse(self.body.clone().reader()).map_err(ValidationErr::from)?;
let result = root
.children
.iter()
.map(|elem| elem.as_element().unwrap())
.map(|elem| {
if elem.name == "Deleted" {
Ok(DeleteResult::Deleted(DeletedObject {
name: get_text_result(elem, "Key")?,
version_id: get_text_option(elem, "VersionId"),
delete_marker: get_text_default(elem, "DeleteMarker").to_lowercase()
== "true",
delete_marker_version_id: get_text_option(elem, "DeleteMarkerVersionId"),
}))
} else {
assert_eq!(elem.name, "Error");
Ok(DeleteResult::Error(DeleteError {
code: get_text_result(elem, "Code")?,
message: get_text_result(elem, "Message")?,
object_name: get_text_result(elem, "Key")?,
version_id: get_text_option(elem, "VersionId"),
}))
}
})
.collect::<Result<Vec<DeleteResult>, Error>>()?;
Ok(result)
}
}