match-v5.ParticipantDto use champion_id: Result<Champion, TryFromIntError> to handle invalid ints

Riot bug: https://github.com/RiotGames/developer-relations/issues/553
Fix #36
This commit is contained in:
Mingwei Samuel 2021-12-29 09:34:12 -08:00
parent 44b78abca9
commit c07efb1087
4 changed files with 60 additions and 10 deletions

View file

@ -6,8 +6,6 @@
// // // //
/////////////////////////////////////////////// ///////////////////////////////////////////////
use serde::{ Serialize, Deserialize };
newtype_enum! { newtype_enum! {
/// A League of Legends champion. /// A League of Legends champion.
/// ///
@ -174,7 +172,7 @@ newtype_enum! {
/// `ZILEAN` | "Zilean" | "Zilean" | 26 /// `ZILEAN` | "Zilean" | "Zilean" | 26
/// `ZOE` | "Zoe" | "Zoe" | 142 /// `ZOE` | "Zoe" | "Zoe" | 142
/// `ZYRA` | "Zyra" | "Zyra" | 143 /// `ZYRA` | "Zyra" | "Zyra" | 143
#[derive(Serialize, Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
#[serde(transparent)] #[serde(transparent)]
pub newtype_enum Champion(i16) { pub newtype_enum Champion(i16) {
/// `266`. /// `266`.
@ -837,6 +835,29 @@ impl Champion {
_ => None, _ => None,
} }
} }
/// https://github.com/MingweiSamuel/Riven/issues/36
pub(crate) fn serialize_result<S>(
val: &Result<Self, std::num::TryFromIntError>,
serializer: S,
) -> Result<S::Ok, S::Error>
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<Result<Self, std::num::TryFromIntError>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
use std::convert::TryInto;
<i64 as serde::de::Deserialize>::deserialize(deserializer).map(|id| id.try_into().map(Self))
}
} }
impl std::str::FromStr for Champion { impl std::str::FromStr for Champion {

View file

@ -820,7 +820,9 @@ pub mod match_v5 {
pub champ_level: i32, 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. /// 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")] #[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<crate::consts::Champion, std::num::TryFromIntError>,
#[serde(rename = "championName")] #[serde(rename = "championName")]
pub champion_name: String, pub champion_name: String,
/// This field is currently only utilized for Kayn's transformations. (Legal values: 0 - None, 1 - Slayer, 2 - Assassin) /// This field is currently only utilized for Kayn's transformations. (Legal values: 0 - None, 1 - Slayer, 2 - Assassin)

View file

@ -16,8 +16,6 @@
}; };
}}{{= dotUtils.preamble() }} }}{{= dotUtils.preamble() }}
use serde::{ Serialize, Deserialize };
newtype_enum! { newtype_enum! {
/// A League of Legends champion. /// A League of Legends champion.
/// ///
@ -34,7 +32,7 @@ newtype_enum! {
{{ {{
} }
}} }}
#[derive(Serialize, Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
#[serde(transparent)] #[serde(transparent)]
pub newtype_enum Champion(i16) { pub newtype_enum Champion(i16) {
{{ {{
@ -92,6 +90,29 @@ impl Champion {
_ => None, _ => None,
} }
} }
/// https://github.com/MingweiSamuel/Riven/issues/36
pub(crate) fn serialize_result<S>(
val: &Result<Self, std::num::TryFromIntError>,
serializer: S,
) -> Result<S::Ok, S::Error>
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<Result<Self, std::num::TryFromIntError>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
use std::convert::TryInto;
<i64 as serde::de::Deserialize>::deserialize(deserializer).map(|id| id.try_into().map(Self))
}
} }
impl std::str::FromStr for Champion { impl std::str::FromStr for Champion {

View file

@ -49,16 +49,22 @@ pub mod {{= dotUtils.changeCase.snakeCase(endpoint) }} {
for (let [ propKey, prop ] of Object.entries(props)) for (let [ propKey, prop ] of Object.entries(props))
{ {
const name = dotUtils.normalizePropName(propKey); const name = dotUtils.normalizePropName(propKey);
const required = requiredSet.has(propKey); const optional = !requiredSet.has(propKey);
}} }}
{{? prop.description }} {{? prop.description }}
/// {{= prop.description.split('\n').map(x => x.trim()).join('<br>\r\n /// ') }} /// {{= prop.description.split('\n').map(x => x.trim()).join('<br>\r\n /// ') }}
{{?}} {{?}}
{{= dotUtils.formatJsonProperty(propKey) }} {{= dotUtils.formatJsonProperty(propKey) }}
{{? !required }} {{? optional }}
#[serde(skip_serializing_if = "Option::is_none")] #[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<crate::consts::Champion, std::num::TryFromIntError>,
{{??}}
pub {{= name }}: {{= dotUtils.stringifyType(prop, { optional }) }},
{{?}}
{{ {{
} }
}} }}