mirror of
https://github.com/MingweiSamuel/Riven.git
synced 2024-12-26 02:46:31 +00:00
fix: regen, updates to fix bad match data
https://github.com/RiotGames/developer-relations/issues/898
This commit is contained in:
parent
ff6a3af9e1
commit
95c3ccbe0b
10 changed files with 157 additions and 13 deletions
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -7,5 +7,9 @@
|
||||||
"RUST_LOG": "riven=debug"
|
"RUST_LOG": "riven=debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"rust-analyzer.cargo.features": [
|
||||||
|
"nightly",
|
||||||
|
"deny-unknown"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,5 +31,38 @@ pub enum GameType {
|
||||||
TUTORIAL_GAME,
|
TUTORIAL_GAME,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GameType {
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn serialize_empty<S>(
|
||||||
|
val: &Option<Self>,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::Serialize;
|
||||||
|
if let Some(val) = val {
|
||||||
|
val.serialize(serializer)
|
||||||
|
} else {
|
||||||
|
"".serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn deserialize_empty<'de, D>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<Option<Self>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::IntoDeserializer;
|
||||||
|
let opt = Option::<String>::deserialize(deserializer)?;
|
||||||
|
match opt.as_deref() {
|
||||||
|
None | Some("") => Ok(None),
|
||||||
|
Some(s) => Self::deserialize(s.into_deserializer()).map(Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
|
@ -49,10 +49,17 @@ macro_rules! serde_strum_unknown {
|
||||||
<&str>::deserialize(deserializer)
|
<&str>::deserialize(deserializer)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.and_then(|item| match item {
|
.and_then(|item| match item {
|
||||||
Self::UNKNOWN(unknown) => Err(serde::de::Error::unknown_variant(
|
Self::UNKNOWN(unknown) => {
|
||||||
|
if unknown.is_empty() {
|
||||||
|
// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
Ok(Self::UNKNOWN(unknown))
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::unknown_variant(
|
||||||
&*unknown,
|
&*unknown,
|
||||||
<Self as strum::VariantNames>::VARIANTS,
|
<Self as strum::VariantNames>::VARIANTS,
|
||||||
)),
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
other => Ok(other),
|
other => Ok(other),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -151,7 +158,8 @@ macro_rules! newtype_enum {
|
||||||
{
|
{
|
||||||
<$repr>::deserialize(deserializer).map(Into::into)
|
<$repr>::deserialize(deserializer).map(Into::into)
|
||||||
.and_then(|item: Self| {
|
.and_then(|item: Self| {
|
||||||
if !item.is_known() {
|
// Exception for id zero: https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
if 0 != item.0 && !item.is_known() {
|
||||||
Err(serde::de::Error::custom(format!(
|
Err(serde::de::Error::custom(format!(
|
||||||
"Unknown integer enum variant: {} (\"deny-unknown-enum-variants-integers\" feature is enabled).\nExpected one of the following: {:?}",
|
"Unknown integer enum variant: {} (\"deny-unknown-enum-variants-integers\" feature is enabled).\nExpected one of the following: {:?}",
|
||||||
item, Self::ALL_KNOWN
|
item, Self::ALL_KNOWN
|
||||||
|
|
|
@ -56,3 +56,36 @@ pub use team::*;
|
||||||
|
|
||||||
mod tier;
|
mod tier;
|
||||||
pub use tier::*;
|
pub use tier::*;
|
||||||
|
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn serialize_empty_string_none<S, T>(
|
||||||
|
val: &Option<T>,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
T: serde::ser::Serialize,
|
||||||
|
{
|
||||||
|
use serde::ser::Serialize;
|
||||||
|
if let Some(val) = val {
|
||||||
|
val.serialize(serializer)
|
||||||
|
} else {
|
||||||
|
"".serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn deserialize_empty_string_none<'de, D, T>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<Option<T>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
T: serde::de::Deserialize<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::{Deserialize, IntoDeserializer};
|
||||||
|
let opt = Option::<String>::deserialize(deserializer)?;
|
||||||
|
match opt.as_deref() {
|
||||||
|
None | Some("") => Ok(None),
|
||||||
|
Some(s) => T::deserialize(s.into_deserializer()).map(Some),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version ba7699aed741222f2431e1f3e4ba42c3ac302510
|
// Version 031d3e7fc343bd86d82c45559fc79d3a87fa1b82
|
||||||
|
|
||||||
//! Automatically generated endpoint handles.
|
//! Automatically generated endpoint handles.
|
||||||
#![allow(clippy::let_and_return, clippy::too_many_arguments)]
|
#![allow(clippy::let_and_return, clippy::too_many_arguments)]
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version ba7699aed741222f2431e1f3e4ba42c3ac302510
|
// Version 031d3e7fc343bd86d82c45559fc79d3a87fa1b82
|
||||||
|
|
||||||
//! Metadata about the Riot API and Riven.
|
//! Metadata about the Riot API and Riven.
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version ba7699aed741222f2431e1f3e4ba42c3ac302510
|
// Version 031d3e7fc343bd86d82c45559fc79d3a87fa1b82
|
||||||
|
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
|
@ -999,7 +999,11 @@ pub mod match_v5 {
|
||||||
#[serde(rename = "gameStartTimestamp")]
|
#[serde(rename = "gameStartTimestamp")]
|
||||||
pub game_start_timestamp: i64,
|
pub game_start_timestamp: i64,
|
||||||
#[serde(rename = "gameType")]
|
#[serde(rename = "gameType")]
|
||||||
pub game_type: crate::consts::GameType,
|
///
|
||||||
|
/// Will be `None` if empty string is returned: https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
#[serde(serialize_with = "crate::consts::serialize_empty_string_none")]
|
||||||
|
#[serde(deserialize_with = "crate::consts::deserialize_empty_string_none")]
|
||||||
|
pub game_type: Option<crate::consts::GameType>,
|
||||||
/// The first two parts can be used to determine the patch a game was played on.
|
/// The first two parts can be used to determine the patch a game was played on.
|
||||||
#[serde(rename = "gameVersion")]
|
#[serde(rename = "gameVersion")]
|
||||||
pub game_version: String,
|
pub game_version: String,
|
||||||
|
@ -2203,7 +2207,8 @@ pub mod match_v5 {
|
||||||
#[serde(rename = "events")]
|
#[serde(rename = "events")]
|
||||||
pub events: std::vec::Vec<MatchTimelineInfoFrameEvent>,
|
pub events: std::vec::Vec<MatchTimelineInfoFrameEvent>,
|
||||||
#[serde(rename = "participantFrames")]
|
#[serde(rename = "participantFrames")]
|
||||||
pub participant_frames: MatchTimelineInfoFrameParticipantFrames,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub participant_frames: Option<MatchTimelineInfoFrameParticipantFrames>,
|
||||||
#[serde(rename = "timestamp")]
|
#[serde(rename = "timestamp")]
|
||||||
pub timestamp: i32,
|
pub timestamp: i32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,38 @@ pub enum GameType {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GameType {
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn serialize_empty<S>(
|
||||||
|
val: &Option<Self>,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::Serialize;
|
||||||
|
if let Some(val) = val {
|
||||||
|
val.serialize(serializer)
|
||||||
|
} else {
|
||||||
|
"".serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
pub(crate) fn deserialize_empty<'de, D>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<Option<Self>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::IntoDeserializer;
|
||||||
|
let opt = Option::<String>::deserialize(deserializer)?;
|
||||||
|
match opt.as_deref() {
|
||||||
|
None | Some("") => Ok(None),
|
||||||
|
Some(s) => Self::deserialize(s.into_deserializer()).map(Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
|
@ -68,6 +68,12 @@ pub mod {{= dotUtils.changeCase.snakeCase(endpoint) }} {
|
||||||
#[serde(serialize_with = "crate::consts::Champion::serialize_result")]
|
#[serde(serialize_with = "crate::consts::Champion::serialize_result")]
|
||||||
#[serde(deserialize_with = "crate::consts::Champion::deserialize_result")]
|
#[serde(deserialize_with = "crate::consts::Champion::deserialize_result")]
|
||||||
pub {{= name }}: Result<crate::consts::Champion, std::num::TryFromIntError>,
|
pub {{= name }}: Result<crate::consts::Champion, std::num::TryFromIntError>,
|
||||||
|
{{?? 'gameType' === propKey && 'Info' === schemaName && 'match-v5' === endpoint }}
|
||||||
|
///
|
||||||
|
/// Will be `None` if empty string is returned: https://github.com/RiotGames/developer-relations/issues/898
|
||||||
|
#[serde(serialize_with = "crate::consts::serialize_empty_string_none")]
|
||||||
|
#[serde(deserialize_with = "crate::consts::deserialize_empty_string_none")]
|
||||||
|
pub {{= name }}: Option<{{= dotUtils.stringifyType(prop, {}) }}>,
|
||||||
{{??}}
|
{{??}}
|
||||||
pub {{= name }}: {{= dotUtils.stringifyType(prop, { optional }) }},
|
pub {{= name }}: {{= dotUtils.stringifyType(prop, { optional }) }},
|
||||||
{{?}}
|
{{?}}
|
||||||
|
|
|
@ -227,6 +227,23 @@ pub async fn match_v5_get(
|
||||||
.champion()
|
.champion()
|
||||||
.map_err(|e| format!("Failed to determine match {} champion: {}", matche, e))?;
|
.map_err(|e| format!("Failed to determine match {} champion: {}", matche, e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let game_id = m.info.game_id;
|
||||||
|
if 0 == game_id {
|
||||||
|
eprintln!(
|
||||||
|
"Match {} `game_id` is zero, skipping remaining tests (see https://github.com/RiotGames/developer-relations/issues/898).",
|
||||||
|
matche
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
} else if matche[(matche.find('_').unwrap() + 1)..] != game_id.to_string() {
|
||||||
|
return Err(format!(
|
||||||
|
"Match {} timeline number ID should match `game_id` {}.",
|
||||||
|
matche, game_id
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if m.info.teams.is_empty() {
|
if m.info.teams.is_empty() {
|
||||||
return Err(format!("Match {} should have teams.", matche));
|
return Err(format!("Match {} should have teams.", matche));
|
||||||
}
|
}
|
||||||
|
@ -256,12 +273,17 @@ pub async fn match_v5_get_timeline(
|
||||||
return Err(format!("Match {} should have participants.", matche));
|
return Err(format!("Match {} should have participants.", matche));
|
||||||
}
|
}
|
||||||
if let Some(game_id) = m.info.game_id {
|
if let Some(game_id) = m.info.game_id {
|
||||||
if matche[(matche.find('_').unwrap() + 1)..] != game_id.to_string() {
|
if 0 == game_id {
|
||||||
return Err(format!("Match {} number ID should match.", matche));
|
eprintln!("Match {} timeline `game_id` is zero (see https://github.com/RiotGames/developer-relations/issues/898).", matche);
|
||||||
|
} else if matche[(matche.find('_').unwrap() + 1)..] != game_id.to_string() {
|
||||||
|
return Err(format!(
|
||||||
|
"Match {} timeline number ID should match `game_id` {}.",
|
||||||
|
matche, game_id
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.info.frames.is_empty() {
|
if m.info.frames.is_empty() {
|
||||||
return Err(format!("Match {} timleine should have frames.", matche));
|
return Err(format!("Match {} timeline should have frames.", matche));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue