motdmaker/src/cli.rs

151 lines
3.8 KiB
Rust
Raw Normal View History

2025-07-10 20:36:32 -04:00
use clap::Parser;
use serde::Deserialize;
#[derive(Parser)]
#[command(name = env!("CARGO_PKG_NAME"))]
#[command(version)]
#[command(about = "Generate random messages with customizable word lists.")]
pub struct Args {
/// Specify configuration directory
#[arg(short = 'c', long)]
pub configdir: Option<String>,
/// Write output to file
#[arg(short = 'o', long)]
pub output: Option<String>,
/// Add an adjective
#[arg(short = 'a', long)]
pub adjective: Option<Vec<String>>,
/// Add a noun
#[arg(short = 'n', long)]
pub noun: Option<Vec<String>>,
/// Add a verb
#[arg(short = 'v', long)]
pub verb: Option<Vec<String>>,
/// Add an adverb
#[arg(short = 'd', long)]
pub adverb: Option<Vec<String>>,
/// Add a location
#[arg(short = 'l', long)]
pub location: Option<Vec<String>>,
/// Custom override template: "{(n)oun} {(a)djective} {(v)erb} {a(d)verb} {(l)ocation}"
#[arg(short = 't', long)]
pub template: Option<String>,
/// Replace default lists instead of extending
#[arg(short = 'r', long)]
pub replace: bool,
/// Lowercase output
#[arg(short = 'L', long)]
pub lowercase: bool,
/// Capitalize output
#[arg(short = 'U', long)]
pub uppercase: bool,
/// String to strip
#[arg(short = 's', long)]
pub strip: Option<Vec<String>>,
/// Delimiter
#[arg(short = 'D', long)]
pub delimiter: Option<String>,
/// Cut-off
#[arg(short = 'C', long)]
pub cut_off: Option<i32>,
/// Dump default lists
#[arg(short = 'p', long, value_name = "WORD_TYPE")]
pub print: Option<Option<String>>,
/// Outputs shell completion for the given shell
#[arg(long, value_name = "SHELL")]
pub completion: Option<clap_complete::Shell>,
}
#[derive(Deserialize, Default, Debug)]
pub struct RcArgs {
pub output: Option<String>,
pub adjective: Option<Vec<String>>,
pub noun: Option<Vec<String>>,
pub verb: Option<Vec<String>>,
pub adverb: Option<Vec<String>>,
pub location: Option<Vec<String>>,
pub template: Option<String>,
pub replace: Option<bool>,
pub lowercase: Option<bool>,
pub uppercase: Option<bool>,
pub strip: Option<Vec<String>>,
pub delimiter: Option<String>,
pub cut_off: Option<i32>,
}
impl Args {
pub fn merge_with_rc(mut self, rc_args: RcArgs) -> Self {
// CLI args take precedence over RC file args
// Only use RC file values if CLI values are None/false/default
if self.output.is_none() {
self.output = rc_args.output;
}
if self.adjective.is_none() {
self.adjective = rc_args.adjective;
}
if self.noun.is_none() {
self.noun = rc_args.noun;
}
if self.verb.is_none() {
self.verb = rc_args.verb;
}
if self.adverb.is_none() {
self.adverb = rc_args.adverb;
}
if self.location.is_none() {
self.location = rc_args.location;
}
if self.template.is_none() {
self.template = rc_args.template;
}
if !self.replace {
self.replace = rc_args.replace.unwrap_or(false);
}
if !self.lowercase {
self.lowercase = rc_args.lowercase.unwrap_or(false);
}
if !self.uppercase {
self.uppercase = rc_args.uppercase.unwrap_or(false);
}
if self.strip.is_none() {
self.strip = rc_args.strip;
}
if self.delimiter.is_none() {
self.delimiter = rc_args.delimiter;
}
if self.cut_off.is_none() {
self.cut_off = rc_args.cut_off;
}
self
}
}