use state_shift::{states, type_state};
#[derive(Debug)]
struct Player {
race: Race,
}
#[derive(Debug, PartialEq)]
enum Race {
Orc,
Human,
}
#[type_state(state_slots = 1, default_state = Initial1)]
struct PlayerBuilder1 {
race: Option<Race>,
}
#[states(Initial1, RaceSet1)]
impl PlayerBuilder1 {
#[require(Initial1)] fn new() -> PlayerBuilder1 {
PlayerBuilder1 { race: None }
}
#[require(Initial1)] #[switch_to(RaceSet1)] fn set_race(self, race: Race) -> PlayerBuilder1 {
PlayerBuilder1 { race: Some(race) }
}
#[require(RaceSet1)]
fn build(self) -> Player {
Player {
race: self.race.expect("type safety ensures this is set"),
}
}
}
#[type_state(state_slots = 1, default_state = Initial2)]
struct PlayerBuilder2 {
race: Option<Race>,
}
#[states(Initial2, RaceSet2)]
impl PlayerBuilder2 {
#[require(Initial2)] fn new() -> PlayerBuilder2 {
PlayerBuilder2 { race: None }
}
#[require(Initial2)] #[switch_to(RaceSet2)] fn set_race(self, race: Race) -> PlayerBuilder2 {
PlayerBuilder2 { race: Some(race) }
}
#[require(RaceSet2)]
fn build(self) -> Player {
Player {
race: self.race.expect("type safety ensures this is set"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn double_player_creation_works() {
let player1 = PlayerBuilder1::new().set_race(Race::Human).build();
let player2 = PlayerBuilder2::new().set_race(Race::Orc).build();
assert_eq!(player1.race, Race::Human);
assert_eq!(player2.race, Race::Orc);
}
}