#4001: the part comparison lists every field of Part

`same_content` destructures `Document` field by field, so a new field does not
build until someone decides whether a change to it counts. `same_parts` did not
do the same for `Part`: it compared the three fields it knew about by hand, so
a new one would have been silently ignored, and a command that changed only it
would have counted as a no-op. Same rule, same guarantee.
This commit is contained in:
Mat Strange
2026-10-23 16:44:13 +01:00
parent 688fedc677
commit 0c143bae6e
+10 -3
View File
@@ -186,10 +186,17 @@ fn same_blocks(a: &Blocks, b: &Blocks) -> bool {
a.len() == b.len() && a.iter().zip(b).all(|(x, y)| Arc::ptr_eq(x, y) || **x == **y)
}
/// The same parts: the same kinds, the same text bodies and the same blocks.
/// The same parts: the same keys, and each part the same.
fn same_parts(a: &BTreeMap<u32, Part>, b: &BTreeMap<u32, Part>) -> bool {
a.len() == b.len()
&& a.iter().zip(b).all(|((k1, p1), (k2, p2))| k1 == k2 && p1.kind == p2.kind && p1.body == p2.body && same_blocks(&p1.blocks, &p2.blocks))
a.len() == b.len() && a.iter().zip(b).all(|((k1, p1), (k2, p2))| k1 == k2 && same_part(p1, p2))
}
/// The same part: the same kind, text body and blocks. Every field is listed, so a new one
/// does not build until someone decides whether a change to it counts.
fn same_part(a: &Part, b: &Part) -> bool {
let Part { kind, blocks, body } = a;
let Part { kind: other_kind, blocks: other_blocks, body: other_body } = b;
kind == other_kind && body == other_body && same_blocks(blocks, other_blocks)
}
/// The same bytes: the same content. The bytes are compared by address first — a changed