Files
STARTLINER/rust/src/patcher.rs
2025-04-19 19:48:08 +00:00

49 lines
1.6 KiB
Rust

use std::path::Path;
use anyhow::Result;
use sha256::try_digest;
use crate::model::patch::{Patch, PatchFile, PatchFileVec};
impl PatchFileVec {
pub fn new(config_path: impl AsRef<Path>) -> Result<PatchFileVec> {
let path = config_path.as_ref().join("patches");
if !path.exists() {
std::fs::create_dir(&path)?;
}
std::fs::write(path.join("builtin-chunithm.json5"), include_bytes!("../static/standard-chunithm.json5"))?;
let mut res = Vec::new();
for f in std::fs::read_dir(path)? {
let f = f?;
let f = &f.path();
match serde_json5::from_str::<PatchFile>(&std::fs::read_to_string(f)?) {
Ok(parsed) => res.push(parsed),
Err(e) => {
log::error!("Error parsing {f:?}: {e}");
anyhow::bail!("Error parsing {f:?}: {e}");
}
}
}
Ok(PatchFileVec(res))
}
pub fn find_patches(&self, target: impl AsRef<Path>) -> Result<Vec<Patch>> {
let checksum = try_digest(target.as_ref())?;
let mut res = Vec::new();
for pfile in &self.0 {
for plist in &pfile.0 {
log::debug!("checking {}", plist.sha256.to_ascii_lowercase());
if plist.sha256.to_ascii_lowercase() == checksum {
let mut cloned = plist.clone().patches;
res.append(&mut cloned);
}
}
}
if res.len() == 0 {
log::warn!("no matching patchset for {:?} ({})", target.as_ref(), checksum);
}
Ok(res)
}
}