From c07efb1087befa296d7f07d6dcc7c1b50632c3b7 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Wed, 29 Dec 2021 09:34:12 -0800 Subject: [PATCH] match-v5.ParticipantDto use champion_id: Result to handle invalid ints Riot bug: https://github.com/RiotGames/developer-relations/issues/553 Fix #36 --- riven/src/consts/champion.rs | 27 ++++++++++++++++++++++++--- riven/src/models.rs | 4 +++- riven/srcgen/consts/champion.rs.dt | 27 ++++++++++++++++++++++++--- riven/srcgen/models.rs.dt | 12 +++++++++--- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/riven/src/consts/champion.rs b/riven/src/consts/champion.rs index ca2916a..3d75f1f 100644 --- a/riven/src/consts/champion.rs +++ b/riven/src/consts/champion.rs @@ -6,8 +6,6 @@ // // /////////////////////////////////////////////// -use serde::{ Serialize, Deserialize }; - newtype_enum! { /// A League of Legends champion. /// @@ -174,7 +172,7 @@ newtype_enum! { /// `ZILEAN` | "Zilean" | "Zilean" | 26 /// `ZOE` | "Zoe" | "Zoe" | 142 /// `ZYRA` | "Zyra" | "Zyra" | 143 - #[derive(Serialize, Deserialize)] + #[derive(serde::Serialize, serde::Deserialize)] #[serde(transparent)] pub newtype_enum Champion(i16) { /// `266`. @@ -837,6 +835,29 @@ impl Champion { _ => None, } } + + /// https://github.com/MingweiSamuel/Riven/issues/36 + pub(crate) fn serialize_result( + val: &Result, + serializer: S, + ) -> Result + where + S: serde::ser::Serializer, + { + use serde::ser::Serialize; + val.unwrap_or(Champion(-1)).serialize(serializer) + } + + /// https://github.com/MingweiSamuel/Riven/issues/36 + pub(crate) fn deserialize_result<'de, D>( + deserializer: D, + ) -> Result, D::Error> + where + D: serde::de::Deserializer<'de>, + { + use std::convert::TryInto; + ::deserialize(deserializer).map(|id| id.try_into().map(Self)) + } } impl std::str::FromStr for Champion { diff --git a/riven/src/models.rs b/riven/src/models.rs index 7a0eb74..ad0f590 100644 --- a/riven/src/models.rs +++ b/riven/src/models.rs @@ -820,7 +820,9 @@ pub mod match_v5 { pub champ_level: i32, /// Prior to patch 11.4, on Feb 18th, 2021, this field returned invalid championIds. We recommend determining the champion based on the championName field for matches played prior to patch 11.4. #[serde(rename = "championId")] - pub champion_id: crate::consts::Champion, + #[serde(serialize_with = "crate::consts::Champion::serialize_result")] + #[serde(deserialize_with = "crate::consts::Champion::deserialize_result")] + pub champion_id: Result, #[serde(rename = "championName")] pub champion_name: String, /// This field is currently only utilized for Kayn's transformations. (Legal values: 0 - None, 1 - Slayer, 2 - Assassin) diff --git a/riven/srcgen/consts/champion.rs.dt b/riven/srcgen/consts/champion.rs.dt index d124218..a650a15 100644 --- a/riven/srcgen/consts/champion.rs.dt +++ b/riven/srcgen/consts/champion.rs.dt @@ -16,8 +16,6 @@ }; }}{{= dotUtils.preamble() }} -use serde::{ Serialize, Deserialize }; - newtype_enum! { /// A League of Legends champion. /// @@ -34,7 +32,7 @@ newtype_enum! { {{ } }} - #[derive(Serialize, Deserialize)] + #[derive(serde::Serialize, serde::Deserialize)] #[serde(transparent)] pub newtype_enum Champion(i16) { {{ @@ -92,6 +90,29 @@ impl Champion { _ => None, } } + + /// https://github.com/MingweiSamuel/Riven/issues/36 + pub(crate) fn serialize_result( + val: &Result, + serializer: S, + ) -> Result + where + S: serde::ser::Serializer, + { + use serde::ser::Serialize; + val.unwrap_or(Champion(-1)).serialize(serializer) + } + + /// https://github.com/MingweiSamuel/Riven/issues/36 + pub(crate) fn deserialize_result<'de, D>( + deserializer: D, + ) -> Result, D::Error> + where + D: serde::de::Deserializer<'de>, + { + use std::convert::TryInto; + ::deserialize(deserializer).map(|id| id.try_into().map(Self)) + } } impl std::str::FromStr for Champion { diff --git a/riven/srcgen/models.rs.dt b/riven/srcgen/models.rs.dt index 8c6ca9f..62ba1e9 100644 --- a/riven/srcgen/models.rs.dt +++ b/riven/srcgen/models.rs.dt @@ -49,16 +49,22 @@ pub mod {{= dotUtils.changeCase.snakeCase(endpoint) }} { for (let [ propKey, prop ] of Object.entries(props)) { const name = dotUtils.normalizePropName(propKey); - const required = requiredSet.has(propKey); + const optional = !requiredSet.has(propKey); }} {{? prop.description }} /// {{= prop.description.split('\n').map(x => x.trim()).join('
\r\n /// ') }} {{?}} {{= dotUtils.formatJsonProperty(propKey) }} -{{? !required }} +{{? optional }} #[serde(skip_serializing_if = "Option::is_none")] {{?}} - pub {{= name }}: {{= dotUtils.stringifyType(prop, { optional: !required }) }}, +{{? 'championId' === propKey && (prop.description || '').includes('this field returned invalid championIds') }} + #[serde(serialize_with = "crate::consts::Champion::serialize_result")] + #[serde(deserialize_with = "crate::consts::Champion::deserialize_result")] + pub {{= name }}: Result, +{{??}} + pub {{= name }}: {{= dotUtils.stringifyType(prop, { optional }) }}, +{{?}} {{ } }}