pub fn apply_tree_delta(
base: &Value,
delta: &Value,
limits: &Limits,
) -> Result<Value, ValidationError>Expand description
Compose a delta onto the snapshot it names, then validate the result.
The four composition rules, in the order they are applied:
removedtakes each id with its whole subtree. The cascade is what keeps a delta small — dropping a dialog is one id, not one per descendant — and it is the only rule that leaves no orphans behind.- Removals happen before upserts, so one delta can move a node out of a subtree it is deleting.
changedupserts by id, replacing a node wholesale. Merging would need a third state meaning “clear this optional field”, which the wire cannot express.rootIdspresent replaces the list; absent inherits the base’s minus whatever the removals took. Adding a new root therefore requires sendingrootIds— otherwise the parentless node is missing from the root list and validation says so, loudly.
An absent cursor is inherited; there is no way to remove one, and none is
needed, because hiding it is visible: false.
A base that disagrees is reported rather than patched around: the caller
asks for a full snapshot instead of guessing (§8.3). The composed tree then
goes through validate_snapshot, because a delta is trusted to
describe a valid tree, never to produce one.
The order of the composed nodes is not normative; this implementation
keeps base order with new nodes appended, which makes output deterministic.
§Errors
Returns a ValidationError whose code matches the reference.