use std::path::PathBuf;
use clap::{builder::PossibleValue, Parser};
#[derive(Parser)]
#[command(
name = "rust-petname",
version,
author,
after_help = "Based on Dustin Kirkland's petname project <https://github.com/dustinkirkland/petname>."
)]
pub struct Cli {
#[arg(short, long, value_name = "WORDS", default_value_t = 2)]
pub words: u8,
#[arg(short, long, value_name = "SEP", default_value = "-")]
pub separator: String,
#[arg(long, value_name = "LIST", default_value_t = WordList::Medium)]
pub lists: WordList,
#[arg(short, long, value_name = "NUM", default_value = None, conflicts_with = "lists", hide_possible_values = true)]
pub complexity: Option<WordList>,
#[arg(short, long = "dir", value_name = "DIR", conflicts_with = "lists")]
pub directory: Option<PathBuf>,
#[arg(long, value_name = "COUNT", default_value_t = 1)]
pub count: usize,
#[arg(long, conflicts_with = "count")]
pub stream: bool,
#[arg(short, long, value_name = "LETTERS", default_value_t = 0)]
pub letters: usize,
#[arg(short, long)]
pub alliterate: bool,
#[arg(short = 'A', long, value_name = "LETTER")]
pub alliterate_with: Option<char>,
#[arg(short, long, conflicts_with = "alliterate", conflicts_with = "alliterate_with")]
pub ubuntu: bool,
#[arg(long, value_name = "SEED")]
pub seed: Option<u64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum WordList {
Small,
Medium,
Large,
}
impl std::fmt::Display for WordList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Small => write!(f, "small"),
Self::Medium => write!(f, "medium"),
Self::Large => write!(f, "large"),
}
}
}
impl clap::ValueEnum for WordList {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Small, Self::Medium, Self::Large]
}
fn to_possible_value(&self) -> Option<PossibleValue> {
Some(match self {
Self::Small => PossibleValue::new("small").alias("0"),
Self::Medium => PossibleValue::new("medium").alias("1"),
Self::Large => PossibleValue::new("large").alias("2"),
})
}
}
#[cfg(test)]
mod compatibility {
use clap::Parser;
use super::{Cli, WordList};
#[test]
fn compat_words() {
assert_eq!(Cli::parse_from(["petname"]).words, 2);
assert_eq!(Cli::parse_from(["petname", "-w", "7"]).words, 7);
assert_eq!(Cli::parse_from(["petname", "--words", "5"]).words, 5);
assert_eq!(Cli::parse_from(["petname", "--words=6"]).words, 6);
}
#[test]
fn compat_letters() {
assert_eq!(Cli::parse_from(["petname"]).letters, 0); assert_eq!(Cli::parse_from(["petname", "-l", "7"]).letters, 7);
assert_eq!(Cli::parse_from(["petname", "--letters", "5"]).letters, 5);
assert_eq!(Cli::parse_from(["petname", "--letters=6"]).letters, 6);
}
#[test]
fn compat_separator() {
assert_eq!(Cli::parse_from(["petname"]).separator, "-");
assert_eq!(Cli::parse_from(["petname", "-s", ":"]).separator, ":");
assert_eq!(Cli::parse_from(["petname", "--separator", "|"]).separator, "|");
assert_eq!(Cli::parse_from(["petname", "--separator=."]).separator, ".");
}
#[test]
fn compat_complexity() {
assert_eq!(Cli::parse_from(["petname"]).complexity, None);
assert_eq!(Cli::parse_from(["petname", "-c", "0"]).complexity, Some(WordList::Small));
assert_eq!(Cli::parse_from(["petname", "--complexity", "1"]).complexity, Some(WordList::Medium));
assert_eq!(Cli::parse_from(["petname", "--complexity=2"]).complexity, Some(WordList::Large));
}
#[test]
fn compat_ubuntu() {
assert!(!Cli::parse_from(["petname"]).ubuntu);
assert!(Cli::parse_from(["petname", "-u"]).ubuntu);
assert!(Cli::parse_from(["petname", "--ubuntu"]).ubuntu);
}
}