use std::path::PathBuf;
use clap::{Args, Command as ClapCommand};
use clap::{Parser, Subcommand};
use clap_complete::{Generator, Shell, generate};
use figlet_rs::FIGlet;
use iggy::prelude::{Args as IggyArgs, ArgsOptional as IggyArgsOptional};
use iggy_cli::commands::binary_context::common::ContextConfig;
use segment::SegmentAction;
use system::SnapshotArgs;
use crate::args::{
client::ClientAction,
cluster::ClusterAction,
consumer_group::ConsumerGroupAction,
consumer_offset::ConsumerOffsetAction,
context::ContextAction,
message::MessageAction,
partition::PartitionAction,
personal_access_token::PersonalAccessTokenAction,
stream::StreamAction,
system::{PingArgs, StatsArgs},
topic::TopicAction,
};
#[cfg(feature = "login-session")]
use crate::args::system::LoginArgs;
#[cfg(feature = "login-session")]
use crate::args::session::SessionAction;
use self::user::UserAction;
pub(crate) mod client;
pub(crate) mod cluster;
pub(crate) mod common;
pub(crate) mod consumer_group;
pub(crate) mod consumer_offset;
pub(crate) mod context;
pub(crate) mod message;
pub(crate) mod partition;
pub(crate) mod permissions;
pub(crate) mod personal_access_token;
pub(crate) mod segment;
pub(crate) mod stream;
pub(crate) mod system;
pub(crate) mod topic;
pub(crate) mod user;
#[cfg(feature = "login-session")]
pub(crate) mod session;
static CARGO_BIN_NAME: &str = env!("CARGO_BIN_NAME");
static CARGO_PKG_HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE");
#[derive(Debug, Parser)]
#[command(author, version, about, long_about = None)]
pub(crate) struct IggyConsoleArgs {
#[clap(flatten, verbatim_doc_comment)]
pub(crate) iggy: IggyArgsOptional,
#[clap(flatten, verbatim_doc_comment)]
pub(crate) cli: CliOptions,
#[clap(subcommand)]
pub(crate) command: Option<Command>,
}
#[derive(Debug, Parser)]
#[command(author, version, about, long_about = None)]
pub(crate) struct CliOptions {
#[clap(short, long, default_value_t = false)]
pub(crate) quiet: bool,
#[clap(short, long)]
pub(crate) debug: Option<PathBuf>,
#[clap(short, long, group = "credentials")]
pub(crate) username: Option<String>,
#[clap(short, long, verbatim_doc_comment)]
pub(crate) password: Option<String>,
#[clap(short, long, group = "credentials")]
pub(crate) token: Option<String>,
#[cfg(feature = "login-session")]
#[clap(short = 'n', long, group = "credentials", verbatim_doc_comment)]
pub(crate) token_name: Option<String>,
#[clap(verbatim_doc_comment)]
#[clap(long = "generate", value_enum)]
pub(crate) generator: Option<Shell>,
}
#[derive(Debug, Clone, Subcommand)]
pub(crate) enum Command {
#[command(subcommand, visible_alias = "s")]
Stream(StreamAction),
#[command(subcommand, visible_alias = "t")]
Topic(TopicAction),
#[command(subcommand, visible_alias = "p")]
Partition(PartitionAction),
#[command(subcommand, visible_alias = "seg")]
Segment(SegmentAction),
#[clap(verbatim_doc_comment)]
Ping(PingArgs),
#[clap(verbatim_doc_comment)]
Me,
#[clap(verbatim_doc_comment)]
Stats(StatsArgs),
#[clap(verbatim_doc_comment)]
Snapshot(SnapshotArgs),
#[command(subcommand)]
Pat(PersonalAccessTokenAction),
#[command(subcommand, visible_alias = "u")]
User(UserAction),
#[command(subcommand, visible_alias = "c")]
Client(ClientAction),
#[command(subcommand, visible_alias = "cl")]
Cluster(ClusterAction),
#[command(subcommand, visible_alias = "g")]
ConsumerGroup(ConsumerGroupAction),
#[command(subcommand, visible_alias = "o")]
ConsumerOffset(ConsumerOffsetAction),
#[command(subcommand, visible_alias = "m")]
Message(MessageAction),
#[command(subcommand, visible_alias = "ctx")]
Context(ContextAction),
#[cfg(feature = "login-session")]
#[clap(verbatim_doc_comment, visible_alias = "li")]
Login(LoginArgs),
#[cfg(feature = "login-session")]
#[clap(verbatim_doc_comment, visible_alias = "lo")]
Logout,
#[cfg(feature = "login-session")]
#[command(subcommand, visible_alias = "sess")]
Session(SessionAction),
}
impl IggyConsoleArgs {
pub(crate) fn generate_completion<G: Generator>(&self, generator: G) {
generate(
generator,
&mut IggyConsoleArgs::augment_args_for_update(
ClapCommand::new(CARGO_BIN_NAME).bin_name(CARGO_BIN_NAME),
),
CARGO_BIN_NAME,
&mut std::io::stdout(),
);
}
pub(crate) fn print_overview() {
let mut cli = IggyConsoleArgs::augment_args_for_update(
ClapCommand::new(CARGO_BIN_NAME).bin_name(CARGO_BIN_NAME),
);
let full_help = cli.render_help().to_string();
let help = full_help.replace(
&full_help[full_help.find("Options:").unwrap()..full_help.len()],
"",
);
let standard_font = FIGlet::standard().unwrap();
let figure = standard_font.convert("Iggy CLI").unwrap();
println!("{figure}");
println!("{help}");
println!("Run '{CARGO_BIN_NAME} --help' for full help message.");
println!("Run '{CARGO_BIN_NAME} COMMAND --help' for more information on a command.");
println!();
println!("For more help on what's Iggy and how to use it, head to {CARGO_PKG_HOMEPAGE}");
}
}
pub struct IggyMergedConsoleArgs {
pub iggy: IggyArgs,
pub cli: CliOptions,
}
impl IggyMergedConsoleArgs {
pub fn from_context(context: ContextConfig, args: IggyConsoleArgs) -> Self {
let merged_cli_options = CliOptions {
quiet: args.cli.quiet,
debug: args.cli.debug,
username: args.cli.username.or(context.username),
password: args.cli.password.or(context.password),
token: args.cli.token.or(context.token),
#[cfg(feature = "login-session")]
token_name: args.cli.token_name.or(context.token_name),
generator: args.cli.generator,
};
Self {
iggy: IggyArgs::from(vec![context.iggy, args.iggy]),
cli: merged_cli_options,
}
}
}