1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
pub const PLAYER_EVENT_START: &str = "start";
pub const PLAYER_EVENT_JUMP: &str = "jump";
pub const PLAYER_EVENT_LAND: &str = "land";
pub const PLAYER_EVENT_FALL: &str = "fall";
pub const PLAYER_EVENT_CATCH_UP: &str = "catch_up";
pub const PLAYER_EVENT_CHANGE_COLUMN: &str = "change_column";
pub const PLAYER_EVENT_BOOST: &str = "boost";
pub const PLAYER_EVENT_OVERDRIVE: &str = "overdrive";
pub const PLAYER_EVENT_THOUSAND_SCORE: &str = "thousand_score";
pub const PLAYER_EVENT_PERCENT_TIME: &str = "percent_time";
pub const PLAYER_EVENT_HIGH_SCORE: &str = "high_score";
pub const PLAYER_EVENT_FINISH: &str = "finish";

/// Events which can be triggered by the player.
#[derive(Debug, Clone, Copy)]
pub enum PlayerEventKind {
    // Player starts.
    Start,
    // A jump happened.
    Jump,
    // The player landed.
    Land,
    // The player fell.
    Fall,
    // Player catched up and can score again.
    CatchUp,
    // Player changed to a new column.
    ChangeColumn,
    // Player stumbled on a boost slab.
    Boost,
    // Player stumbled on a boost slab, for the second time.
    Overdrive,
    // Player reached a round thousand score limit.
    ThousandScore,
    // Player reached a remarkable percentage of time.
    PercentTime,
    // High score was beaten.
    HighScore,
    // Player finished the level.
    Finish,
}

impl PlayerEventKind {
    // Transforms a player event as an &str.
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Start => PLAYER_EVENT_START,
            Self::Jump => PLAYER_EVENT_JUMP,
            Self::Land => PLAYER_EVENT_LAND,
            Self::Fall => PLAYER_EVENT_FALL,
            Self::CatchUp => PLAYER_EVENT_CATCH_UP,
            Self::ChangeColumn => PLAYER_EVENT_CHANGE_COLUMN,
            Self::Boost => PLAYER_EVENT_BOOST,
            Self::Overdrive => PLAYER_EVENT_OVERDRIVE,
            Self::ThousandScore => PLAYER_EVENT_THOUSAND_SCORE,
            Self::PercentTime => PLAYER_EVENT_PERCENT_TIME,
            Self::HighScore => PLAYER_EVENT_HIGH_SCORE,
            Self::Finish => PLAYER_EVENT_FINISH,
        }
    }
}

impl std::fmt::Display for PlayerEventKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_fmt() {
        assert_eq!("start", format!("{}", PlayerEventKind::Start));
        assert_eq!("jump", format!("{}", PlayerEventKind::Jump));
        assert_eq!("land", format!("{}", PlayerEventKind::Land));
        assert_eq!("fall", format!("{}", PlayerEventKind::Fall));
        assert_eq!("catch_up", format!("{}", PlayerEventKind::CatchUp));
        assert_eq!(
            "change_column",
            format!("{}", PlayerEventKind::ChangeColumn)
        );
        assert_eq!("boost", format!("{}", PlayerEventKind::Boost));
        assert_eq!("overdrive", format!("{}", PlayerEventKind::Overdrive));
        assert_eq!(
            "thousand_score",
            format!("{}", PlayerEventKind::ThousandScore)
        );
        assert_eq!("percent_time", format!("{}", PlayerEventKind::PercentTime));
        assert_eq!("high_score", format!("{}", PlayerEventKind::HighScore));
        assert_eq!("finish", format!("{}", PlayerEventKind::Finish));
    }
}