use crate::impl_has_s3fields;
use crate::s3::error::{Error, S3ServerError, ValidationErr};
use crate::s3::minio_error_response::MinioErrorCode;
use crate::s3::response_traits::{HasBucket, HasObject, HasRegion, HasVersion};
use crate::s3::types::{FromS3Response, RetentionMode, S3Request};
use crate::s3::utils::{UtcTime, from_iso8601utc, get_text_option};
use async_trait::async_trait;
use bytes::{Buf, Bytes};
use http::HeaderMap;
use std::mem;
use xmltree::Element;
#[derive(Clone, Debug)]
pub struct GetObjectRetentionResponse {
request: S3Request,
headers: HeaderMap,
body: Bytes,
}
impl_has_s3fields!(GetObjectRetentionResponse);
impl HasBucket for GetObjectRetentionResponse {}
impl HasRegion for GetObjectRetentionResponse {}
impl HasObject for GetObjectRetentionResponse {}
impl HasVersion for GetObjectRetentionResponse {}
impl GetObjectRetentionResponse {
pub fn retention_mode(&self) -> Result<Option<RetentionMode>, ValidationErr> {
if self.body.is_empty() {
return Ok(None);
}
let root = Element::parse(self.body.clone().reader())?;
Ok(match get_text_option(&root, "Mode") {
Some(v) => Some(RetentionMode::parse(&v)?),
_ => None,
})
}
pub fn retain_until_date(&self) -> Result<Option<UtcTime>, ValidationErr> {
if self.body.is_empty() {
return Ok(None);
}
let root = Element::parse(self.body.clone().reader())?;
Ok(match get_text_option(&root, "RetainUntilDate") {
Some(v) => Some(from_iso8601utc(&v)?),
_ => None,
})
}
}
#[async_trait]
impl FromS3Response for GetObjectRetentionResponse {
async fn from_s3response(
request: S3Request,
response: Result<reqwest::Response, Error>,
) -> Result<Self, Error> {
match response {
Ok(mut resp) => Ok(Self {
request,
headers: mem::take(resp.headers_mut()),
body: resp.bytes().await.map_err(ValidationErr::HttpError)?,
}),
Err(Error::S3Server(S3ServerError::S3Error(mut e)))
if matches!(e.code(), MinioErrorCode::NoSuchObjectLockConfiguration) =>
{
Ok(Self {
request,
headers: e.take_headers(),
body: Bytes::new(),
})
}
Err(e) => Err(e),
}
}
}