Handle some unexpected keys in Steam data
This commit is contained in:
parent
629b5c5942
commit
97683408c5
2 changed files with 53 additions and 3 deletions
16
src/cli.rs
16
src/cli.rs
|
@ -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 {
|
||||
|
|
40
src/steam.rs
40
src/steam.rs
|
@ -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,
|
||||
|
|
Reference in a new issue