use internal_prelude::v1::*;
pub trait PrimitiveEnum where Self: Sized + Copy {
type Primitive: PartialEq + Sized + Copy + Debug;
fn from_primitive(val: Self::Primitive) -> Option<Self>;
fn to_primitive(&self) -> Self::Primitive;
fn from_str(s: &str) -> Option<Self>;
fn from_str_lower(s: &str) -> Option<Self>;
}
pub trait PrimitiveEnumStaticStr where Self: Sized + Copy + PrimitiveEnum {
fn to_display_str(&self) -> &'static str;
fn all_variants() -> &'static [Self];
}
#[cfg(any(feature="alloc", feature="std"))]
pub trait PrimitiveEnumDynamicStr where Self: Sized + Copy + PrimitiveEnum {
fn to_display_str(&self) -> Cow<'static, str>;
fn all_variants() -> Cow<'static, [Self]>;
}
#[derive(Copy, Clone, Debug)]
pub enum EnumCatchAll<E> where E: PrimitiveEnum {
Enum(E),
CatchAll(E::Primitive)
}
impl<E> EnumCatchAll<E> where E: PrimitiveEnum {
pub fn from_enum(v: E) -> Self {
EnumCatchAll::Enum(v)
}
}
impl<E> From<E> for EnumCatchAll<E> where E: PrimitiveEnum {
fn from(v: E) -> Self {
EnumCatchAll::Enum(v)
}
}
impl<E> PartialEq<Self> for EnumCatchAll<E> where E: PrimitiveEnum {
fn eq(&self, other: &Self) -> bool {
self.to_primitive() == other.to_primitive()
}
}
impl<E> PrimitiveEnum for EnumCatchAll<E>
where E: PrimitiveEnum
{
type Primitive = E::Primitive;
fn from_primitive(val: E::Primitive) -> Option<Self> {
match E::from_primitive(val) {
Some(p) => Some(EnumCatchAll::Enum(p)),
None => Some(EnumCatchAll::CatchAll(val))
}
}
fn to_primitive(&self) -> E::Primitive {
match *self {
EnumCatchAll::Enum(p) => p.to_primitive(),
EnumCatchAll::CatchAll(v) => v
}
}
fn from_str(s: &str) -> Option<Self> {
E::from_str(s).map(|e| EnumCatchAll::Enum(e))
}
fn from_str_lower(s: &str) -> Option<Self> {
E::from_str_lower(s).map(|e| EnumCatchAll::Enum(e))
}
}
#[cfg(any(feature="alloc", feature="std"))]
impl<E> PrimitiveEnumDynamicStr for EnumCatchAll<E>
where E: PrimitiveEnum + PrimitiveEnumDynamicStr
{
fn to_display_str(&self) -> Cow<'static, str> {
match *self {
EnumCatchAll::Enum(p) => p.to_display_str(),
EnumCatchAll::CatchAll(v) => format!("Unknown value: {:?}", v).into()
}
}
fn all_variants() -> Cow<'static, [Self]> {
let l: Vec<_> = E::all_variants().iter().map(|v| EnumCatchAll::Enum(*v)).collect();
Cow::from(l)
}
}