rustfs_cli/commands/
mod.rs

1//! CLI command definitions and execution
2//!
3//! This module contains all CLI commands and their implementations.
4//! Commands are organized by functionality and follow the pattern established
5//! in the command implementation template.
6
7use clap::{Parser, Subcommand};
8
9use crate::exit_code::ExitCode;
10use crate::output::OutputConfig;
11
12mod alias;
13mod cat;
14mod completions;
15pub mod cp;
16pub mod diff;
17mod find;
18mod head;
19mod ls;
20mod mb;
21mod mirror;
22mod mv;
23mod pipe;
24mod rb;
25mod rm;
26mod share;
27mod stat;
28mod tag;
29mod tree;
30mod version;
31
32/// rc - Rust S3 CLI Client
33///
34/// A command-line interface for S3-compatible object storage services.
35/// Supports RustFS, AWS S3, and other S3-compatible backends.
36#[derive(Parser, Debug)]
37#[command(name = "rc")]
38#[command(author, version, about, long_about = None)]
39#[command(propagate_version = true)]
40pub struct Cli {
41    /// Output format: human-readable or JSON
42    #[arg(long, global = true, default_value = "false")]
43    pub json: bool,
44
45    /// Disable colored output
46    #[arg(long, global = true, default_value = "false")]
47    pub no_color: bool,
48
49    /// Disable progress bar
50    #[arg(long, global = true, default_value = "false")]
51    pub no_progress: bool,
52
53    /// Suppress non-error output
54    #[arg(short, long, global = true, default_value = "false")]
55    pub quiet: bool,
56
57    /// Enable debug logging
58    #[arg(long, global = true, default_value = "false")]
59    pub debug: bool,
60
61    #[command(subcommand)]
62    pub command: Commands,
63}
64
65#[derive(Subcommand, Debug)]
66pub enum Commands {
67    /// Manage storage service aliases
68    #[command(subcommand)]
69    Alias(alias::AliasCommands),
70
71    // Phase 2: Basic commands
72    /// List buckets and objects
73    Ls(ls::LsArgs),
74
75    /// Create a bucket
76    Mb(mb::MbArgs),
77
78    /// Remove a bucket
79    Rb(rb::RbArgs),
80
81    /// Display object contents
82    Cat(cat::CatArgs),
83
84    /// Display first N lines of an object
85    Head(head::HeadArgs),
86
87    /// Show object metadata
88    Stat(stat::StatArgs),
89
90    // Phase 3: Transfer commands
91    /// Copy objects (local<->S3, S3<->S3)
92    Cp(cp::CpArgs),
93
94    /// Move objects (copy + delete source)
95    Mv(mv::MvArgs),
96
97    /// Remove objects
98    Rm(rm::RmArgs),
99
100    /// Stream stdin to an object
101    Pipe(pipe::PipeArgs),
102
103    // Phase 4: Advanced commands
104    /// Find objects matching criteria
105    Find(find::FindArgs),
106
107    /// Show differences between locations
108    Diff(diff::DiffArgs),
109
110    /// Mirror objects between locations
111    Mirror(mirror::MirrorArgs),
112
113    /// Display objects in tree format
114    Tree(tree::TreeArgs),
115
116    /// Generate presigned URLs
117    Share(share::ShareArgs),
118
119    // Phase 5: Optional commands (capability-dependent)
120    /// Manage bucket versioning
121    #[command(subcommand)]
122    Version(version::VersionCommands),
123
124    /// Manage object tags
125    #[command(subcommand)]
126    Tag(tag::TagCommands),
127
128    // Phase 6: Utilities
129    /// Generate shell completion scripts
130    Completions(completions::CompletionsArgs),
131    // /// Manage object retention
132    // Retention(retention::RetentionArgs),
133    // /// Watch for object events
134    // Watch(watch::WatchArgs),
135    // /// Run S3 Select queries
136    // Sql(sql::SqlArgs),
137}
138
139/// Execute the CLI command and return an exit code
140pub async fn execute(cli: Cli) -> ExitCode {
141    let output_config = OutputConfig {
142        json: cli.json,
143        no_color: cli.no_color,
144        no_progress: cli.no_progress,
145        quiet: cli.quiet,
146    };
147
148    match cli.command {
149        Commands::Alias(cmd) => alias::execute(cmd, cli.json).await,
150        Commands::Ls(args) => ls::execute(args, output_config).await,
151        Commands::Mb(args) => mb::execute(args, output_config).await,
152        Commands::Rb(args) => rb::execute(args, output_config).await,
153        Commands::Cat(args) => cat::execute(args, output_config).await,
154        Commands::Head(args) => head::execute(args, output_config).await,
155        Commands::Stat(args) => stat::execute(args, output_config).await,
156        Commands::Cp(args) => cp::execute(args, output_config).await,
157        Commands::Mv(args) => mv::execute(args, output_config).await,
158        Commands::Rm(args) => rm::execute(args, output_config).await,
159        Commands::Pipe(args) => pipe::execute(args, output_config).await,
160        Commands::Find(args) => find::execute(args, output_config).await,
161        Commands::Diff(args) => diff::execute(args, output_config).await,
162        Commands::Mirror(args) => mirror::execute(args, output_config).await,
163        Commands::Tree(args) => tree::execute(args, output_config).await,
164        Commands::Share(args) => share::execute(args, output_config).await,
165        Commands::Version(cmd) => {
166            version::execute(version::VersionArgs { command: cmd }, output_config).await
167        }
168        Commands::Tag(cmd) => tag::execute(tag::TagArgs { command: cmd }, output_config).await,
169        Commands::Completions(args) => completions::execute(args),
170    }
171}