Handle some unexpected keys in Steam data

This commit is contained in:
mtkennerly 2024-04-20 17:54:21 -04:00
parent 629b5c5942
commit 97683408c5
No known key found for this signature in database
GPG key ID: E764BE00BE6E6408
2 changed files with 53 additions and 3 deletions

View file

@ -18,6 +18,21 @@ fn styles() -> clap::builder::styling::Styles {
.placeholder(AnsiColor::Green.on_default())
}
fn parse_games(games: Vec<String>) -> Vec<String> {
if !games.is_empty() {
games
} else {
use std::io::IsTerminal;
let stdin = std::io::stdin();
if stdin.is_terminal() {
vec![]
} else {
stdin.lines().map_while(Result::ok).collect()
}
}
}
#[derive(clap::Parser, Clone, Debug, PartialEq, Eq)]
#[clap(name = "ludusavi-manifest", version, max_term_width = 100, next_line_help = true, styles = styles())]
pub struct Cli {
@ -115,6 +130,7 @@ pub async fn run(
schema::validate_manifest(manifest)?;
}
Subcommand::Solo { local, games } => {
let games = parse_games(games);
let outdated_only = false;
if !local {

View file

@ -202,6 +202,40 @@ mod product_info {
Ok(s == "1")
}
fn parse_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: serde::de::DeserializeOwned,
{
use serde::de::Deserialize;
let mut out = vec![];
let raw = match BTreeMap::<String, serde_json::Value>::deserialize(deserializer) {
Ok(x) => x,
Err(e) => {
println!(" parse_vec: total failure - {e:?}");
return Err(e);
}
};
for (key, value) in raw {
if key.parse::<u32>().is_err() {
println!(" parse_vec: unexpected key '{}'", key);
continue;
}
match serde_json::from_value::<T>(value) {
Ok(value) => out.push(value),
Err(e) => {
println!(" parse_vec: type failure - {e:?}");
return Err(serde::de::Error::custom("parse_vec: type failure - {e:?}"));
}
}
}
Ok(out)
}
#[derive(Debug, Default, Clone, serde::Deserialize)]
pub struct Response {
pub apps: BTreeMap<String, App>,
@ -251,8 +285,8 @@ mod product_info {
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[serde(default)]
pub struct AppUfs {
#[serde(rename = "savefiles")]
pub save_files: BTreeMap<String, AppUfsSaveFile>,
#[serde(rename = "savefiles", deserialize_with = "parse_vec")]
pub save_files: Vec<AppUfsSaveFile>,
#[serde(rename = "rootoverrides")]
pub root_overrides: BTreeMap<String, AppUfsRootOverride>,
}
@ -374,7 +408,7 @@ impl SteamCacheEntry {
saves: app
.ufs
.save_files
.into_values()
.into_iter()
.map(|x| CloudSave {
path: x.path,
pattern: x.pattern,