use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("unrecognized auth type: {0:?}")]
pub struct ParseAuthTypeError(pub String);
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("unrecognized auth retry mode: {0:?}")]
pub struct ParseAuthRetryModeError(pub String);
#[derive(Debug, Clone, PartialEq, Eq, strum::Display)]
pub enum AuthType {
Auth,
#[strum(to_string = "Private Key")]
PrivateKey,
#[strum(to_string = "HTTP Proxy")]
HttpProxy,
#[strum(to_string = "SOCKS Proxy")]
SocksProxy,
#[strum(default)]
Unknown(String),
}
impl FromStr for AuthType {
type Err = ParseAuthTypeError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"Auth" => Ok(Self::Auth),
"Private Key" => Ok(Self::PrivateKey),
"HTTP Proxy" => Ok(Self::HttpProxy),
"SOCKS Proxy" => Ok(Self::SocksProxy),
other => Err(ParseAuthTypeError(other.to_string())),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::Display)]
#[strum(serialize_all = "lowercase")]
pub enum AuthRetryMode {
None,
Interact,
#[strum(to_string = "nointeract")]
NoInteract,
}
impl FromStr for AuthRetryMode {
type Err = ParseAuthRetryModeError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"none" => Ok(Self::None),
"interact" => Ok(Self::Interact),
"nointeract" => Ok(Self::NoInteract),
other => Err(ParseAuthRetryModeError(other.to_string())),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_case::test_case;
#[test_case(AuthType::Auth)]
#[test_case(AuthType::PrivateKey)]
#[test_case(AuthType::HttpProxy)]
#[test_case(AuthType::SocksProxy)]
fn auth_type_roundtrip(at: AuthType) {
let string = at.to_string();
assert_eq!(string.parse::<AuthType>().unwrap(), at);
}
#[test]
fn auth_type_phantom_aliases_are_rejected() {
assert!("PrivateKey".parse::<AuthType>().is_err());
assert!("HTTPProxy".parse::<AuthType>().is_err());
assert!("SOCKSProxy".parse::<AuthType>().is_err());
}
#[test]
fn auth_type_unknown_is_err() {
assert!("MyPlugin".parse::<AuthType>().is_err());
}
#[test_case(AuthRetryMode::None)]
#[test_case(AuthRetryMode::Interact)]
#[test_case(AuthRetryMode::NoInteract)]
fn auth_retry_roundtrip(mode: AuthRetryMode) {
let string = mode.to_string();
assert_eq!(string.parse::<AuthRetryMode>().unwrap(), mode);
}
#[test]
fn auth_retry_invalid() {
assert!("bogus".parse::<AuthRetryMode>().is_err());
}
}