Apply rustfmt to entire workspace
Runs cargo fmt --all; all 573 tests still passing, clippy still clean. No logic changes — formatting only. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
3d524e2d63
commit
1c107fe58a
@@ -102,7 +102,10 @@ pub fn diff_manifests(old: &DatasetManifest, new: &DatasetManifest) -> DiffResul
|
||||
ord.then_with(|| a.path.cmp(&b.path))
|
||||
});
|
||||
|
||||
DiffResult { patches, unchanged_count }
|
||||
DiffResult {
|
||||
patches,
|
||||
unchanged_count,
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a set of patches keyed by dataset path, look up data bytes in `src`
|
||||
@@ -207,7 +210,7 @@ mod tests {
|
||||
let new = manifest_from(&[("a", vec![1.0]), ("b", vec![9.9]), ("c", vec![3.0])]);
|
||||
let diff = diff_manifests(&old, &new);
|
||||
assert_eq!(diff.unchanged_count, 2); // a and c
|
||||
assert_eq!(diff.patches.len(), 1); // only b modified
|
||||
assert_eq!(diff.patches.len(), 1); // only b modified
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -269,7 +272,10 @@ mod tests {
|
||||
|
||||
let resolved = resolve_patch_data(&diff.patches, &src_file);
|
||||
assert_eq!(resolved.len(), 1);
|
||||
assert!(resolved[0].is_some(), "Added patch should resolve to Some(bytes)");
|
||||
assert!(
|
||||
resolved[0].is_some(),
|
||||
"Added patch should resolve to Some(bytes)"
|
||||
);
|
||||
// 3 f64 values = 24 bytes
|
||||
assert_eq!(resolved[0].as_ref().unwrap().len(), 3 * 8);
|
||||
}
|
||||
@@ -284,7 +290,10 @@ mod tests {
|
||||
// The Removed patch has kind=Removed, so resolve should return None.
|
||||
let resolved = resolve_patch_data(&diff.patches, &src_file);
|
||||
assert_eq!(resolved.len(), 1);
|
||||
assert!(resolved[0].is_none(), "Removed patch should resolve to None");
|
||||
assert!(
|
||||
resolved[0].is_none(),
|
||||
"Removed patch should resolve to None"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -14,7 +14,11 @@ pub enum Hdf5SyncError {
|
||||
DatasetNotFound(String),
|
||||
|
||||
#[error("patch type mismatch for dataset '{path}': expected {expected}, got {actual}")]
|
||||
TypeMismatch { path: String, expected: String, actual: String },
|
||||
TypeMismatch {
|
||||
path: String,
|
||||
expected: String,
|
||||
actual: String,
|
||||
},
|
||||
|
||||
#[error("manifest serialization error: {0}")]
|
||||
Serialize(String),
|
||||
|
||||
@@ -24,5 +24,6 @@ pub mod patcher;
|
||||
pub use differ::{DatasetPatch, DiffResult, PatchKind, diff_manifests};
|
||||
pub use error::Hdf5SyncError;
|
||||
pub use manifest::{DatasetEntry, DatasetManifest};
|
||||
pub use patcher::{PatchStats, ReceivedDataset, apply_patches, apply_patches_to_bytes,
|
||||
apply_received_payloads};
|
||||
pub use patcher::{
|
||||
PatchStats, ReceivedDataset, apply_patches, apply_patches_to_bytes, apply_received_payloads,
|
||||
};
|
||||
|
||||
@@ -48,7 +48,10 @@ impl DatasetManifest {
|
||||
let file = File::open(h5_path)?;
|
||||
let mut datasets = HashMap::new();
|
||||
collect_datasets(file.root(), "", &mut datasets)?;
|
||||
Ok(Self { file_blake3, datasets })
|
||||
Ok(Self {
|
||||
file_blake3,
|
||||
datasets,
|
||||
})
|
||||
}
|
||||
|
||||
/// Build a manifest from already-read bytes (avoids double I/O when the
|
||||
@@ -58,7 +61,10 @@ impl DatasetManifest {
|
||||
let file = File::from_bytes(raw.to_vec())?;
|
||||
let mut datasets = HashMap::new();
|
||||
collect_datasets(file.root(), "", &mut datasets)?;
|
||||
Ok(Self { file_blake3, datasets })
|
||||
Ok(Self {
|
||||
file_blake3,
|
||||
datasets,
|
||||
})
|
||||
}
|
||||
|
||||
/// Return paths of all datasets in this manifest.
|
||||
@@ -113,7 +119,16 @@ fn collect_datasets(
|
||||
let blake3 = blake3_bytes(&raw);
|
||||
let byte_len = raw.len() as u64;
|
||||
|
||||
out.insert(path.clone(), DatasetEntry { path, blake3, shape, dtype, byte_len });
|
||||
out.insert(
|
||||
path.clone(),
|
||||
DatasetEntry {
|
||||
path,
|
||||
blake3,
|
||||
shape,
|
||||
dtype,
|
||||
byte_len,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Recurse into sub-groups
|
||||
@@ -167,10 +182,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn manifest_counts_datasets() {
|
||||
let bytes = write_test_h5(&[
|
||||
("alpha", vec![1.0, 2.0]),
|
||||
("beta", vec![3.0, 4.0, 5.0]),
|
||||
]);
|
||||
let bytes = write_test_h5(&[("alpha", vec![1.0, 2.0]), ("beta", vec![3.0, 4.0, 5.0])]);
|
||||
let m = DatasetManifest::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(m.len(), 2);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,9 @@ pub fn apply_patches_to_bytes(
|
||||
|
||||
for patch in patches {
|
||||
match patch.kind {
|
||||
PatchKind::Removed => { stats.datasets_removed += 1; }
|
||||
PatchKind::Removed => {
|
||||
stats.datasets_removed += 1;
|
||||
}
|
||||
PatchKind::Added => {
|
||||
if let Some(data) = patched.get(&patch.path) {
|
||||
stats.bytes_written += data.raw.len() as u64;
|
||||
@@ -261,7 +263,11 @@ pub fn apply_received_payloads(
|
||||
// Write received (Added/Modified) datasets.
|
||||
for p in payloads {
|
||||
let dtype = dtype_from_str(&p.dtype);
|
||||
let raw = DatasetRaw { raw: p.data.clone(), dtype, shape: p.shape.clone() };
|
||||
let raw = DatasetRaw {
|
||||
raw: p.data.clone(),
|
||||
dtype,
|
||||
shape: p.shape.clone(),
|
||||
};
|
||||
write_dataset(&mut builder, p.path.trim_start_matches('/'), &raw);
|
||||
// Classify as added or modified based on whether server had it.
|
||||
if existing.contains_key(&p.path) {
|
||||
@@ -383,31 +389,41 @@ fn write_dataset(builder: &mut FileBuilder, name: &str, data: &DatasetRaw) {
|
||||
let ds = builder.create_dataset(name);
|
||||
match &data.dtype {
|
||||
DType::F64 => {
|
||||
let vals: Vec<f64> = data.raw.chunks_exact(8)
|
||||
let vals: Vec<f64> = data
|
||||
.raw
|
||||
.chunks_exact(8)
|
||||
.map(|b| f64::from_le_bytes(b.try_into().unwrap_or([0u8; 8])))
|
||||
.collect();
|
||||
ds.with_f64_data(&vals);
|
||||
}
|
||||
DType::F32 => {
|
||||
let vals: Vec<f32> = data.raw.chunks_exact(4)
|
||||
let vals: Vec<f32> = data
|
||||
.raw
|
||||
.chunks_exact(4)
|
||||
.map(|b| f32::from_le_bytes(b.try_into().unwrap_or([0u8; 4])))
|
||||
.collect();
|
||||
ds.with_f32_data(&vals);
|
||||
}
|
||||
DType::I32 => {
|
||||
let vals: Vec<i32> = data.raw.chunks_exact(4)
|
||||
let vals: Vec<i32> = data
|
||||
.raw
|
||||
.chunks_exact(4)
|
||||
.map(|b| i32::from_le_bytes(b.try_into().unwrap_or([0u8; 4])))
|
||||
.collect();
|
||||
ds.with_i32_data(&vals);
|
||||
}
|
||||
DType::I64 => {
|
||||
let vals: Vec<i64> = data.raw.chunks_exact(8)
|
||||
let vals: Vec<i64> = data
|
||||
.raw
|
||||
.chunks_exact(8)
|
||||
.map(|b| i64::from_le_bytes(b.try_into().unwrap_or([0u8; 8])))
|
||||
.collect();
|
||||
ds.with_i64_data(&vals);
|
||||
}
|
||||
DType::U64 => {
|
||||
let vals: Vec<u64> = data.raw.chunks_exact(8)
|
||||
let vals: Vec<u64> = data
|
||||
.raw
|
||||
.chunks_exact(8)
|
||||
.map(|b| u64::from_le_bytes(b.try_into().unwrap_or([0u8; 8])))
|
||||
.collect();
|
||||
// Use i64 storage for u64 (bit-preserving)
|
||||
@@ -462,7 +478,10 @@ mod tests {
|
||||
|
||||
let result = DatasetManifest::from_bytes(&patched).unwrap();
|
||||
let src_m = DatasetManifest::from_bytes(&src).unwrap();
|
||||
assert_eq!(result.get("/x").unwrap().blake3, src_m.get("/x").unwrap().blake3);
|
||||
assert_eq!(
|
||||
result.get("/x").unwrap().blake3,
|
||||
src_m.get("/x").unwrap().blake3
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -495,8 +514,14 @@ mod tests {
|
||||
|
||||
let orig = DatasetManifest::from_bytes(&bytes).unwrap();
|
||||
let result = DatasetManifest::from_bytes(&patched).unwrap();
|
||||
assert_eq!(orig.get("/a").unwrap().blake3, result.get("/a").unwrap().blake3);
|
||||
assert_eq!(orig.get("/b").unwrap().blake3, result.get("/b").unwrap().blake3);
|
||||
assert_eq!(
|
||||
orig.get("/a").unwrap().blake3,
|
||||
result.get("/a").unwrap().blake3
|
||||
);
|
||||
assert_eq!(
|
||||
orig.get("/b").unwrap().blake3,
|
||||
result.get("/b").unwrap().blake3
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -511,7 +536,7 @@ mod tests {
|
||||
let (_, stats) = apply_patches_to_bytes(&diff.patches, &src, &dst).unwrap();
|
||||
|
||||
assert_eq!(stats.datasets_modified, 1); // a
|
||||
assert_eq!(stats.datasets_removed, 1); // b
|
||||
assert_eq!(stats.datasets_removed, 1); // b
|
||||
assert_eq!(stats.datasets_unchanged, 1); // c
|
||||
assert_eq!(stats.datasets_added, 0);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
//! creating real HDF5 files in memory and on disk as needed.
|
||||
|
||||
use clawhdf5::{File, FileBuilder};
|
||||
use clawsync_hdf5::{DatasetManifest, PatchKind, apply_patches, apply_patches_to_bytes, diff_manifests};
|
||||
use clawsync_hdf5::{
|
||||
DatasetManifest, PatchKind, apply_patches, apply_patches_to_bytes, diff_manifests,
|
||||
};
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -37,7 +39,10 @@ fn write_temp_h5(bytes: &[u8]) -> (NamedTempFile, std::path::PathBuf) {
|
||||
/// A dataset present in source but absent from target is added after patching.
|
||||
#[test]
|
||||
fn patch_adds_new_dataset() {
|
||||
let src = h5_bytes(&[("temperature", &[20.0, 21.5, 22.0]), ("humidity", &[55.0, 57.0])]);
|
||||
let src = h5_bytes(&[
|
||||
("temperature", &[20.0, 21.5, 22.0]),
|
||||
("humidity", &[55.0, 57.0]),
|
||||
]);
|
||||
let tgt = h5_bytes(&[("temperature", &[20.0, 21.5, 22.0])]);
|
||||
|
||||
let old_m = DatasetManifest::from_bytes(&tgt).unwrap();
|
||||
@@ -51,7 +56,8 @@ fn patch_adds_new_dataset() {
|
||||
let result_m = DatasetManifest::from_bytes(&patched).unwrap();
|
||||
|
||||
// The new dataset must be present with the correct hash.
|
||||
let result_entry = result_m.get("/humidity")
|
||||
let result_entry = result_m
|
||||
.get("/humidity")
|
||||
.expect("humidity should exist after patching");
|
||||
let src_entry = new_m.get("/humidity").unwrap();
|
||||
assert_eq!(result_entry.blake3, src_entry.blake3);
|
||||
@@ -107,13 +113,22 @@ fn patch_removes_dataset() {
|
||||
let diff = diff_manifests(&old_m, &new_m);
|
||||
|
||||
assert_eq!(diff.of_kind(&PatchKind::Removed).count(), 1);
|
||||
assert_eq!(diff.of_kind(&PatchKind::Removed).next().unwrap().path, "/current");
|
||||
assert_eq!(
|
||||
diff.of_kind(&PatchKind::Removed).next().unwrap().path,
|
||||
"/current"
|
||||
);
|
||||
|
||||
let (patched, _) = apply_patches_to_bytes(&diff.patches, &src, &tgt).unwrap();
|
||||
let result_m = DatasetManifest::from_bytes(&patched).unwrap();
|
||||
|
||||
assert!(result_m.get("/current").is_none(), "current should have been removed");
|
||||
assert!(result_m.get("/voltage").is_some(), "voltage should be retained");
|
||||
assert!(
|
||||
result_m.get("/current").is_none(),
|
||||
"current should have been removed"
|
||||
);
|
||||
assert!(
|
||||
result_m.get("/voltage").is_some(),
|
||||
"voltage should be retained"
|
||||
);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -148,13 +163,13 @@ fn patch_noop_when_identical() {
|
||||
fn patch_multiple_changes() {
|
||||
// source: "kept" (same), "updated" (changed), "added" (new)
|
||||
let src = h5_bytes(&[
|
||||
("kept", &[1.0, 2.0]),
|
||||
("kept", &[1.0, 2.0]),
|
||||
("updated", &[99.0, 100.0]),
|
||||
("added", &[7.0, 8.0, 9.0]),
|
||||
("added", &[7.0, 8.0, 9.0]),
|
||||
]);
|
||||
// target: "kept" (same), "updated" (old values), "removed" (extra)
|
||||
let tgt = h5_bytes(&[
|
||||
("kept", &[1.0, 2.0]),
|
||||
("kept", &[1.0, 2.0]),
|
||||
("updated", &[0.0, 0.0]),
|
||||
("removed", &[42.0]),
|
||||
]);
|
||||
@@ -163,9 +178,9 @@ fn patch_multiple_changes() {
|
||||
let new_m = DatasetManifest::from_bytes(&src).unwrap();
|
||||
let diff = diff_manifests(&old_m, &new_m);
|
||||
|
||||
assert_eq!(diff.of_kind(&PatchKind::Added).count(), 1);
|
||||
assert_eq!(diff.of_kind(&PatchKind::Added).count(), 1);
|
||||
assert_eq!(diff.of_kind(&PatchKind::Modified).count(), 1);
|
||||
assert_eq!(diff.of_kind(&PatchKind::Removed).count(), 1);
|
||||
assert_eq!(diff.of_kind(&PatchKind::Removed).count(), 1);
|
||||
|
||||
let (patched, _) = apply_patches_to_bytes(&diff.patches, &src, &tgt).unwrap();
|
||||
let result_m = DatasetManifest::from_bytes(&patched).unwrap();
|
||||
@@ -194,26 +209,18 @@ fn patch_multiple_changes() {
|
||||
#[test]
|
||||
fn stats_counts_correct() {
|
||||
// source: "a" (modified), "c" (unchanged), "d" (new)
|
||||
let src = h5_bytes(&[
|
||||
("a", &[9.0, 9.0]),
|
||||
("c", &[3.0]),
|
||||
("d", &[4.0, 5.0]),
|
||||
]);
|
||||
let src = h5_bytes(&[("a", &[9.0, 9.0]), ("c", &[3.0]), ("d", &[4.0, 5.0])]);
|
||||
// target: "a" (old values), "b" (to be removed), "c" (same as source)
|
||||
let tgt = h5_bytes(&[
|
||||
("a", &[1.0, 2.0]),
|
||||
("b", &[0.0]),
|
||||
("c", &[3.0]),
|
||||
]);
|
||||
let tgt = h5_bytes(&[("a", &[1.0, 2.0]), ("b", &[0.0]), ("c", &[3.0])]);
|
||||
|
||||
let old_m = DatasetManifest::from_bytes(&tgt).unwrap();
|
||||
let new_m = DatasetManifest::from_bytes(&src).unwrap();
|
||||
let diff = diff_manifests(&old_m, &new_m);
|
||||
let (_, stats) = apply_patches_to_bytes(&diff.patches, &src, &tgt).unwrap();
|
||||
|
||||
assert_eq!(stats.datasets_added, 1, "d was added");
|
||||
assert_eq!(stats.datasets_added, 1, "d was added");
|
||||
assert_eq!(stats.datasets_modified, 1, "a was modified");
|
||||
assert_eq!(stats.datasets_removed, 1, "b was removed");
|
||||
assert_eq!(stats.datasets_removed, 1, "b was removed");
|
||||
assert_eq!(stats.datasets_unchanged, 1, "c was unchanged");
|
||||
// bytes_written must be positive (added + modified + unchanged datasets).
|
||||
assert!(stats.bytes_written > 0);
|
||||
@@ -227,13 +234,8 @@ fn stats_counts_correct() {
|
||||
/// manifest read back from disk matches the source manifest.
|
||||
#[test]
|
||||
fn apply_patches_file_path_api() {
|
||||
let src_bytes = h5_bytes(&[
|
||||
("chan_x", &[1.1, 2.2, 3.3]),
|
||||
("chan_y", &[4.4, 5.5]),
|
||||
]);
|
||||
let tgt_bytes = h5_bytes(&[
|
||||
("chan_x", &[0.0, 0.0, 0.0]),
|
||||
]);
|
||||
let src_bytes = h5_bytes(&[("chan_x", &[1.1, 2.2, 3.3]), ("chan_y", &[4.4, 5.5])]);
|
||||
let tgt_bytes = h5_bytes(&[("chan_x", &[0.0, 0.0, 0.0])]);
|
||||
|
||||
// Write both files to disk using NamedTempFile.
|
||||
let (_src_guard, src_path) = write_temp_h5(&src_bytes);
|
||||
@@ -248,8 +250,11 @@ fn apply_patches_file_path_api() {
|
||||
// Use the file-path API (the one under test).
|
||||
let stats = apply_patches(&diff.patches, &src_path, &tgt_path).unwrap();
|
||||
|
||||
assert!(stats.datasets_added >= 1, "chan_y should have been added");
|
||||
assert!(stats.datasets_modified >= 1, "chan_x should have been modified");
|
||||
assert!(stats.datasets_added >= 1, "chan_y should have been added");
|
||||
assert!(
|
||||
stats.datasets_modified >= 1,
|
||||
"chan_x should have been modified"
|
||||
);
|
||||
|
||||
// Read the patched file back from disk and verify it matches source.
|
||||
let result_m = DatasetManifest::from_path(&tgt_path).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user