use crate::config::Config;
use clap::{Parser, Subcommand};
use std::ffi::OsString;
#[cfg(feature = "version")]
use shadow_rs::shadow;
#[cfg(feature = "version")]
shadow!(build);
pub mod common;
pub mod common_client;
pub mod cp;
pub mod create_bucket;
pub mod delete_bucket;
pub mod delete_bucket_policy;
pub mod delete_bucket_tagging;
pub mod delete_object_tagging;
pub mod get_bucket_policy;
pub mod get_bucket_tagging;
pub mod get_bucket_versioning;
pub mod get_object_tagging;
pub mod head_bucket;
pub mod head_object;
pub mod mv;
pub mod put_bucket_policy;
pub mod put_bucket_tagging;
pub mod put_bucket_versioning;
pub mod put_object_tagging;
pub mod rm;
pub mod value_parser;
#[cfg(test)]
mod tests;
pub use cp::CpArgs;
pub use create_bucket::CreateBucketArgs;
pub use delete_bucket::DeleteBucketArgs;
pub use delete_bucket_policy::DeleteBucketPolicyArgs;
pub use delete_bucket_tagging::DeleteBucketTaggingArgs;
pub use delete_object_tagging::DeleteObjectTaggingArgs;
pub use get_bucket_policy::GetBucketPolicyArgs;
pub use get_bucket_tagging::GetBucketTaggingArgs;
pub use get_bucket_versioning::GetBucketVersioningArgs;
pub use get_object_tagging::GetObjectTaggingArgs;
pub use head_bucket::HeadBucketArgs;
pub use head_object::HeadObjectArgs;
pub use mv::MvArgs;
pub use put_bucket_policy::PutBucketPolicyArgs;
pub use put_bucket_tagging::PutBucketTaggingArgs;
pub use put_bucket_versioning::PutBucketVersioningArgs;
pub use put_object_tagging::PutObjectTaggingArgs;
pub use rm::RmArgs;
#[cfg(test)]
pub(crate) use common::TARGET_LOCAL_DIRECTORY_DOES_NOT_EXIST_PREFIX;
const EXPRESS_ONEZONE_STORAGE_SUFFIX: &str = "--x-s3";
#[derive(Parser, Clone, Debug)]
#[cfg_attr(
feature = "version",
command(version = format!(
"{} ({} {}), {}",
build::PKG_VERSION,
build::SHORT_COMMIT,
build::BUILD_TARGET,
build::RUST_VERSION
))
)]
#[cfg_attr(not(feature = "version"), command(version))]
#[command(name = "s3util", about = "S3 utility commands")]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand, Clone, Debug)]
pub enum Commands {
#[command(display_order = 1)]
Cp(CpArgs),
#[command(display_order = 8)]
CreateBucket(CreateBucketArgs),
#[command(display_order = 10)]
DeleteBucket(DeleteBucketArgs),
#[command(display_order = 13)]
DeleteBucketPolicy(DeleteBucketPolicyArgs),
#[command(display_order = 16)]
DeleteBucketTagging(DeleteBucketTaggingArgs),
#[command(display_order = 7)]
DeleteObjectTagging(DeleteObjectTaggingArgs),
#[command(display_order = 12)]
GetBucketPolicy(GetBucketPolicyArgs),
#[command(display_order = 15)]
GetBucketTagging(GetBucketTaggingArgs),
#[command(display_order = 18)]
GetBucketVersioning(GetBucketVersioningArgs),
#[command(display_order = 6)]
GetObjectTagging(GetObjectTaggingArgs),
#[command(display_order = 9)]
HeadBucket(HeadBucketArgs),
#[command(display_order = 4)]
HeadObject(HeadObjectArgs),
#[command(display_order = 2)]
Mv(MvArgs),
#[command(display_order = 11)]
PutBucketPolicy(PutBucketPolicyArgs),
#[command(display_order = 14)]
PutBucketTagging(PutBucketTaggingArgs),
#[command(display_order = 17)]
PutBucketVersioning(PutBucketVersioningArgs),
#[command(display_order = 5)]
PutObjectTagging(PutObjectTaggingArgs),
#[command(display_order = 3)]
Rm(RmArgs),
}
pub fn parse_from_args<I, T>(args: I) -> Result<Cli, clap::Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
Cli::try_parse_from(args)
}
pub fn build_config_from_args<I, T>(args: I) -> Result<Config, String>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let cli = Cli::try_parse_from(args).map_err(|e| e.to_string())?;
match cli.command {
Commands::Cp(cp_args) => Config::try_from(cp_args),
Commands::CreateBucket(_) => Err(
"build_config_from_args is for cp/mv only; create-bucket is dispatched in main.rs"
.to_string(),
),
Commands::DeleteBucket(_) => Err(
"build_config_from_args is for cp/mv only; delete-bucket is dispatched in main.rs"
.to_string(),
),
Commands::DeleteBucketPolicy(_) => Err(
"build_config_from_args is for cp/mv only; delete-bucket-policy is dispatched in main.rs"
.to_string(),
),
Commands::DeleteBucketTagging(_) => Err(
"build_config_from_args is for cp/mv only; delete-bucket-tagging is dispatched in main.rs"
.to_string(),
),
Commands::DeleteObjectTagging(_) => Err(
"build_config_from_args is for cp/mv only; delete-object-tagging is dispatched in main.rs"
.to_string(),
),
Commands::GetBucketPolicy(_) => Err(
"build_config_from_args is for cp/mv only; get-bucket-policy is dispatched in main.rs"
.to_string(),
),
Commands::GetBucketTagging(_) => Err(
"build_config_from_args is for cp/mv only; get-bucket-tagging is dispatched in main.rs"
.to_string(),
),
Commands::GetBucketVersioning(_) => Err(
"build_config_from_args is for cp/mv only; get-bucket-versioning is dispatched in main.rs"
.to_string(),
),
Commands::GetObjectTagging(_) => Err(
"build_config_from_args is for cp/mv only; get-object-tagging is dispatched in main.rs"
.to_string(),
),
Commands::HeadBucket(_) => Err(
"build_config_from_args is for cp/mv only; head-bucket is dispatched in main.rs"
.to_string(),
),
Commands::HeadObject(_) => Err(
"build_config_from_args is for cp/mv only; head-object is dispatched in main.rs"
.to_string(),
),
Commands::Mv(mv_args) => Config::try_from(mv_args),
Commands::PutBucketPolicy(_) => Err(
"build_config_from_args is for cp/mv only; put-bucket-policy is dispatched in main.rs"
.to_string(),
),
Commands::PutBucketTagging(_) => Err(
"build_config_from_args is for cp/mv only; put-bucket-tagging is dispatched in main.rs"
.to_string(),
),
Commands::PutBucketVersioning(_) => Err(
"build_config_from_args is for cp/mv only; put-bucket-versioning is dispatched in main.rs"
.to_string(),
),
Commands::PutObjectTagging(_) => Err(
"build_config_from_args is for cp/mv only; put-object-tagging is dispatched in main.rs"
.to_string(),
),
Commands::Rm(_) => {
Err("build_config_from_args is for cp/mv only; rm is dispatched in main.rs".to_string())
}
}
}
pub(crate) fn is_express_onezone_storage(bucket: &str) -> bool {
bucket.ends_with(EXPRESS_ONEZONE_STORAGE_SUFFIX)
}