#![allow(dead_code)] extern crate penum; use penum::penum; use std::ops::Add; pub trait AbcTrait { fn a(&self) -> Option; fn b(&self) -> &Option; fn c(&self) -> (Option, &Option<&String>); fn d(&self) -> &String; } impl AbcTrait for String { fn a(&self) -> Option { Some(10) } fn b(&self) -> &Option { &Some(20) } fn c(&self) -> (Option, &Option<&String>) { (Some(30), &None) } fn d(&self) -> &String { self } } #[penum( (T) where T: ^AsRef )] enum Foo { Bar(String), } #[penum( unit | (T, ..) | () where T: ^AbcTrait )] enum Foo1 { Ber(String), Bar(String), Bor, Bur(), } #[penum((T) where T: ^Add)] enum Foo2 { Bar(i32), Bor(i32), } fn main() { let foot = Foo::Bar("Word".to_owned()); assert_eq!("word", foot.as_ref()); let foot1 = Foo1::Bar("Word".to_owned()); assert_eq!(Some(10), foot1.a()); assert_eq!(&Some(20), foot1.b()); assert_eq!((Some(30), &None), foot1.c()); assert_eq!(foot1.d(), foot1.d()); let foot2 = Foo2::Bar(100); assert_eq!(300, foot2 + 200); }