team04_server/messages/
player_character.rs

1use rand::{rng, seq::IndexedRandom};
2use serde::{Deserialize, Serialize};
3use strum::VariantArray;
4
5/// Each player is represented in-game by one of these.
6#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, VariantArray)]
7#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
8pub enum PlayerCharacter {
9    Luke,
10    Vader,
11    Leia,
12    Mandalorian,
13    Grogu,
14    Kenobi,
15    Grievous,
16    Ahsoka,
17    Padme,
18    Palpatine,
19    Maul,
20    Jabba,
21    Solo,
22    Kylo,
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub struct PlayerCharacterOrNone(pub Option<PlayerCharacter>);
27
28impl<'de> Deserialize<'de> for PlayerCharacterOrNone {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: serde::Deserializer<'de>,
32    {
33        struct PCONVisitor;
34
35        impl<'vis> serde::de::Visitor<'vis> for PCONVisitor {
36            type Value = PlayerCharacterOrNone;
37
38            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39                write!(formatter, "a Player character or 'NONE'")
40            }
41
42            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
43            where
44                E: serde::de::Error,
45            {
46                if v == "NONE" {
47                    Ok(PlayerCharacterOrNone(None))
48                } else {
49                    Ok(PlayerCharacterOrNone(Some(PlayerCharacter::deserialize(
50                        serde::de::IntoDeserializer::into_deserializer(v),
51                    )?)))
52                }
53            }
54        }
55
56        deserializer.deserialize_str(PCONVisitor)
57    }
58}
59
60impl Serialize for PlayerCharacterOrNone {
61    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62    where
63        S: serde::Serializer,
64    {
65        match self.0 {
66            None => "NONE".serialize(serializer),
67            Some(pc) => pc.serialize(serializer),
68        }
69    }
70}
71
72impl PlayerCharacter {
73    pub fn random() -> Self {
74        *Self::VARIANTS.choose(&mut rng()).unwrap()
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use crate::messages::{deserialize, player_character::PlayerCharacterOrNone, serialize};
81    use strum::VariantArray;
82
83    use super::PlayerCharacter;
84
85    #[test]
86    fn test_player_character_serde() {
87        assert_eq!(serialize(&PlayerCharacter::Luke), r#""LUKE""#);
88        assert_eq!(serialize(&PlayerCharacter::Grogu), r#""GROGU""#);
89        let mut did_something = false;
90        for character in PlayerCharacter::VARIANTS {
91            did_something = true;
92            assert_eq!(*character, deserialize(&serialize(character)).unwrap());
93        }
94        assert!(did_something);
95    }
96    #[test]
97    fn test_player_character_or_none_serde() {
98        assert_eq!(serialize(&PlayerCharacterOrNone(None)), r#""NONE""#);
99        assert_eq!(
100            PlayerCharacterOrNone(None),
101            deserialize(&serialize(&PlayerCharacterOrNone(None))).unwrap()
102        );
103        let mut did_something = false;
104        for character in PlayerCharacter::VARIANTS {
105            did_something = true;
106            assert_eq!(
107                PlayerCharacterOrNone(Some(*character)),
108                deserialize(&serialize(&PlayerCharacterOrNone(Some(*character)))).unwrap()
109            );
110            assert_eq!(
111                *character,
112                deserialize(&serialize(&PlayerCharacterOrNone(Some(*character)))).unwrap()
113            );
114            assert_eq!(
115                PlayerCharacterOrNone(Some(*character)),
116                deserialize(&serialize(character)).unwrap()
117            );
118        }
119        assert!(did_something);
120    }
121}