battler_data/moves/
switch_type.rs1use alloc::format;
2use core::{
3 fmt,
4 fmt::Display,
5 str::FromStr,
6};
7
8use anyhow::Error;
9use serde::{
10 Deserialize,
11 Serialize,
12 Serializer,
13 de::{
14 Unexpected,
15 Visitor,
16 },
17};
18
19#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
21pub enum SwitchType {
22 #[default]
24 Normal,
25 CopyVolatile,
27 IfHit,
29}
30
31impl SwitchType {
32 pub fn if_hit(&self) -> bool {
34 match self {
35 Self::IfHit => true,
36 _ => false,
37 }
38 }
39}
40
41impl Display for SwitchType {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 match self {
44 Self::Normal => write!(f, "{}", true),
45 Self::CopyVolatile => write!(f, "copyvolatile"),
46 Self::IfHit => write!(f, "ifhit"),
47 }
48 }
49}
50
51impl FromStr for SwitchType {
52 type Err = Error;
53 fn from_str(s: &str) -> Result<Self, Self::Err> {
54 match s {
55 "copyvolatile" => Ok(Self::CopyVolatile),
56 "ifhit" => Ok(Self::IfHit),
57 _ => Err(Error::msg(format!("invalid user switch type: \"{s}\""))),
58 }
59 }
60}
61
62impl Serialize for SwitchType {
63 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64 where
65 S: Serializer,
66 {
67 match self {
68 Self::Normal => serializer.serialize_bool(true),
69 Self::CopyVolatile => serializer.serialize_str("copyvolatile"),
70 Self::IfHit => serializer.serialize_str("ifhit"),
71 }
72 }
73}
74
75struct UserSwitchTypeVisitor;
76
77impl<'de> Visitor<'de> for UserSwitchTypeVisitor {
78 type Value = SwitchType;
79
80 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
81 write!(formatter, "true, \"copyvolatile\", or \"ifhit\"")
82 }
83
84 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
85 where
86 E: serde::de::Error,
87 {
88 if !v {
89 Err(E::invalid_value(Unexpected::Bool(v), &self))
90 } else {
91 Ok(Self::Value::Normal)
92 }
93 }
94
95 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
96 where
97 E: serde::de::Error,
98 {
99 Self::Value::from_str(v).map_err(|_| E::invalid_value(Unexpected::Str(&v), &self))
100 }
101}
102
103impl<'de> Deserialize<'de> for SwitchType {
104 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
105 where
106 D: serde::Deserializer<'de>,
107 {
108 deserializer.deserialize_any(UserSwitchTypeVisitor)
109 }
110}
111
112#[cfg(test)]
113mod user_switch_type_test {
114 use crate::{
115 moves::SwitchType,
116 test_util::test_serialization,
117 };
118
119 #[test]
120 fn serializes_to_string() {
121 test_serialization(SwitchType::Normal, true);
122 test_serialization(SwitchType::CopyVolatile, "\"copyvolatile\"");
123 test_serialization(SwitchType::IfHit, "\"ifhit\"");
124 }
125}