use std::ops::Deref;
use std::os::unix::prelude::OsStrExt;
use mountpoint_s3_crt::s3::client::MetaRequestResult;
use crate::object_client::{DeleteObjectError, DeleteObjectResult, ObjectClientResult};
use super::{S3CrtClient, S3Operation, S3RequestError};
impl S3CrtClient {
pub(super) async fn delete_object(
&self,
bucket: &str,
key: &str,
) -> ObjectClientResult<DeleteObjectResult, DeleteObjectError, S3RequestError> {
let span = request_span!(self.inner, "delete_object", bucket, key);
let request = {
let mut message = self
.inner
.new_request_template("DELETE", bucket)
.map_err(S3RequestError::construction_failure)?;
message
.set_request_path(format!("/{key}"))
.map_err(S3RequestError::construction_failure)?;
self.inner.meta_request_without_payload(
message.into_options(S3Operation::DeleteObject),
span,
parse_delete_object_error,
)?
};
request.await?;
Ok(DeleteObjectResult {})
}
}
fn parse_delete_object_error(result: &MetaRequestResult) -> Option<DeleteObjectError> {
match result.response_status {
404 => {
let body = result.error_response_body.as_ref()?;
let root = xmltree::Element::parse(body.as_bytes()).ok()?;
let error_code = root.get_child("Code")?;
let error_str = error_code.get_text()?;
match error_str.deref() {
"NoSuchBucket" => Some(DeleteObjectError::NoSuchBucket),
_ => None,
}
}
_ => None,
}
}
#[cfg(test)]
mod tests {
use std::ffi::{OsStr, OsString};
use super::*;
fn make_result(response_status: i32, body: impl Into<OsString>) -> MetaRequestResult {
MetaRequestResult {
response_status,
crt_error: 1i32.into(),
error_response_headers: None,
error_response_body: Some(body.into()),
}
}
#[test]
fn parse_404_no_such_bucket() {
let body = br#"<?xml version="1.0" encoding="UTF-8"?><Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>djonesoa-nosuchbucket</BucketName><RequestId>BHCQ0FTYY0HKMV43</RequestId><HostId>ntCK1jQfPxY7sSNL/GB13RttgJLjSETfIuOiuRnwImO0dQP2ttj2Qqpn5S/jSLt3Ql0TgHWuYF0=</HostId></Error>"#;
let result = make_result(404, OsStr::from_bytes(&body[..]));
let result = parse_delete_object_error(&result);
assert_eq!(result, Some(DeleteObjectError::NoSuchBucket));
}
}