From 65eeb7ae44619176489c501855654ba92039d234 Mon Sep 17 00:00:00 2001 From: TotallyNot <44345987+TotallyNot@users.noreply.github.com> Date: Thu, 8 Sep 2022 00:44:06 +0200 Subject: [PATCH] added elim field --- torn-api/Cargo.toml | 2 +- torn-api/src/user.rs | 182 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 182 insertions(+), 2 deletions(-) diff --git a/torn-api/Cargo.toml b/torn-api/Cargo.toml index 2065c1d..7dc8f86 100644 --- a/torn-api/Cargo.toml +++ b/torn-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "torn-api" -version = "0.3.0" +version = "0.3.1" edition = "2021" [features] diff --git a/torn-api/src/user.rs b/torn-api/src/user.rs index 903fdab..4fc05ec 100644 --- a/torn-api/src/user.rs +++ b/torn-api/src/user.rs @@ -1,5 +1,8 @@ use chrono::{serde::ts_seconds, DateTime, Utc}; -use serde::Deserialize; +use serde::{ + de::{self, MapAccess, Visitor}, + Deserialize, Deserializer, +}; use macros::ApiCategory; @@ -99,6 +102,138 @@ pub struct LifeBar { pub increment: i16, } +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum EliminationTeam { + Firestarters, + HardBoiled, + QuackAddicts, + RainMen, + TotallyBoned, + RawringThunder, + DirtyCops, + LaughingStock, + JeanTherapy, + #[serde(rename = "statants-soldiers")] + SatansSoldiers, + WolfPack, + Sleepyheads, +} + +#[derive(Debug, Clone)] +pub enum Competition { + Elimination { + score: i16, + attacks: i16, + team: EliminationTeam, + }, +} + +fn deserialize_comp<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + #[serde(rename_all = "lowercase")] + enum Field { + Name, + Score, + Team, + Attacks, + } + + #[derive(Deserialize)] + enum CompetitionName { + Elimination, + } + + struct CompetitionVisitor; + + impl<'de> Visitor<'de> for CompetitionVisitor { + type Value = Option; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct Competition") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut team: Option = None; + let mut score = None; + let mut attacks = None; + let mut name: Option = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Name => { + name = Some(map.next_value()?); + } + Field::Score => { + score = Some(map.next_value()?); + } + Field::Attacks => { + attacks = Some(map.next_value()?); + } + Field::Team => { + let team_raw: String = map.next_value()?; + team = if team_raw.is_empty() { + None + } else { + Some(match team_raw.as_str() { + "firestarters" => EliminationTeam::Firestarters, + "hard-boiled" => EliminationTeam::HardBoiled, + "quack-addicts" => EliminationTeam::QuackAddicts, + "rain-men" => EliminationTeam::RainMen, + "totally-boned" => EliminationTeam::TotallyBoned, + "rawring-thunder" => EliminationTeam::RawringThunder, + "dirty-cops" => EliminationTeam::DirtyCops, + "laughing-stock" => EliminationTeam::LaughingStock, + "jean-therapy" => EliminationTeam::JeanTherapy, + "satants-soldiers" => EliminationTeam::SatansSoldiers, + "wolf-pack" => EliminationTeam::WolfPack, + "sleepyheads" => EliminationTeam::Sleepyheads, + _ => Err(de::Error::unknown_variant( + &team_raw, + &[ + "firestarters", + "hard-boiled", + "quack-addicts", + "rain-men", + "totally-boned", + "rawring-thunder", + "dirty-cops", + "laughing-stock", + "jean-therapy", + "satants-soldiers", + "wolf-pack", + "sleepyheads", + ], + ))?, + }) + } + } + } + } + + match (name, team, score, attacks) { + (Some(CompetitionName::Elimination), Some(team), Some(score), Some(attacks)) => { + Ok(Some(Competition::Elimination { + team, + score, + attacks, + })) + } + _ => Ok(None), + } + } + } + + const FIELDS: &[&str] = &["name", "score", "team", "attacks"]; + deserializer.deserialize_struct("Competition", FIELDS, CompetitionVisitor) +} + #[derive(Debug, Clone, Deserialize)] pub struct Profile { pub player_id: i32, @@ -112,6 +247,9 @@ pub struct Profile { pub last_action: LastAction, pub faction: Faction, pub status: Status, + + #[serde(deserialize_with = "deserialize_comp")] + pub competition: Option, } #[derive(Debug, Clone, Deserialize)] @@ -193,4 +331,46 @@ mod tests { assert!(faction.days_in_faction.is_none()); assert!(faction.position.is_none()); } + + #[async_test] + async fn team_visible() { + let key = setup(); + + let response = Client::default() + .torn_api(key) + .user(|b| b.selections(&[Selection::Profile])) + .await + .unwrap(); + + let profile = response.profile().unwrap(); + assert!(profile.competition.is_some()); + } + + #[async_test] + async fn team_invisible() { + let key = setup(); + + let response = Client::default() + .torn_api(key) + .user(|b| b.id(2526617).selections(&[Selection::Profile])) + .await + .unwrap(); + + let profile = response.profile().unwrap(); + assert!(profile.competition.is_none()); + } + + #[async_test] + async fn team_none() { + let key = setup(); + + let response = Client::default() + .torn_api(key) + .user(|b| b.id(2681712).selections(&[Selection::Profile])) + .await + .unwrap(); + + let profile = response.profile().unwrap(); + assert!(profile.competition.is_none()); + } }