On this page· 4
Compare packs
- file format 6
- Rust SDK 1.0 preview
Goal: list what changed between a before pack and an after pack.
- 1. Open both packs.
- 2. Call
diff(&before, &after). - 3. Read
added,removedandchanged, or printto_json().
Needs the Rust SDK
diff.rsrust
// Compare two packs record by record.
use plxi_sdk::{diff, write, OpenOptions, Pack, Record};
fn open(lines: &[&str]) -> Result<Pack, plxi_sdk::Error> {
let records: Vec<Record> = lines
.iter()
.map(|l| Record::from_json_line(l))
.collect::<Result<_, _>>()?;
Pack::from_bytes(write(&records, None)?, OpenOptions::default())
}
fn main() -> Result<(), plxi_sdk::Error> {
let before = open(&[
r#"{"k":"ent","id":"e1","t":"P","name":"A"}"#,
r#"{"k":"ent","id":"e2","t":"P"}"#,
r#"{"k":"rel","src":"e1","tgt":"e2","kind":"knows"}"#,
])?;
let after = open(&[
r#"{"k":"ent","id":"e1","t":"P","name":"B"}"#,
r#"{"k":"ent","id":"e3","t":"P"}"#,
r#"{"k":"rel","src":"e1","tgt":"e2","kind":"knows"}"#,
])?;
let d = diff(&before, &after)?;
let e3 = r#"{"k":"ent","v":1,"id":"e3","t":"P","stub":false}"#;
let e2 = r#"{"k":"ent","v":1,"id":"e2","t":"P","stub":false}"#;
assert_eq!(d.added, [e3]);
assert_eq!(d.removed, [e2]);
assert_eq!(d.changed.len(), 1);
assert_eq!(d.changed[0].key, ("ent".to_string(), "e1".to_string()));
assert!(!d.is_empty());
println!("{}", d.to_json());
// A pack compared with itself has no differences.
assert!(diff(&before, &before)?.is_empty());
Ok(())
}
Output
{"added":["{\"k\":\"ent\",\"v\":1,\"id\":\"e3\",\"t\":\"P\",\"stub\":false}"],"removed":["{\"k\":\"ent\",\"v\":1,\"id\":\"e2\",\"t\":\"P\",\"stub\":false}"],"changed":[{"key":["ent","e1"],"before":"{\"k\":\"ent\",\"v\":1,\"id\":\"e1\",\"t\":\"P\",\"name\":\"A\",\"stub\":false}","after":"{\"k\":\"ent\",\"v\":1,\"id\":\"e1\",\"t\":\"P\",\"name\":\"B\",\"stub\":false}"}],"duplicate_keys":[],"appendix":{"added":[],"removed":[],"changed":[]}}Ran with cargo run --example 06_diff · exit status 0
| Member | Holds |
|---|---|
added | record lines whose key is only in the second pack |
removed | record lines whose key is only in the first pack |
changed | one entry per key in both packs whose identity forms differ: key, before, after |
duplicate_keys | keys that occur more than once in either pack; such a key appears here and nowhere else |
appendix | lists of section indexes: added, removed, changed |
| Case | Input | Result |
|---|---|---|
diff-member-order-only | the same record with members in another order and 1.0 written as 1.00 | every list empty |
diff-duplicate-keys | the after pack holds ent e5 twice | duplicate_keys holds ["ent","e5"], and nothing else |
diff-appendix-section-changed | one byte changed in appendix section 1 | appendix.changed holds [1] |
- Records are compared in identity form. Member order, whitespace and number spelling alone are never a difference.
- Diff has a direction: the first pack is before, the second is after.
- Appendix sections are matched by position and compared by type and CRC32C. A section inserted at index 0 makes every later index read as changed, and the diff names section indexes, not rows.
- Diff does not check that relations still point at entities. In the example, the after pack keeps a relation to
e2, which was removed. - Both packs are opened first, so both were verified unless opened with
no_verify().