use std::future::Future;
use http::Method;
use serde::{Deserialize, Serialize};
use crate::body::NoneBody;
use crate::error::Result;
use crate::response::BodyResponseProcessor;
use crate::ser::OnlyKeyField;
use crate::{Client, Ops, Prepared, Request};
#[derive(Debug, Clone, Default, Serialize)]
pub struct GetBucketWormParams {
worm: OnlyKeyField,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
pub enum WormState {
InProgress,
Locked,
}
impl WormState {
pub fn as_str(&self) -> &'static str {
match self {
WormState::InProgress => "InProgress",
WormState::Locked => "Locked",
}
}
}
impl AsRef<str> for WormState {
fn as_ref(&self) -> &str {
self.as_str()
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct WormConfiguration {
pub worm_id: String,
pub state: WormState,
pub retention_period_in_days: u32,
pub creation_date: String,
pub expiration_date: Option<String>,
}
pub struct GetBucketWorm;
impl Ops for GetBucketWorm {
type Response = BodyResponseProcessor<WormConfiguration>;
type Body = NoneBody;
type Query = GetBucketWormParams;
fn prepare(self) -> Result<Prepared<GetBucketWormParams>> {
Ok(Prepared {
method: Method::GET,
query: Some(GetBucketWormParams::default()),
..Default::default()
})
}
}
pub trait GetBucketWormOps {
fn get_bucket_worm(&self) -> impl Future<Output = Result<WormConfiguration>>;
}
impl GetBucketWormOps for Client {
async fn get_bucket_worm(&self) -> Result<WormConfiguration> {
self.request(GetBucketWorm).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn params_serialize_adds_worm_subresource() {
let q = crate::ser::to_string(&GetBucketWormParams::default()).unwrap();
assert_eq!(q, "worm");
}
#[test]
fn prepared_uses_get() {
let prepared = GetBucketWorm.prepare().unwrap();
assert_eq!(prepared.method, Method::GET);
assert!(prepared.body.is_none());
}
#[test]
fn parse_locked_policy() {
let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
<WormConfiguration>
<WormId>1666E2CFB2B3418****</WormId>
<State>Locked</State>
<RetentionPeriodInDays>1</RetentionPeriodInDays>
<CreationDate>2020-10-15T15:50:32</CreationDate>
</WormConfiguration>"#;
let parsed: WormConfiguration = quick_xml::de::from_str(xml).unwrap();
assert_eq!(parsed.worm_id, "1666E2CFB2B3418****");
assert_eq!(parsed.state, WormState::Locked);
assert_eq!(parsed.retention_period_in_days, 1);
}
#[test]
fn parse_in_progress_policy() {
let xml = r#"<WormConfiguration>
<WormId>abc</WormId>
<State>InProgress</State>
<RetentionPeriodInDays>365</RetentionPeriodInDays>
<CreationDate>2024-01-01T00:00:00</CreationDate>
</WormConfiguration>"#;
let parsed: WormConfiguration = quick_xml::de::from_str(xml).unwrap();
assert_eq!(parsed.state, WormState::InProgress);
assert_eq!(parsed.retention_period_in_days, 365);
assert!(parsed.expiration_date.is_none());
}
#[test]
fn parse_locked_policy_with_expiration_date() {
let xml = r#"<WormConfiguration>
<WormId>abc</WormId>
<State>Locked</State>
<RetentionPeriodInDays>30</RetentionPeriodInDays>
<CreationDate>2024-01-01T00:00:00</CreationDate>
<ExpirationDate>2024-01-31T00:00:00</ExpirationDate>
</WormConfiguration>"#;
let parsed: WormConfiguration = quick_xml::de::from_str(xml).unwrap();
assert_eq!(parsed.expiration_date.as_deref(), Some("2024-01-31T00:00:00"));
}
}