use std::ops::Deref;
use anyhow::Result;
use clap::{builder::PossibleValue, Parser, ValueEnum};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum Protocol {
#[cfg(unix)]
UnixSocket,
Tcp,
}
impl Protocol {
pub const ALL: &[Protocol] = &[
#[cfg(unix)]
Protocol::UnixSocket,
Protocol::Tcp,
];
}
impl ValueEnum for Protocol {
fn from_str(input: &str, ignore_case: bool) -> Result<Self, String> {
match input {
#[cfg(unix)]
p if "unix-socket" == p || ignore_case && p.eq_ignore_ascii_case("unix-socket") => {
Ok(Self::UnixSocket)
}
p if "tcp" == p || ignore_case && p.eq_ignore_ascii_case("tcp") => Ok(Self::Tcp),
p => Err(format!("Invalid protocol {p}")),
}
}
fn value_variants<'a>() -> &'a [Self] {
&[
#[cfg(unix)]
Self::UnixSocket,
Self::Tcp,
]
}
fn to_possible_value(&self) -> Option<PossibleValue> {
match self {
#[cfg(unix)]
Self::UnixSocket => Some(PossibleValue::new("unix-socket")),
Self::Tcp => Some(PossibleValue::new("tcp")),
}
}
}
impl ToString for Protocol {
fn to_string(&self) -> String {
match self {
#[cfg(unix)]
Self::UnixSocket => "unix-socket".into(),
Self::Tcp => "tcp".into(),
}
}
}
#[derive(Debug, Parser)]
pub struct ProtocolArg {
#[arg(name = "protocol", value_name = "PROTOCOL")]
pub value: Option<Protocol>,
}
impl Deref for ProtocolArg {
type Target = Option<Protocol>;
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[derive(Debug, Parser)]
pub struct ProtocolsArg {
#[arg(name = "protocols", value_name = "PROTOCOLS")]
pub value: Option<Vec<Protocol>>,
}
impl Deref for ProtocolsArg {
type Target = Option<Vec<Protocol>>;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<ProtocolsArg> for Option<Vec<Protocol>> {
fn from(arg: ProtocolsArg) -> Self {
arg.value
}
}