mongodb-command-cli 0.1.1

Mongodb tool
Documentation
use anyhow::Result;
use clap::{Parser, Subcommand};
use std::path::PathBuf;

mod copier;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
    /// Optional name to operate on
    name: Option<String>,

    /// Sets a custom config file
    #[arg(short, long, value_name = "FILE")]
    config: Option<PathBuf>,

    /// Turn debugging information on
    #[arg(short, long, action = clap::ArgAction::Count)]
    debug: u8,

    #[command(subcommand)]
    command: Option<Commands>,
}

#[derive(Subcommand)]
enum Commands {
    /// does testing things
    Test {
        /// lists test values
        #[arg(short, long)]
        list: bool,
    },
    /// Copy documents between mongodb instances.
    CopyDocs {
        #[arg(short, long)]
        database: String,
        #[arg(short, long)]
        collection: String,
        #[arg( long)]
        id: Option<String>,
        #[arg(long)]
        filter_str: Option<String>,
        #[arg(short, long)]
        from: String,
        #[arg(short, long)]
        to: String,
        #[arg(short, long)]
        ignore_error: Option<bool>,
    },

    /// Creates a new user on the database where you run the command.
    CreateUser {
        name: String,
        pwd: String,
        roles: Vec<String>,
    },
    /// Removes the user from the database on which you run the command.
    DropUser { name: String },
    /// Grants additional roles to a user.
    GrantUser { name: String, roles: Vec<String> },
    /// Removes a one or more roles from a user on the database where the roles exist.
    RevokeUser { name: String, roles: Vec<String> },
    /// Updates the user's profile on the database on which you run the command.
    UpdateUser {
        name: String,
        pwd: String,
        roles: Vec<String>,
    },
    /// Returns information about one or more users.
    UsersInfo,

    /// xx
    CreateRole,
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = Cli::parse();

    // You can check the value provided by positional arguments, or option arguments
    if let Some(name) = cli.name.as_deref() {
        println!("Value for name: {}", name);
    }

    if let Some(config_path) = cli.config.as_deref() {
        println!("Value for config: {}", config_path.display());
    }

    // You can see how many times a particular flag or argument occurred
    // Note, only flags can have multiple occurrences
    match cli.debug {
        0 => println!("Debug mode is off"),
        1 => println!("Debug mode is kind of on"),
        2 => println!("Debug mode is on"),
        _ => println!("Don't be crazy"),
    }

    // You can check for the existence of subcommands, and if found use their
    // matches just as you would the top level cmd
    match &cli.command {
        Some(Commands::Test { list }) => {
            if *list {
                println!("Printing testing lists...");
            } else {
                println!("Not printing testing lists...");
            }
            Ok(())
        }
        Some(Commands::CopyDocs {
            database,
            collection,
            id,
            filter_str,
            from,
            to,
            ignore_error,
        }) => copier::copy_docs(copier::Param {
            database: database.to_owned(),
            collection: collection.to_owned(),
            id: id.to_owned(),
            filter_str: filter_str.to_owned(),
            from: from.to_owned(),
            to: to.to_owned(),
            ignore_error: ignore_error.to_owned()
        }).await,

        Some(_) => {
            Ok(())
        },

        None => {
            Ok(())
        }
    }

    // Continued program logic goes here...
}