Skip to main content

s3util_rs/config/args/
mv.rs

1use crate::config::Config;
2use crate::config::args::common::CommonTransferArgs;
3use crate::config::args::value_parser::storage_path;
4use crate::types::StoragePath;
5use clap::Parser;
6
7const STDIO_NOT_SUPPORTED: &str = "stdin/stdout (-) is not supported by mv\n";
8
9#[derive(Parser, Clone, Debug)]
10pub struct MvArgs {
11    #[arg(env, help = "s3://<BUCKET_NAME>[/prefix] or local path", value_parser = storage_path::check_storage_path, required_unless_present = "auto_complete_shell")]
12    pub source: Option<String>,
13
14    #[arg(env, help = "s3://<BUCKET_NAME>[/prefix] or local path", value_parser = storage_path::check_storage_path, required_unless_present = "auto_complete_shell")]
15    pub target: Option<String>,
16
17    #[command(flatten)]
18    pub common: CommonTransferArgs,
19
20    /// Treat ETag/checksum verify warnings as success: delete source and exit 0.
21    #[arg(long, env, default_value_t = false, help_heading = "Verification")]
22    pub no_fail_on_verify_error: bool,
23}
24
25impl MvArgs {
26    pub fn auto_complete_shell(&self) -> Option<clap_complete::shells::Shell> {
27        self.common.auto_complete_shell
28    }
29
30    fn source_str(&self) -> &str {
31        self.source.as_deref().unwrap_or("")
32    }
33
34    fn target_str(&self) -> &str {
35        self.target.as_deref().unwrap_or("")
36    }
37
38    fn is_source_stdio(&self) -> bool {
39        matches!(
40            storage_path::parse_storage_path(self.source_str()),
41            StoragePath::Stdio
42        )
43    }
44
45    fn is_target_stdio(&self) -> bool {
46        matches!(
47            storage_path::parse_storage_path(self.target_str()),
48            StoragePath::Stdio
49        )
50    }
51
52    fn check_no_stdio(&self) -> Result<(), String> {
53        if self.is_source_stdio() || self.is_target_stdio() {
54            return Err(STDIO_NOT_SUPPORTED.to_string());
55        }
56        Ok(())
57    }
58
59    fn validate_storage_config(&self) -> Result<(), String> {
60        let source = self.source_str();
61        let target = self.target_str();
62        self.check_no_stdio()?;
63        self.common.validate_common_storage_config(source, target)?;
64        Ok(())
65    }
66}
67
68impl TryFrom<MvArgs> for Config {
69    type Error = String;
70
71    fn try_from(value: MvArgs) -> Result<Self, Self::Error> {
72        value.validate_storage_config()?;
73        let no_fail_on_verify_error = value.no_fail_on_verify_error;
74        let mut config = crate::config::args::common::build_config_from_common(
75            value.common,
76            value.source,
77            value.target,
78        )?;
79        config.no_fail_on_verify_error = no_fail_on_verify_error;
80        Ok(config)
81    }
82}