mod keys;
mod ldb;
mod merge;
mod nbt;
mod split;
pub use merge::merge;
pub use split::split;
pub enum ProgressEvent {
Phase(&'static str),
Total(u64),
Advance(u64),
}
pub struct RoundTripReport {
pub pairs_checked: usize,
}
pub fn verify_round_trip(
world: &std::path::Path,
cb: &mut dyn FnMut(ProgressEvent),
) -> anyhow::Result<RoundTripReport> {
let temp_base = world.parent().unwrap_or(std::path::Path::new("."));
let tmp = tempfile::Builder::new().tempdir_in(temp_base)?;
let split_dir = tmp.path().join("split");
let merged_dir = tmp.path().join("merged");
split(world, &split_dir, cb)?;
merge(&split_dir, &merged_dir, cb)?;
let mut original_db = ldb::open_world_db(&world.join("db"))?;
let original_pairs = ldb::read_all(&mut original_db)?;
let mut reconstructed_db = ldb::open_world_db(&merged_dir.join("db"))?;
let reconstructed_pairs = ldb::read_all(&mut reconstructed_db)?;
let orig_map: std::collections::HashMap<Vec<u8>, Vec<u8>> =
original_pairs.into_iter().collect();
let reco_map: std::collections::HashMap<Vec<u8>, Vec<u8>> =
reconstructed_pairs.into_iter().collect();
anyhow::ensure!(
orig_map.len() == reco_map.len(),
"DB entry count mismatch: original={} reconstructed={}",
orig_map.len(),
reco_map.len(),
);
for (key, orig_val) in &orig_map {
let reco_val = reco_map
.get(key)
.ok_or_else(|| anyhow::anyhow!("Key missing from reconstructed DB: {key:?}"))?;
anyhow::ensure!(orig_val == reco_val, "Value mismatch for key {key:?}");
}
Ok(RoundTripReport {
pairs_checked: orig_map.len(),
})
}