#![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::()); assert!(Test::BB(B).is::()); assert!(!Test::C(C).is::()); } #[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 = 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()); }