# Typemarker Procedural macro for easily creating multiple linked marker types, useful for the typestate pattern. # Examples By default, typemarker adds both a trait and a dynamic value for the marker enum called "Trait" and "Dynamic" respectively. ```rust use core::marker::PhantomData; use typemarker::typemarker; #[typemarker] enum LightColor { Red, Yellow, Green, } struct TrafficLight(PhantomData); impl TrafficLight { fn turn_green(self) -> TrafficLight { TrafficLight::(PhantomData) } } impl TrafficLight { fn can_go(&self) -> bool { Color::dynamic() == LightColor::Dynamic::Green } } let light = TrafficLight::(PhantomData); assert!(!light.can_go()); let light = light.turn_green(); assert!(light.can_go()); ``` Both the trait and the dynamic value can be disabled using `no_value` and `no_trait` respectively. ```rust use core::marker::PhantomData; use typemarker::typemarker; #[typemarker(no_value, no_trait)] enum LightColor { Red, Yellow, Green, } // Compile error, LightColor::Trait does not exist on no_trait. // struct TrafficLight(PhantomData); struct TrafficLight(PhantomData); impl TrafficLight { fn turn_green(self) -> TrafficLight { TrafficLight::(PhantomData) } } // Compile error, dynamic doesn't exist on no_value. // impl TrafficLight { // fn can_go(&self) -> bool { // Color::dynamic() == LightColor::Dynamic::Green // } // } let light = TrafficLight::(PhantomData); light.turn_green(); ``` They can also be renamed using `trait_name = ...` and `value_name = ...`: ```rust use core::marker::PhantomData; use typemarker::typemarker; #[typemarker(trait_name = TraitName, value_name = ValueName)] enum LightColor { Red, Yellow, Green, } struct TrafficLight(PhantomData); impl TrafficLight { fn turn_green(self) -> TrafficLight { TrafficLight::(PhantomData) } } impl TrafficLight { fn can_go(&self) -> bool { Color::dynamic() == LightColor::ValueName::Green } } let light = TrafficLight::(PhantomData); assert!(!light.can_go()); let light = light.turn_green(); assert!(light.can_go()); ```