use rc_core::{Capabilities, Error, Result};
pub async fn detect_capabilities(
client: &aws_sdk_s3::Client,
bucket: &str,
) -> Result<Capabilities> {
let caps = Capabilities {
versioning: check_versioning(client, bucket).await,
tagging: check_tagging(client, bucket).await,
..Default::default()
};
Ok(caps)
}
async fn check_versioning(client: &aws_sdk_s3::Client, bucket: &str) -> bool {
client
.get_bucket_versioning()
.bucket(bucket)
.send()
.await
.is_ok()
}
async fn check_tagging(client: &aws_sdk_s3::Client, bucket: &str) -> bool {
match client.get_bucket_tagging().bucket(bucket).send().await {
Ok(_) => true,
Err(e) => {
let err = e.into_service_error();
!err.to_string().contains("NotImplemented")
}
}
}
pub fn require_capability(caps: &Capabilities, feature: &str) -> Result<()> {
let supported = match feature {
"versioning" => caps.versioning,
"object_lock" | "retention" => caps.object_lock,
"tagging" => caps.tagging,
"select" | "sql" => caps.select,
"notifications" | "watch" => caps.notifications,
"lifecycle" => caps.lifecycle,
"replication" => caps.replication,
_ => false,
};
if supported {
Ok(())
} else {
Err(Error::UnsupportedFeature(format!(
"The backend does not support '{feature}'. Use --force to attempt anyway."
)))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_require_capability_versioning() {
let caps = Capabilities {
versioning: true,
..Default::default()
};
assert!(require_capability(&caps, "versioning").is_ok());
let caps = Capabilities {
versioning: false,
..Default::default()
};
assert!(require_capability(&caps, "versioning").is_err());
}
#[test]
fn test_require_capability_unknown() {
let caps = Capabilities::default();
assert!(require_capability(&caps, "unknown_feature").is_err());
}
}