1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use anyhow::Result;
use tracing::info;
use s3util_rs::config::ClientConfig;
use s3util_rs::config::args::get_bucket_notification_configuration::GetBucketNotificationConfigurationArgs;
use s3util_rs::output::json::get_bucket_notification_configuration_to_json;
use s3util_rs::storage::s3::api::{self, HeadError};
use super::ExitStatus;
/// Runtime entry for
/// `s3util get-bucket-notification-configuration s3://<BUCKET>`.
///
/// Builds the SDK client from `client_config`, issues
/// `GetBucketNotificationConfiguration`, and prints the response as
/// AWS-CLI-shape pretty-printed JSON followed by a newline. When the
/// bucket has no notifications configured, S3 returns success with an
/// empty body (there is no per-resource NotFound error code) and nothing
/// is printed to stdout — matching the empty-body semantics of
/// `aws s3api get-bucket-notification-configuration`, which prints nothing
/// in that case. Returns `ExitStatus::NotFound` (exit code 4) when S3
/// reports `NoSuchBucket`.
pub async fn run_get_bucket_notification_configuration(
args: GetBucketNotificationConfigurationArgs,
client_config: ClientConfig,
) -> Result<ExitStatus> {
let bucket = args
.bucket_name()
.map_err(|e| anyhow::anyhow!("{}", e.trim_end()))?;
let client = client_config.create_client().await;
match api::get_bucket_notification_configuration(&client, &bucket).await {
Ok(out) => {
let json = get_bucket_notification_configuration_to_json(&out);
if json.as_object().is_some_and(|m| m.is_empty()) {
info!(bucket = %bucket, "Bucket notification configuration not configured.");
} else {
let pretty = serde_json::to_string_pretty(&json)?;
println!("{pretty}");
}
Ok(ExitStatus::Success)
}
Err(HeadError::BucketNotFound) | Err(HeadError::NotFound) => {
// `get-bucket-notification-configuration` never returns a
// subresource NotFound — the NotFound arm is unreachable in
// practice but kept here for symmetry with the other `get_*`
// runtimes and to satisfy exhaustiveness on the shared
// `HeadError` type.
tracing::error!("bucket s3://{bucket} not found");
Ok(ExitStatus::NotFound)
}
Err(HeadError::Other(e)) => Err(e),
}
}