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.turngreen(); assert!(light.cango()); ```

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(novalue, notrait)]

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 novalue. // impl TrafficLight { // fn cango(&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(traitname = TraitName, valuename = 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.turngreen(); assert!(light.cango()); ```