#![feature(specialization)]
use std::{convert::TryInto, fmt};
use tyenum::tyenum;
#[derive(Debug, PartialEq)]
struct A;
impl fmt::Display for A {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "A")
}
}
#[derive(Debug, PartialEq)]
struct B;
impl fmt::Display for B {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "B")
}
}
#[derive(Debug, PartialEq)]
struct C;
#[tyenum(derive = [Name], trait_obj = [fmt::Display])]
#[derive(Debug, PartialEq)]
enum Test {
A,
BB(B),
C(C),
}
trait Name {
fn name(&self) -> String;
}
impl Name for A {
fn name(&self) -> String {
String::from("A")
}
}
impl Name for B {
fn name(&self) -> String {
String::from("B")
}
}
impl Name for C {
fn name(&self) -> String {
String::from("C")
}
}
#[tyenum]
enum AnotherEnum {
A,
B,
}
#[test]
fn into() {
assert_eq!(Test::A(A), A.into());
assert_eq!(Test::BB(B), B.into());
assert_ne!(Test::A(A), C.into());
}
#[test]
fn is() {
assert!(Test::A(A).is::<A>());
assert!(Test::BB(B).is::<B>());
assert!(!Test::C(C).is::<A>());
}
#[test]
fn try_into() {
assert_eq!(Test::A(A).try_into(), Ok(A));
assert_eq!(Test::BB(B).try_into(), Ok(B));
let a: Result<A, _> = Test::C(C).try_into();
assert_eq!(a, Err(tyenum::TryFromTyenumError));
}
#[test]
fn derive() {
let mut named = Test::A(A);
assert_eq!("A", named.name());
named = Test::BB(B);
assert_eq!("B", named.name());
named = Test::C(C);
assert_eq!("C", named.name());
}
#[test]
fn try_into_trait_object() {
let mut a = Test::A(A);
let mut maybe_display: Option<&mut dyn fmt::Display> = a.trait_obj();
println!("{}", maybe_display.unwrap());
let mut b = Test::BB(B);
maybe_display = b.trait_obj();
assert!(maybe_display.is_some());
let mut c = Test::C(C);
maybe_display = c.trait_obj();
assert!(maybe_display.is_none());
}