diff --git a/clap_complete/src/dynamic/mod.rs b/clap_complete/src/dynamic/mod.rs index da62dd59..44529569 100644 --- a/clap_complete/src/dynamic/mod.rs +++ b/clap_complete/src/dynamic/mod.rs @@ -1,6 +1,8 @@ //! Complete commands within shells -pub mod bash; mod completer; +pub mod bash; +pub mod shells; + pub use completer::*; diff --git a/clap_complete/src/dynamic/shells/mod.rs b/clap_complete/src/dynamic/shells/mod.rs new file mode 100644 index 00000000..a56cbba0 --- /dev/null +++ b/clap_complete/src/dynamic/shells/mod.rs @@ -0,0 +1,5 @@ +//! Shell support + +mod shell; + +pub use shell::*; diff --git a/clap_complete/src/dynamic/shells/shell.rs b/clap_complete/src/dynamic/shells/shell.rs new file mode 100644 index 00000000..bde2757a --- /dev/null +++ b/clap_complete/src/dynamic/shells/shell.rs @@ -0,0 +1,48 @@ +use std::fmt::Display; +use std::str::FromStr; + +use clap::builder::PossibleValue; +use clap::ValueEnum; + +/// Shell with auto-generated completion script available. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[non_exhaustive] +pub enum Shell { + /// Bourne Again SHell (bash) + Bash, +} + +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 { + for variant in Self::value_variants() { + if variant.to_possible_value().unwrap().matches(s, false) { + return Ok(*variant); + } + } + Err(format!("invalid variant: {s}")) + } +} + +// Hand-rolled so it can work even when `derive` feature is disabled +impl ValueEnum for Shell { + fn value_variants<'a>() -> &'a [Self] { + &[Shell::Bash] + } + + fn to_possible_value<'a>(&self) -> Option { + Some(match self { + Shell::Bash => PossibleValue::new("bash"), + }) + } +}