use std::collections::HashSet;
use std::fmt::{self, Debug, Display};
use std::hash::Hash;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EnumMatcher<E: EnumPredicate> {
Equals(E),
NotEquals(E),
In(HashSet<E>),
}
pub trait EnumPredicate: Sized + Eq + Hash + Clone + Debug {
fn from_str(s: &str) -> Result<Self, String>;
fn all_valid_strings() -> &'static [&'static str];
fn as_str(&self) -> &'static str;
fn aliases(&self) -> &'static [&'static str];
}
impl<E: EnumPredicate> EnumMatcher<E> {
pub fn is_match(&self, value: &E) -> bool {
match self {
EnumMatcher::Equals(v) => value == v,
EnumMatcher::NotEquals(v) => value != v,
EnumMatcher::In(set) => set.contains(value),
}
}
}
impl<E: EnumPredicate> Display for EnumMatcher<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EnumMatcher::Equals(v) => write!(f, "== {}", v.as_str()),
EnumMatcher::NotEquals(v) => write!(f, "!= {}", v.as_str()),
EnumMatcher::In(set) => {
write!(f, "in [")?;
let mut items: Vec<_> = set.iter().map(EnumPredicate::as_str).collect();
items.sort_unstable(); write!(f, "{}", items.join(", "))?;
write!(f, "]")
}
}
}
}