battler_data/mons/
shiny_chance.rs1use alloc::format;
2use core::{
3 fmt,
4 str::FromStr,
5};
6
7use anyhow::Error;
8use serde::{
9 Deserialize,
10 Serialize,
11 de::Visitor,
12};
13
14#[derive(Debug, Default, Clone, PartialEq)]
16pub enum ShinyChance {
17 Never,
19 #[default]
21 Chance,
22 Always,
24}
25
26impl From<bool> for ShinyChance {
27 fn from(value: bool) -> Self {
28 if value { Self::Always } else { Self::Never }
29 }
30}
31
32impl FromStr for ShinyChance {
33 type Err = Error;
34
35 fn from_str(s: &str) -> Result<Self, Self::Err> {
36 match s {
37 "maybe" => Ok(Self::Chance),
38 "always" => Ok(Self::Always),
39 "never" => Ok(Self::Never),
40 _ => Err(Error::msg(format!("invalid shiny chance \"{s}\""))),
41 }
42 }
43}
44
45impl Serialize for ShinyChance {
46 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
47 where
48 S: serde::Serializer,
49 {
50 match self {
51 Self::Never => serializer.serialize_bool(false),
52 Self::Chance => serializer.serialize_str("maybe"),
53 Self::Always => serializer.serialize_bool(true),
54 }
55 }
56}
57
58struct ShinyChanceVisitor;
59
60impl<'de> Visitor<'de> for ShinyChanceVisitor {
61 type Value = ShinyChance;
62
63 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
64 write!(formatter, "a boolean or \"maybe\"")
65 }
66
67 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
68 where
69 E: serde::de::Error,
70 {
71 Ok(Self::Value::from(v))
72 }
73
74 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
75 where
76 E: serde::de::Error,
77 {
78 Self::Value::from_str(v)
79 .map_err(|_| E::invalid_value(serde::de::Unexpected::Str(&v), &self))
80 }
81}
82
83impl<'de> Deserialize<'de> for ShinyChance {
84 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85 where
86 D: serde::Deserializer<'de>,
87 {
88 deserializer.deserialize_any(ShinyChanceVisitor)
89 }
90}
91
92#[cfg(test)]
93mod shiny_chance_test {
94 use crate::{
95 mons::ShinyChance,
96 test_util::{
97 test_serialization,
98 test_string_deserialization,
99 },
100 };
101
102 #[test]
103 fn serializes_numbers_and_strings() {
104 test_serialization(ShinyChance::Never, false);
105 test_serialization(ShinyChance::Chance, "\"maybe\"");
106 test_serialization(ShinyChance::Always, true);
107 }
108
109 #[test]
110 fn deserializes_alias_strings() {
111 test_string_deserialization("always", ShinyChance::Always);
112 test_string_deserialization("never", ShinyChance::Never);
113 }
114}