mirror of
https://github.com/djibux/BoilR.git
synced 2026-09-01 05:53:41 +02:00
Itch: Parse paths as lossy
This commit is contained in:
@@ -5,41 +5,29 @@ use nom::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub(crate) struct DbPaths<'a> {
|
pub(crate) struct DbPaths {
|
||||||
pub(crate) base_path: &'a str,
|
pub(crate) base_path: String,
|
||||||
pub(crate) path: &'a str,
|
pub(crate) path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_butler_db<'a>(content: &'a [u8]) -> nom::IResult<&[u8], Vec<DbPaths<'a>>> {
|
pub(crate) fn parse_butler_db<'a>(content: &'a [u8]) -> nom::IResult<&[u8], Vec<DbPaths>> {
|
||||||
many0(parse_path)(content)
|
many0(parse_path)(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_path<'a>(i: &'a [u8]) -> nom::IResult<&[u8], DbPaths<'a>> {
|
fn parse_path<'a>(i: &'a [u8]) -> nom::IResult<&[u8], DbPaths> {
|
||||||
let prefix = "{\"basePath\":\"";
|
let prefix = "{\"basePath\":\"";
|
||||||
let suffix = "\",\"totalSize\"";
|
let suffix = "\",\"totalSize\"";
|
||||||
let (i, _taken) = take_until(prefix)(i)?;
|
let (i, _taken) = take_until(prefix)(i)?;
|
||||||
let (i, _taken) = tag(prefix)(i)?;
|
let (i, _taken) = tag(prefix)(i)?;
|
||||||
let (i, base_path) = take_until(suffix)(i)?;
|
let (i, base_path) = take_until(suffix)(i)?;
|
||||||
let base_path_str = std::str::from_utf8(base_path);
|
let base_path = String::from_utf8_lossy(base_path).to_string();
|
||||||
let base_path = match base_path_str{
|
|
||||||
Ok(base_path) => base_path,
|
|
||||||
Err(e) => {
|
|
||||||
return convert_to_nom_error(i, e);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let prefix = ":[{\"path\":\"";
|
let prefix = ":[{\"path\":\"";
|
||||||
let suffix = "\",\"depth";
|
let suffix = "\",\"depth";
|
||||||
let (i, _taken) = take_until(prefix)(i)?;
|
let (i, _taken) = take_until(prefix)(i)?;
|
||||||
let (i, _taken) = tag(prefix)(i)?;
|
let (i, _taken) = tag(prefix)(i)?;
|
||||||
let (i, path) = take_until(suffix)(i)?;
|
let (i, path) = take_until(suffix)(i)?;
|
||||||
let path_str = std::str::from_utf8(path);
|
let path = String::from_utf8_lossy(path).to_string();
|
||||||
let path = match path_str{
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(e) => {
|
|
||||||
return convert_to_nom_error(i, e);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
IResult::Ok((
|
IResult::Ok((
|
||||||
i,
|
i,
|
||||||
@@ -50,12 +38,6 @@ fn parse_path<'a>(i: &'a [u8]) -> nom::IResult<&[u8], DbPaths<'a>> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_to_nom_error(i: &[u8], e: std::str::Utf8Error) -> Result<(&[u8], DbPaths), nom::Err<nom::error::Error<&[u8]>>> {
|
|
||||||
use nom::error::*;
|
|
||||||
IResult::Err(nom::Err::Error(Error::from_external_error(i, ErrorKind::AlphaNumeric,e)))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
@@ -91,4 +73,21 @@ mod tests {
|
|||||||
assert_eq!(paths[5].base_path, "/home/philip/.config/itch/apps/islands");
|
assert_eq!(paths[5].base_path, "/home/philip/.config/itch/apps/islands");
|
||||||
assert_eq!(paths[5].path, "Islands_Linux.x86_64");
|
assert_eq!(paths[5].path, "Islands_Linux.x86_64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_itch_butler_db_test_other() {
|
||||||
|
let content = include_bytes!("../testdata/itch/other-butler.db-wal");
|
||||||
|
let result = parse_butler_db(content);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let (_r, paths) = result.unwrap();
|
||||||
|
assert_eq!(paths.len(), 94);
|
||||||
|
|
||||||
|
assert_eq!(paths[0].base_path, "/home/deck/.config/itch/apps/risetoruins");
|
||||||
|
assert_eq!(paths[0].path, "Core.jar");
|
||||||
|
//The parser finds douplicates
|
||||||
|
assert_eq!(paths[0], paths[1]);
|
||||||
|
assert_eq!(paths[1], paths[2]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ impl Platform<ItchGame, ItchErrors> for ItchPlatform {
|
|||||||
}),
|
}),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
//This is done to remove douplicates
|
//This is done dedupe
|
||||||
let paths: HashSet<&DbPaths> = paths.iter().collect();
|
let paths: HashSet<&DbPaths> = paths.iter().collect();
|
||||||
|
|
||||||
let res = paths.iter().filter_map(|e| dbpath_to_game(*e)).collect();
|
let res = paths.iter().filter_map(|e| dbpath_to_game(*e)).collect();
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
@@ -71,8 +70,8 @@ impl Platform<ItchGame, ItchErrors> for ItchPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dbpath_to_game(paths: &DbPaths<'_>) -> Option<ItchGame> {
|
fn dbpath_to_game(paths: &DbPaths) -> Option<ItchGame> {
|
||||||
let recipt = Path::new(paths.base_path)
|
let recipt = Path::new(paths.base_path.as_str())
|
||||||
.join(".itch")
|
.join(".itch")
|
||||||
.join("receipt.json.gz");
|
.join("receipt.json.gz");
|
||||||
if !&recipt.exists() {
|
if !&recipt.exists() {
|
||||||
|
|||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user