Skip to content

Commit 2fb5fde

Browse files
authored
fix: deserialize ChomboWeight from stringified decimals (#300)
1 parent c468372 commit 2fb5fde

File tree

5 files changed

+61
-8
lines changed

5 files changed

+61
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ log = "0.4.29"
2626
num-bigint = "0.4.6"
2727
itertools = "0.14.0"
2828
poise = "0.6.1"
29+
serde_json = "1.0.149"

chombot-kcc/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ num-bigint.workspace = true
2525
itertools.workspace = true
2626
poise.workspace = true
2727
chombot-common = { path = "../chombot-common" }
28+
29+
[dev-dependencies]
30+
serde_json.workspace = true

chombot-kcc/src/kcc3/data_types.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ impl Serialize for ChomboWeight {
123123

124124
impl<'de> Deserialize<'de> for ChomboWeight {
125125
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
126-
let v = f64::deserialize(deserializer)?;
126+
let v = String::deserialize(deserializer)?;
127+
let v: f64 = v.parse().map_err(serde::de::Error::custom)?;
127128
Ok(Self::from_f64(v))
128129
}
129130
}
@@ -156,7 +157,9 @@ impl Chombo {
156157

157158
#[cfg(test)]
158159
mod tests {
159-
use crate::kcc3::data_types::{ChomboWeight, DiscordId, Player, PlayerId};
160+
use chrono::{DateTime, Utc};
161+
162+
use crate::kcc3::data_types::{Chombo, ChomboWeight, DiscordId, Player, PlayerId};
160163

161164
#[test]
162165
fn short_name_should_return_nickname() {
@@ -217,4 +220,51 @@ mod tests {
217220
assert_eq!(ChomboWeight::from_f64(0.0), ChomboWeight::W1);
218221
assert_eq!(ChomboWeight::from_f64(7.0), ChomboWeight::W1);
219222
}
223+
224+
#[test]
225+
fn deserialize_from_string() {
226+
assert_eq!(
227+
serde_json::from_str::<ChomboWeight>("\"2.5\"").unwrap(),
228+
ChomboWeight::W2_5
229+
);
230+
assert_eq!(
231+
serde_json::from_str::<ChomboWeight>("\"1.0\"").unwrap(),
232+
ChomboWeight::W1
233+
);
234+
}
235+
236+
#[test]
237+
fn deserialize_invalid_string() {
238+
assert!(serde_json::from_str::<ChomboWeight>("\"abc\"").is_err());
239+
}
240+
241+
#[test]
242+
fn deserialize_rejects_number() {
243+
assert!(serde_json::from_str::<ChomboWeight>("2.5").is_err());
244+
}
245+
246+
#[test]
247+
fn deserialize_chombo_from_api_payload() {
248+
let json = r#"{
249+
"id": 229,
250+
"timestamp": "2026-02-15T22:09:03Z",
251+
"comment": "furiten ron",
252+
"weight": "1.0",
253+
"player": "someplayername"
254+
}"#;
255+
let chombo: Chombo = serde_json::from_str(json).unwrap();
256+
assert_eq!(chombo.player, PlayerId("someplayername".to_string()));
257+
assert_eq!(chombo.comment, "furiten ron");
258+
assert_eq!(chombo.weight, ChomboWeight::W1);
259+
assert_eq!(
260+
chombo.timestamp,
261+
DateTime::<Utc>::from_naive_utc_and_offset(
262+
chrono::NaiveDate::from_ymd_opt(2026, 2, 15)
263+
.unwrap()
264+
.and_hms_opt(22, 9, 3)
265+
.unwrap(),
266+
Utc,
267+
)
268+
);
269+
}
220270
}

chombot/src/config.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ impl TournamentWatcherChannelListProvider for ChombotConfig {
2929
type TournamentWatcherChannelList = Vec<ChannelId>;
3030

3131
async fn tournament_watcher_channels(&self) -> Self::TournamentWatcherChannelList {
32-
let channel_ids = self
33-
.config
32+
self.config
3433
.guilds
35-
.iter()
36-
.filter_map(|(_, config)| config.tournaments_watcher_channel_id);
37-
38-
channel_ids.collect()
34+
.values()
35+
.filter_map(|config| config.tournaments_watcher_channel_id)
36+
.collect()
3937
}
4038
}
4139

0 commit comments

Comments
 (0)