mod engine;
mod script;
use std::{fmt, str::FromStr};
pub(crate) use engine::process_request;
const PROTOCOL_ENV: &str = "ARGX_COMPLETE";
const PROTOCOL_VERSION: &str = "1";
const PROTOCOL_COMMAND: &str = "__argx_complete__";
const PROTOCOL_LINE_ENV: &str = "ARGX_COMPLETE_LINE";
const PROTOCOL_WORDS_ENV: &str = "ARGX_COMPLETE_WORDS";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Shell {
Bash,
Fish,
Nushell,
Zsh,
}
impl Shell {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Bash => "bash",
Self::Fish => "fish",
Self::Nushell => "nushell",
Self::Zsh => "zsh",
}
}
}
impl fmt::Display for Shell {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
impl crate::ValueEnum for Shell {
const VALUES: &'static [&'static str] = &["bash", "fish", "nushell", "zsh"];
fn from_value(value: &str) -> Option<Self> {
match value {
"bash" => Some(Self::Bash),
"fish" => Some(Self::Fish),
"nushell" => Some(Self::Nushell),
"zsh" => Some(Self::Zsh),
_ => None,
}
}
}
impl FromStr for Shell {
type Err = crate::ValueEnumError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
<Self as crate::ValueEnum>::from_value(value)
.ok_or_else(|| crate::ValueEnumError::new(<Self as crate::ValueEnum>::VALUES))
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum ScriptError {
#[error(
"cannot generate completions for `{name}`: the command name must be one plain shell word, must not start with `-`, and may contain only ASCII letters, digits, `-`, `_`, `.`, or `+`"
)]
InvalidCommandName {
name: String,
},
}
pub(crate) fn script(command: &str, shell: Shell) -> Result<String, ScriptError> {
script::render(command, shell)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shell_names_parse_and_render() {
assert_eq!("bash".parse(), Ok(Shell::Bash));
assert_eq!(Shell::Fish.to_string(), "fish");
assert_eq!("nushell".parse(), Ok(Shell::Nushell));
assert_eq!(Shell::Nushell.to_string(), "nushell");
assert_eq!(<Shell as crate::ValueEnum>::VALUES, &["bash", "fish", "nushell", "zsh"],);
assert!("nu".parse::<Shell>().is_err());
}
}