Skip to main content

basalt_api/
gamemode.rs

1//! Gamemode type for the Minecraft protocol.
2//!
3//! Provides a type-safe enum instead of raw `u8` values for gamemodes,
4//! preventing invalid values from reaching the protocol layer.
5
6use std::fmt;
7
8/// A Minecraft game mode.
9///
10/// Used by [`Context::set_gamemode`](crate::Context::set_gamemode)
11/// and the `/gamemode` command. Maps directly to the protocol values
12/// sent in the GameStateChange packet (reason = 3).
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum Gamemode {
15    /// Survival mode (id 0): resource gathering, health, hunger.
16    Survival = 0,
17    /// Creative mode (id 1): unlimited resources, flight, no damage.
18    Creative = 1,
19    /// Adventure mode (id 2): survival with block interaction restrictions.
20    Adventure = 2,
21    /// Spectator mode (id 3): invisible, fly through blocks, no interaction.
22    Spectator = 3,
23}
24
25impl Gamemode {
26    /// Returns the protocol ID for this gamemode.
27    pub fn id(self) -> u8 {
28        self as u8
29    }
30
31    /// Creates a gamemode from its protocol ID.
32    ///
33    /// Returns `None` for invalid IDs (anything other than 0-3).
34    pub fn from_id(id: u8) -> Option<Self> {
35        match id {
36            0 => Some(Self::Survival),
37            1 => Some(Self::Creative),
38            2 => Some(Self::Adventure),
39            3 => Some(Self::Spectator),
40            _ => None,
41        }
42    }
43}
44
45impl fmt::Display for Gamemode {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        match self {
48            Gamemode::Survival => write!(f, "Survival"),
49            Gamemode::Creative => write!(f, "Creative"),
50            Gamemode::Adventure => write!(f, "Adventure"),
51            Gamemode::Spectator => write!(f, "Spectator"),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn gamemode_ids() {
62        assert_eq!(Gamemode::Survival.id(), 0);
63        assert_eq!(Gamemode::Creative.id(), 1);
64        assert_eq!(Gamemode::Adventure.id(), 2);
65        assert_eq!(Gamemode::Spectator.id(), 3);
66    }
67
68    #[test]
69    fn from_valid_id() {
70        assert_eq!(Gamemode::from_id(0), Some(Gamemode::Survival));
71        assert_eq!(Gamemode::from_id(1), Some(Gamemode::Creative));
72        assert_eq!(Gamemode::from_id(2), Some(Gamemode::Adventure));
73        assert_eq!(Gamemode::from_id(3), Some(Gamemode::Spectator));
74    }
75
76    #[test]
77    fn from_invalid_id() {
78        assert_eq!(Gamemode::from_id(4), None);
79        assert_eq!(Gamemode::from_id(255), None);
80    }
81
82    #[test]
83    fn display() {
84        assert_eq!(Gamemode::Survival.to_string(), "Survival");
85        assert_eq!(Gamemode::Creative.to_string(), "Creative");
86        assert_eq!(Gamemode::Adventure.to_string(), "Adventure");
87        assert_eq!(Gamemode::Spectator.to_string(), "Spectator");
88    }
89}