use clap::builder::{
Styles,
styling::{AnsiColor, Effects},
};
use clap::{Args, Parser, ValueEnum, ValueHint};
use clap_complete::Shell;
use crate::error::OpenStackCliError;
use crate::config::{Config, ConfigError};
pub fn styles() -> Styles {
Styles::styled()
.header(AnsiColor::Green.on_default() | Effects::BOLD)
.usage(AnsiColor::Green.on_default() | Effects::BOLD)
.literal(AnsiColor::White.on_default() | Effects::BOLD)
.placeholder(AnsiColor::Cyan.on_default())
}
pub trait CliArgs {
fn global_opts(&self) -> &GlobalOpts;
fn config(&self) -> &Config;
}
pub fn parse_config(s: &str) -> Result<Config, OpenStackCliError> {
let mut builder = Config::builder()?;
if !s.is_empty() {
builder = builder.add_source(s).map_err(ConfigError::builder)?;
}
Ok(builder.build()?)
}
#[derive(Args)]
#[command(next_display_order = 800, next_help_heading = "Connection options")]
pub struct ConnectionOpts {
#[arg(long, env = "OS_CLOUD", global = true, display_order = 801, conflicts_with_all(["cloud_config_from_env", "os_cloud_name"]))]
pub os_cloud: Option<String>,
#[arg(long, global = true, action = clap::ArgAction::SetTrue, display_order = 802)]
pub cloud_config_from_env: bool,
#[arg(long, env = "OS_CLOUD_NAME", global = true, display_order = 802)]
pub os_cloud_name: Option<String>,
#[arg(long, env = "OS_PROJECT_ID", global = true, display_order = 803)]
pub os_project_id: Option<String>,
#[arg(long, env = "OS_PROJECT_NAME", global = true, display_order = 803)]
pub os_project_name: Option<String>,
#[arg(long, env = "OS_REGION_NAME", global = true, display_order = 804)]
pub os_region_name: Option<String>,
#[arg(
long,
env = "OS_CLIENT_CONFIG_FILE",
global = true,
value_hint = ValueHint::FilePath,
display_order = 805
)]
pub os_client_config_file: Option<String>,
#[arg(
long,
env = "OS_CLIENT_SECURE_FILE",
global = true,
value_hint = ValueHint::FilePath,
display_order = 805
)]
pub os_client_secure_file: Option<String>,
#[arg(long, global = true, value_hint = ValueHint::ExecutablePath, display_order = 810)]
pub auth_helper_cmd: Option<String>,
}
#[derive(Args)]
#[command(next_display_order = 900, next_help_heading = "Output options")]
pub struct OutputOpts {
#[arg(short, long, global = true, value_enum, display_order = 910)]
pub output: Option<OutputFormat>,
#[arg(short, long, global=true, action=clap::ArgAction::Append, display_order = 910)]
pub fields: Vec<String>,
#[arg(short, long, global=true, action = clap::ArgAction::SetTrue, display_order = 910)]
pub pretty: bool,
#[arg(short, long, global=true, action = clap::ArgAction::Count, display_order = 920)]
pub verbose: u8,
#[arg(long, global=true, default_value_t = TableArrangement::Dynamic, value_enum, display_order = 930)]
pub table_arrangement: TableArrangement,
#[arg(long, global=true, action = clap::ArgAction::SetTrue, display_order = 950)]
pub timing: bool,
}
#[derive(Args)]
#[command(next_display_order = 900)]
pub struct GlobalOpts {
#[command(flatten)]
pub connection: ConnectionOpts,
#[command(flatten)]
pub output: OutputOpts,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum OutputFormat {
Json,
Wide,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum TableArrangement {
#[default]
Dynamic,
DynamicFullWidth,
Disabled,
}
#[derive(Parser, Debug)]
pub struct CompletionCommand {
#[arg(default_value_t = Shell::Bash)]
pub shell: Shell,
}