use std::fmt::Display;
use std::str::FromStr;
use clap::{ArgEnum, PossibleValue};
use crate::shells;
use crate::Generator;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum Shell {
Bash,
Elvish,
Fish,
PowerShell,
Zsh,
}
impl Shell {
#[deprecated(
since = "3.2.0",
note = "Replaced with `EnumValueParser`
Builder API: Instead of `arg.possible_values(Shell::possible_values())`, use `arg.value_parser(value_parser!(Shell))`
"
)]
pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
Shell::value_variants()
.iter()
.filter_map(ArgEnum::to_possible_value)
}
}
impl Display for Shell {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_possible_value()
.expect("no values are skipped")
.get_name()
.fmt(f)
}
}
impl FromStr for Shell {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
for variant in Self::value_variants() {
if variant.to_possible_value().unwrap().matches(s, false) {
return Ok(*variant);
}
}
Err(format!("Invalid variant: {}", s))
}
}
impl ArgEnum for Shell {
fn value_variants<'a>() -> &'a [Self] {
&[
Shell::Bash,
Shell::Elvish,
Shell::Fish,
Shell::PowerShell,
Shell::Zsh,
]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue<'a>> {
Some(match self {
Shell::Bash => PossibleValue::new("bash"),
Shell::Elvish => PossibleValue::new("elvish"),
Shell::Fish => PossibleValue::new("fish"),
Shell::PowerShell => PossibleValue::new("powershell"),
Shell::Zsh => PossibleValue::new("zsh"),
})
}
}
impl Generator for Shell {
fn file_name(&self, name: &str) -> String {
match self {
Shell::Bash => shells::Bash.file_name(name),
Shell::Elvish => shells::Elvish.file_name(name),
Shell::Fish => shells::Fish.file_name(name),
Shell::PowerShell => shells::PowerShell.file_name(name),
Shell::Zsh => shells::Zsh.file_name(name),
}
}
fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::Write) {
match self {
Shell::Bash => shells::Bash.generate(cmd, buf),
Shell::Elvish => shells::Elvish.generate(cmd, buf),
Shell::Fish => shells::Fish.generate(cmd, buf),
Shell::PowerShell => shells::PowerShell.generate(cmd, buf),
Shell::Zsh => shells::Zsh.generate(cmd, buf),
}
}
}