battler_data/moves/
ohko_type.rs1use core::{
2 fmt,
3 fmt::Display,
4 str::FromStr,
5};
6
7use anyhow::Error;
8use serde::{
9 Deserialize,
10 Serialize,
11 Serializer,
12 de::{
13 Unexpected,
14 Visitor,
15 },
16};
17
18use crate::Type;
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum OhkoType {
23 Always,
25 Type(Type),
27}
28
29impl Display for OhkoType {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 Self::Always => write!(f, "{}", true),
33 Self::Type(typ) => write!(f, "{typ}"),
34 }
35 }
36}
37
38impl FromStr for OhkoType {
39 type Err = Error;
40 fn from_str(s: &str) -> Result<Self, Self::Err> {
41 Ok(OhkoType::Type(Type::from_str(s).map_err(Error::msg)?))
42 }
43}
44
45impl Serialize for OhkoType {
46 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
47 where
48 S: Serializer,
49 {
50 match self {
51 Self::Always => serializer.serialize_bool(true),
52 Self::Type(typ) => typ.serialize(serializer),
53 }
54 }
55}
56
57struct OhkoTypeVisitor;
58
59impl<'de> Visitor<'de> for OhkoTypeVisitor {
60 type Value = OhkoType;
61
62 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
63 write!(formatter, "true or \"level\"")
64 }
65
66 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
67 where
68 E: serde::de::Error,
69 {
70 if !v {
71 Err(E::invalid_value(Unexpected::Bool(v), &self))
72 } else {
73 Ok(Self::Value::Always)
74 }
75 }
76
77 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
78 where
79 E: serde::de::Error,
80 {
81 Self::Value::from_str(v).map_err(|_| E::invalid_value(Unexpected::Str(&v), &self))
82 }
83}
84
85impl<'de> Deserialize<'de> for OhkoType {
86 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87 where
88 D: serde::Deserializer<'de>,
89 {
90 deserializer.deserialize_any(OhkoTypeVisitor)
91 }
92}
93
94#[cfg(test)]
95mod ohko_type_test {
96 use crate::{
97 mons::Type,
98 moves::OhkoType,
99 test_util::test_serialization,
100 };
101
102 #[test]
103 fn serializes_to_string() {
104 test_serialization(OhkoType::Always, true);
105 test_serialization(OhkoType::Type(Type::Ice), "\"Ice\"");
106 }
107}