1use std::cell::{Cell, RefCell};
13
14use serde::Serialize;
15use serde::ser::{Impossible, SerializeMap, SerializeSeq, SerializeStruct, Serializer};
16use serde_json::{Map, Value};
17
18pub struct Diff {
20 pub patch: Value,
22
23 pub forced_snapshot: bool,
28}
29
30pub fn diff<T: Serialize>(old: &Value, new: &T) -> Diff {
35 let result = bytes(old, new, &RefCell::new(Scratch::default())).unwrap_or(PatchBytes {
36 patch: Vec::new(),
37 forced_snapshot: true,
38 });
39 Diff {
40 patch: if result.patch.is_empty() {
41 Value::Object(Map::new())
42 } else {
43 serde_json::from_slice(&result.patch).expect("the diff serializer emits JSON")
44 },
45 forced_snapshot: result.forced_snapshot,
46 }
47}
48
49#[derive(Default)]
50pub(crate) struct Scratch {
51 seen: Vec<Vec<String>>,
52 pending: Vec<String>,
53 bytes: Vec<Vec<u8>>,
54 last_capacity: usize,
55 memo: Option<Memo>,
57}
58
59impl Scratch {
60 pub(crate) fn memoized() -> Self {
62 Self {
63 memo: Some(Memo::default()),
64 ..Self::default()
65 }
66 }
67
68 fn buffer(&mut self, depth: usize) -> &mut Vec<u8> {
69 if self.bytes.len() <= depth {
70 self.bytes.resize_with(depth + 1, Vec::new);
71 }
72 &mut self.bytes[depth]
73 }
74
75 pub(crate) fn commit_memo(&mut self) {
78 if let Some(memo) = self.memo.as_mut() {
79 std::mem::swap(&mut memo.current, &mut memo.next);
80 }
81 }
82
83 pub(crate) fn clear_memo(&mut self) {
85 if let Some(memo) = self.memo.as_mut() {
86 memo.current.clear();
87 memo.next.clear();
88 }
89 }
90}
91
92#[derive(Default)]
106pub(crate) struct Memo {
111 current: Entries,
113 next: Entries,
115 check: RefCell<crate::merge::CheckScratch>,
117}
118
119#[derive(Default)]
120struct Entries {
121 bytes: Vec<u8>,
123 ends: Vec<(usize, usize)>,
125 unsorted: bool,
127}
128
129impl Entries {
130 fn clear(&mut self) {
131 self.bytes.clear();
132 self.ends.clear();
133 self.unsorted = false;
134 }
135
136 fn key(&self, index: usize) -> &[u8] {
137 let start = index.checked_sub(1).map_or(0, |prev| self.ends[prev].1);
138 &self.bytes[start..self.ends[index].0]
139 }
140
141 fn value(&self, index: usize) -> &[u8] {
142 &self.bytes[self.ends[index].0..self.ends[index].1]
143 }
144
145 fn find(&self, key: &[u8], cursor: &mut usize) -> Option<usize> {
148 for index in [*cursor, *cursor + 1] {
150 if index < self.ends.len() && self.key(index) == key {
151 *cursor = index + 1;
152 return Some(index);
153 }
154 }
155 if self.unsorted {
156 return None;
157 }
158 while *cursor < self.ends.len() && self.key(*cursor) < key {
161 *cursor += 1;
162 }
163 if *cursor < self.ends.len() && self.key(*cursor) == key {
164 *cursor += 1;
165 return Some(*cursor - 1);
166 }
167 None
168 }
169}
170
171pub(crate) struct PatchBytes {
172 pub patch: Vec<u8>,
173 pub forced_snapshot: bool,
174}
175
176pub(crate) fn bytes<T: Serialize>(old: &Value, new: &T, scratch: &RefCell<Scratch>) -> Result<PatchBytes, String> {
181 if let Some(memo) = scratch.borrow_mut().memo.as_mut() {
182 memo.next.clear();
183 }
184 let forced = Cell::new(false);
185 let node = new.serialize(Differ {
186 baseline: old,
187 present: true,
188 forced: &forced,
189 scratch,
190 depth: 0,
191 });
192 match node {
193 Ok(Node::Same) => Ok(PatchBytes {
194 patch: Vec::new(),
195 forced_snapshot: forced.get(),
196 }),
197 Ok(Node::Diff) => {
198 let mut scratch = scratch.borrow_mut();
199 let patch = std::mem::take(scratch.buffer(0));
200 scratch.last_capacity = patch.capacity();
201 let forced_snapshot = forced.get() || !patch.starts_with(b"{") || !old.is_object();
202 Ok(PatchBytes { patch, forced_snapshot })
203 }
204 Err(err) => Err(err.0),
205 }
206}
207
208enum Node {
210 Same,
212 Diff,
214}
215
216const NULL: Value = Value::Null;
217
218#[derive(Copy, Clone)]
221struct Differ<'a> {
222 baseline: &'a Value,
223 present: bool,
224 forced: &'a Cell<bool>,
225 scratch: &'a RefCell<Scratch>,
226 depth: usize,
227}
228
229impl<'a> Differ<'a> {
230 fn child(&self, key: &str) -> (Differ<'a>, bool) {
233 let (baseline, existed) = match self.baseline {
234 Value::Object(m) => match m.get(key) {
235 Some(value) => (value, true),
236 None => (&NULL, false),
237 },
238 _ => (&NULL, false),
239 };
240 (
241 Differ {
242 baseline,
243 present: existed,
244 forced: self.forced,
245 scratch: self.scratch,
246 depth: self.depth + 1,
247 },
248 existed,
249 )
250 }
251
252 fn scalar<T: Serialize + ?Sized>(self, value: &T, equal: bool, null: bool) -> Result<Node, Error> {
254 if equal {
255 return Ok(Node::Same);
256 }
257 if null {
258 self.forced.set(true);
259 }
260 let mut scratch = self.scratch.borrow_mut();
261 let capacity = scratch.last_capacity;
262 let bytes = scratch.buffer(self.depth);
263 bytes.clear();
264 if self.depth == 0 {
265 bytes.reserve(capacity);
266 }
267 serde_json::to_writer(bytes, value).map_err(|err| Error(err.to_string()))?;
268 Ok(Node::Diff)
269 }
270}
271
272fn lockstep(
280 old: &[u8],
281 new: &[u8],
282 patch: &mut Vec<u8>,
283 forced: &mut bool,
284 check: &RefCell<crate::merge::CheckScratch>,
285) -> Option<()> {
286 if old.first() != Some(&b'{') || new.first() != Some(&b'{') {
287 return replace(new, patch, forced, check);
288 }
289 if old.get(1) == Some(&b'}') || new.get(1) == Some(&b'}') {
291 return None;
292 }
293 let (mut i, mut j) = (1, 1);
294 let mut first = true;
295 loop {
296 let (old_key, new_key) = (skip(old, i)?, skip(new, j)?);
297 if old[i..old_key] != new[j..new_key] {
298 return None;
299 }
300 let (old_end, new_end) = (skip(old, old_key + 1)?, skip(new, new_key + 1)?);
302 let (old_value, new_value) = (&old[old_key + 1..old_end], &new[new_key + 1..new_end]);
303 if old_value != new_value {
304 patch.push(if first { b'{' } else { b',' });
305 first = false;
306 patch.extend_from_slice(&new[j..=new_key]);
307 lockstep(old_value, new_value, patch, forced, check)?;
308 }
309 match (old.get(old_end), new.get(new_end)) {
310 (Some(b','), Some(b',')) => (i, j) = (old_end + 1, new_end + 1),
311 (Some(b'}'), Some(b'}')) => break,
312 _ => return None,
313 }
314 }
315 debug_assert!(!first, "differing bytes under the same keys leave a changed value");
316 patch.push(b'}');
317 Some(())
318}
319
320fn replace(
327 new: &[u8],
328 patch: &mut Vec<u8>,
329 forced: &mut bool,
330 check: &RefCell<crate::merge::CheckScratch>,
331) -> Option<()> {
332 match new {
333 b"null" => *forced = true,
334 [b'{', ..] if new.windows(4).any(|window| window == b"null") => return None,
335 [b'{' | b'[', ..] if crate::merge::check(new, check).is_err() => return None,
336 _ => {}
337 }
338 patch.extend_from_slice(new);
339 Some(())
340}
341
342fn skip(bytes: &[u8], start: usize) -> Option<usize> {
344 let mut depth = 0usize;
345 let mut index = start;
346 loop {
347 match *bytes.get(index)? {
348 b'"' => {
349 index += 1;
350 loop {
351 match *bytes.get(index)? {
352 b'\\' => index += 2,
353 b'"' => break,
354 _ => index += 1,
355 }
356 }
357 index += 1;
358 }
359 b'{' | b'[' => {
360 depth += 1;
361 index += 1;
362 }
363 b'}' | b']' => {
364 depth = depth.checked_sub(1)?;
365 index += 1;
366 }
367 _ => index += 1,
368 }
369 if depth == 0 && matches!(bytes.get(index), None | Some(b',' | b'}' | b']' | b':')) {
370 return Some(index);
371 }
372 }
373}
374
375#[derive(Debug)]
377struct Error(String);
378
379impl std::fmt::Display for Error {
380 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381 f.write_str(&self.0)
382 }
383}
384
385impl std::error::Error for Error {}
386
387impl serde::ser::Error for Error {
388 fn custom<M: std::fmt::Display>(msg: M) -> Self {
389 Error(msg.to_string())
390 }
391}
392
393fn to_plain<T: Serialize + ?Sized>(value: &T) -> Result<Value, Error> {
395 serde_json::to_value(value).map_err(|e| Error(e.to_string()))
396}
397
398impl<'a> Serializer for Differ<'a> {
399 type Ok = Node;
400 type Error = Error;
401 type SerializeSeq = SeqDiff<'a>;
402 type SerializeTuple = SeqDiff<'a>;
403 type SerializeTupleStruct = SeqDiff<'a>;
404 type SerializeTupleVariant = VariantSeq<'a>;
405 type SerializeMap = MapDiff<'a>;
406 type SerializeStruct = MapDiff<'a>;
407 type SerializeStructVariant = VariantMap<'a>;
408
409 fn serialize_bool(self, v: bool) -> Result<Node, Error> {
410 self.scalar(&v, self.baseline == &Value::Bool(v), false)
411 }
412 fn serialize_i8(self, v: i8) -> Result<Node, Error> {
413 self.scalar(&v, self.baseline == &Value::from(v), false)
414 }
415 fn serialize_i16(self, v: i16) -> Result<Node, Error> {
416 self.scalar(&v, self.baseline == &Value::from(v), false)
417 }
418 fn serialize_i32(self, v: i32) -> Result<Node, Error> {
419 self.scalar(&v, self.baseline == &Value::from(v), false)
420 }
421 fn serialize_i64(self, v: i64) -> Result<Node, Error> {
422 self.scalar(&v, self.baseline == &Value::from(v), false)
423 }
424 fn serialize_i128(self, v: i128) -> Result<Node, Error> {
425 {
426 let plain = to_plain(&v)?;
427 self.scalar(&plain, self.baseline == &plain, false)
428 }
429 }
430 fn serialize_u8(self, v: u8) -> Result<Node, Error> {
431 self.scalar(&v, self.baseline == &Value::from(v), false)
432 }
433 fn serialize_u16(self, v: u16) -> Result<Node, Error> {
434 self.scalar(&v, self.baseline == &Value::from(v), false)
435 }
436 fn serialize_u32(self, v: u32) -> Result<Node, Error> {
437 self.scalar(&v, self.baseline == &Value::from(v), false)
438 }
439 fn serialize_u64(self, v: u64) -> Result<Node, Error> {
440 self.scalar(&v, self.baseline == &Value::from(v), false)
441 }
442 fn serialize_u128(self, v: u128) -> Result<Node, Error> {
443 {
444 let plain = to_plain(&v)?;
445 self.scalar(&plain, self.baseline == &plain, false)
446 }
447 }
448 fn serialize_f32(self, v: f32) -> Result<Node, Error> {
449 self.scalar(&v, self.baseline == &Value::from(v), false)
450 }
451 fn serialize_f64(self, v: f64) -> Result<Node, Error> {
452 self.scalar(&v, self.baseline == &Value::from(v), false)
453 }
454 fn serialize_char(self, v: char) -> Result<Node, Error> {
455 let mut utf8 = [0; 4];
456 self.scalar(&v, self.baseline.as_str() == Some(v.encode_utf8(&mut utf8)), false)
457 }
458 fn serialize_str(self, v: &str) -> Result<Node, Error> {
459 if matches!(self.baseline, Value::String(b) if b == v) {
462 Ok(Node::Same)
463 } else {
464 self.scalar(&v, false, false)
465 }
466 }
467 fn serialize_bytes(self, v: &[u8]) -> Result<Node, Error> {
468 let mut seq = self.serialize_seq(Some(v.len()))?;
469 for byte in v {
470 SerializeSeq::serialize_element(&mut seq, byte)?;
471 }
472 SerializeSeq::end(seq)
473 }
474 fn serialize_none(self) -> Result<Node, Error> {
475 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
476 }
477 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Node, Error> {
478 value.serialize(self)
479 }
480 fn serialize_unit(self) -> Result<Node, Error> {
481 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
482 }
483 fn serialize_unit_struct(self, _name: &'static str) -> Result<Node, Error> {
484 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
485 }
486 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<Node, Error> {
487 self.scalar(&variant, self.baseline.as_str() == Some(variant), false)
488 }
489 fn serialize_newtype_struct<T: Serialize + ?Sized>(self, _name: &'static str, value: &T) -> Result<Node, Error> {
490 value.serialize(self)
491 }
492 fn serialize_newtype_variant<T: Serialize + ?Sized>(
493 self,
494 _name: &'static str,
495 _idx: u32,
496 variant: &'static str,
497 value: &T,
498 ) -> Result<Node, Error> {
499 Variant { name: variant, value }.serialize(self)
503 }
504 fn serialize_seq(self, len: Option<usize>) -> Result<SeqDiff<'a>, Error> {
505 let _ = len;
506 self.scratch.borrow_mut().buffer(self.depth).clear();
507 Ok(SeqDiff {
508 differ: self,
509 changed: false,
510 len: 0,
511 })
512 }
513 fn serialize_tuple(self, len: usize) -> Result<SeqDiff<'a>, Error> {
514 self.serialize_seq(Some(len))
515 }
516 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqDiff<'a>, Error> {
517 self.serialize_seq(Some(len))
518 }
519 fn serialize_tuple_variant(
520 self,
521 _name: &'static str,
522 _idx: u32,
523 variant: &'static str,
524 len: usize,
525 ) -> Result<VariantSeq<'a>, Error> {
526 Ok(VariantSeq {
528 differ: self,
529 variant,
530 items: self.child(variant).0.serialize_seq(Some(len))?,
531 })
532 }
533 fn serialize_map(self, _len: Option<usize>) -> Result<MapDiff<'a>, Error> {
534 self.scratch.borrow_mut().buffer(self.depth).clear();
535 Ok(MapDiff {
536 differ: self,
537 entries: 0,
538 seen_len: 0,
539 ordered: true,
540 added_key: false,
541 memo_cursor: 0,
542 })
543 }
544 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapDiff<'a>, Error> {
545 self.serialize_map(Some(len))
546 }
547 fn serialize_struct_variant(
548 self,
549 _name: &'static str,
550 _idx: u32,
551 variant: &'static str,
552 _len: usize,
553 ) -> Result<VariantMap<'a>, Error> {
554 Ok(VariantMap {
556 differ: self,
557 variant,
558 fields: self.child(variant).0.serialize_map(Some(_len))?,
559 })
560 }
561}
562
563struct Variant<'a, T: ?Sized> {
565 name: &'static str,
566 value: &'a T,
567}
568
569impl<T: Serialize + ?Sized> Serialize for Variant<'_, T> {
570 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
571 let mut map = serializer.serialize_map(Some(1))?;
572 map.serialize_entry(self.name, self.value)?;
573 map.end()
574 }
575}
576
577fn finish_variant(differ: Differ<'_>, variant: &'static str, node: Node) -> Result<Node, Error> {
579 let (_, existed) = differ.child(variant);
580 let mut outer = differ.serialize_map(Some(1))?;
581 outer.entry(variant, existed, node)?;
582 SerializeMap::end(outer)
583}
584
585struct VariantSeq<'a> {
586 differ: Differ<'a>,
587 variant: &'static str,
588 items: SeqDiff<'a>,
589}
590
591impl serde::ser::SerializeTupleVariant for VariantSeq<'_> {
592 type Ok = Node;
593 type Error = Error;
594 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
595 SerializeSeq::serialize_element(&mut self.items, value)
596 }
597 fn end(self) -> Result<Node, Error> {
598 finish_variant(self.differ, self.variant, SerializeSeq::end(self.items)?)
599 }
600}
601
602struct VariantMap<'a> {
603 differ: Differ<'a>,
604 variant: &'static str,
605 fields: MapDiff<'a>,
606}
607
608impl serde::ser::SerializeStructVariant for VariantMap<'_> {
609 type Ok = Node;
610 type Error = Error;
611 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
612 SerializeStruct::serialize_field(&mut self.fields, key, value)
613 }
614 fn end(self) -> Result<Node, Error> {
615 finish_variant(self.differ, self.variant, SerializeStruct::end(self.fields)?)
616 }
617}
618
619struct SeqDiff<'a> {
621 differ: Differ<'a>,
622 changed: bool,
623 len: usize,
624}
625
626impl SeqDiff<'_> {
627 fn begin(&mut self, old: &[Value]) -> Result<(), Error> {
628 let mut scratch = self.differ.scratch.borrow_mut();
629 let capacity = scratch.last_capacity;
630 let bytes = scratch.buffer(self.differ.depth);
631 bytes.clear();
632 if self.differ.depth == 0 {
633 bytes.reserve(capacity);
634 }
635 bytes.push(b'[');
636 for item in &old[..self.len] {
637 if bytes.len() > 1 {
638 bytes.push(b',');
639 }
640 serde_json::to_writer(&mut *bytes, item).map_err(|err| Error(err.to_string()))?;
641 }
642 self.changed = true;
643 Ok(())
644 }
645}
646
647impl SerializeSeq for SeqDiff<'_> {
648 type Ok = Node;
649 type Error = Error;
650 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
651 let old = self.differ.baseline.as_array();
652 if !self.changed {
653 let baseline = old.and_then(|old| old.get(self.len)).unwrap_or(&NULL);
654 let forced = Cell::new(false);
656 let equal = matches!(
657 value.serialize(Differ {
658 baseline,
659 present: true,
660 forced: &forced,
661 scratch: self.differ.scratch,
662 depth: self.differ.depth + 1,
663 })?,
664 Node::Same
665 ) && old.is_some_and(|old| self.len < old.len());
666 if !equal {
667 self.begin(old.map(Vec::as_slice).unwrap_or(&[]))?;
668 }
669 }
670 if self.changed {
671 let mut scratch = self.differ.scratch.borrow_mut();
672 let bytes = scratch.buffer(self.differ.depth);
673 if bytes.len() > 1 {
674 bytes.push(b',');
675 }
676 serde_json::to_writer(bytes, value).map_err(|err| Error(err.to_string()))?;
677 }
678 self.len += 1;
679 Ok(())
680 }
681 fn end(mut self) -> Result<Node, Error> {
682 if !self.changed {
683 if let Some(old) = self.differ.baseline.as_array() {
684 if self.len == old.len() {
685 return Ok(Node::Same);
686 }
687 self.begin(old)?;
688 } else {
689 self.begin(&[])?;
690 }
691 }
692 self.differ.scratch.borrow_mut().buffer(self.differ.depth).push(b']');
693 Ok(Node::Diff)
694 }
695}
696
697impl serde::ser::SerializeTuple for SeqDiff<'_> {
698 type Ok = Node;
699 type Error = Error;
700 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
701 SerializeSeq::serialize_element(self, value)
702 }
703 fn end(self) -> Result<Node, Error> {
704 SerializeSeq::end(self)
705 }
706}
707
708impl serde::ser::SerializeTupleStruct for SeqDiff<'_> {
709 type Ok = Node;
710 type Error = Error;
711 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
712 SerializeSeq::serialize_element(self, value)
713 }
714 fn end(self) -> Result<Node, Error> {
715 SerializeSeq::end(self)
716 }
717}
718
719enum Memoized {
721 Off,
723 Hit(Node),
725 Miss,
727}
728
729struct MapDiff<'a> {
731 differ: Differ<'a>,
732 entries: usize,
733 seen_len: usize,
734 ordered: bool,
735 added_key: bool,
736 memo_cursor: usize,
738}
739
740impl MapDiff<'_> {
741 fn value<T: Serialize + ?Sized>(&mut self, key: &str, value: &T) -> Result<(), Error> {
743 let (node, existed) = match self.memoized(key, value)? {
744 Memoized::Hit(node) => (node, true),
745 Memoized::Off => {
746 let (child, existed) = self.differ.child(key);
747 (value.serialize(child)?, existed)
748 }
749 Memoized::Miss => {
750 let entry: Value = {
754 let scratch = self.differ.scratch.borrow();
755 let memo = scratch.memo.as_ref().expect("a miss implies a memo");
756 let (start, end) = *memo.next.ends.last().expect("a miss records its entry");
757 let bytes = &memo.next.bytes[start..end];
758 crate::merge::check(bytes, &memo.check)
759 .and_then(|()| serde_json::from_slice(bytes))
760 .map_err(|err| Error(err.to_string()))?
761 };
762 let (child, existed) = self.differ.child(key);
763 (entry.serialize(child)?, existed)
764 }
765 };
766 self.entry(key, existed, node)
767 }
768
769 fn memoized<T: Serialize + ?Sized>(&mut self, key: &str, value: &T) -> Result<Memoized, Error> {
775 if self.differ.depth != 0 {
776 return Ok(Memoized::Off);
777 }
778 let mut scratch = self.differ.scratch.borrow_mut();
779 let Scratch { memo, bytes, .. } = &mut *scratch;
780 let Some(Memo { current, next, check }) = memo.as_mut() else {
781 return Ok(Memoized::Off);
782 };
783 if let Some(last) = next.ends.len().checked_sub(1)
784 && next.key(last) >= key.as_bytes()
785 {
786 next.unsorted = true;
787 }
788 next.bytes.extend_from_slice(key.as_bytes());
789 let key_end = next.bytes.len();
790 serde_json::to_writer(&mut next.bytes, value).map_err(|err| Error(err.to_string()))?;
791 next.ends.push((key_end, next.bytes.len()));
792
793 let Some(index) = current.find(key.as_bytes(), &mut self.memo_cursor) else {
794 return Ok(Memoized::Miss);
795 };
796 let (old, new) = (current.value(index), &next.bytes[key_end..]);
797 if old == new {
798 return Ok(Memoized::Hit(Node::Same));
799 }
800 if bytes.len() < 2 {
801 bytes.resize_with(2, Vec::new);
802 }
803 let patch = &mut bytes[1];
804 patch.clear();
805 let mut forced = false;
806 if lockstep(old, new, patch, &mut forced, check).is_none() {
807 return Ok(Memoized::Miss);
808 }
809 if forced {
810 self.differ.forced.set(true);
811 }
812 Ok(Memoized::Hit(Node::Diff))
813 }
814
815 fn write_entry(&mut self, key: &str, child: Option<usize>) -> Result<(), Error> {
816 let depth = self.differ.depth;
817 let mut scratch = self.differ.scratch.borrow_mut();
818 let capacity = scratch.last_capacity;
819 let bytes = scratch.buffer(depth);
820 if self.entries == 0 {
821 if depth == 0 {
822 bytes.reserve(capacity);
823 }
824 bytes.push(b'{');
825 } else {
826 bytes.push(b',');
827 }
828 serde_json::to_writer(&mut *bytes, key).map_err(|err| Error(err.to_string()))?;
829 bytes.push(b':');
830 if let Some(child) = child {
831 let (parents, children) = scratch.bytes.split_at_mut(child);
832 parents[depth].extend_from_slice(&children[0]);
833 } else {
834 scratch.bytes[depth].extend_from_slice(b"null");
835 }
836 self.entries += 1;
837 Ok(())
838 }
839
840 fn entry(&mut self, key: &str, existed: bool, node: Node) -> Result<(), Error> {
841 self.added_key |= !existed;
842 if let Node::Diff = node {
843 self.write_entry(key, Some(self.differ.depth + 1))?;
844 }
845 let mut scratch = self.differ.scratch.borrow_mut();
846 if scratch.seen.len() <= self.differ.depth {
847 scratch.seen.resize_with(self.differ.depth + 1, Vec::new);
848 }
849 let seen = &mut scratch.seen[self.differ.depth];
850 if self.seen_len > 0 {
851 match seen[self.seen_len - 1].as_str().cmp(key) {
852 std::cmp::Ordering::Equal => return Err(Error("duplicate JSON object key".into())),
853 std::cmp::Ordering::Greater => self.ordered = false,
854 std::cmp::Ordering::Less => {}
855 }
856 }
857 if self.seen_len == seen.len() {
858 seen.push(key.to_owned());
859 } else {
860 seen[self.seen_len].clear();
861 seen[self.seen_len].push_str(key);
862 }
863 self.seen_len += 1;
864 Ok(())
865 }
866
867 fn finish(mut self) -> Result<Node, Error> {
868 if !self.ordered {
869 let mut scratch = self.differ.scratch.borrow_mut();
870 let seen = &mut scratch.seen[self.differ.depth][..self.seen_len];
871 seen.sort_unstable();
872 if seen.windows(2).any(|pair| pair[0] == pair[1]) {
873 return Err(Error("duplicate JSON object key".into()));
874 }
875 }
876 if let Value::Object(base) = self.differ.baseline
877 && (self.added_key || self.seen_len != base.len())
878 {
879 let depth = self.differ.depth;
880 let mut scratch = self.differ.scratch.borrow_mut();
881 let Scratch {
882 seen,
883 bytes,
884 last_capacity,
885 ..
886 } = &mut *scratch;
887 let seen: &mut [String] = match seen.get_mut(depth) {
889 Some(seen) => &mut seen[..self.seen_len],
890 None => &mut [],
891 };
892 let out = &mut bytes[depth];
893 if self.ordered {
894 seen.sort_unstable();
895 }
896 for key in base.keys() {
897 if seen.binary_search_by(|seen| seen.as_str().cmp(key)).is_err() {
898 if self.entries == 0 {
899 if depth == 0 {
900 out.reserve(*last_capacity);
901 }
902 out.push(b'{');
903 } else {
904 out.push(b',');
905 }
906 serde_json::to_writer(&mut *out, key).map_err(|err| Error(err.to_string()))?;
907 out.extend_from_slice(b":null");
908 self.entries += 1;
909 }
910 }
911 }
912 if self.entries == 0 {
913 if self.differ.baseline.is_object() {
914 return Ok(Node::Same);
915 }
916 self.differ
917 .scratch
918 .borrow_mut()
919 .buffer(self.differ.depth)
920 .extend_from_slice(b"{}");
921 return Ok(Node::Diff);
922 }
923 self.differ.scratch.borrow_mut().buffer(self.differ.depth).push(b'}');
924 Ok(Node::Diff)
925 }
926}
927
928impl SerializeMap for MapDiff<'_> {
929 type Ok = Node;
930 type Error = Error;
931 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Error> {
932 let mut scratch = self.differ.scratch.borrow_mut();
933 if scratch.pending.len() <= self.differ.depth {
934 scratch.pending.resize_with(self.differ.depth + 1, String::new);
935 }
936 let pending = &mut scratch.pending[self.differ.depth];
937 pending.clear();
938 key.serialize(KeySer(pending))
939 }
940 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
941 let depth = self.differ.depth;
942 let key = std::mem::take(&mut self.differ.scratch.borrow_mut().pending[depth]);
943 let result = self.value(&key, value);
944 self.differ.scratch.borrow_mut().pending[depth] = key;
945 result
946 }
947 fn end(self) -> Result<Node, Error> {
948 self.finish()
949 }
950}
951
952impl SerializeStruct for MapDiff<'_> {
953 type Ok = Node;
954 type Error = Error;
955 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
956 self.value(key, value)
957 }
958 fn end(self) -> Result<Node, Error> {
961 self.finish()
962 }
963}
964
965struct KeySer<'a>(&'a mut String);
968
969impl Serializer for KeySer<'_> {
970 type Ok = ();
971 type Error = Error;
972 type SerializeSeq = Impossible<(), Error>;
973 type SerializeTuple = Impossible<(), Error>;
974 type SerializeTupleStruct = Impossible<(), Error>;
975 type SerializeTupleVariant = Impossible<(), Error>;
976 type SerializeMap = Impossible<(), Error>;
977 type SerializeStruct = Impossible<(), Error>;
978 type SerializeStructVariant = Impossible<(), Error>;
979
980 fn serialize_str(self, v: &str) -> Result<(), Error> {
981 {
982 self.0.push_str(v);
983 Ok(())
984 }
985 }
986 fn serialize_char(self, v: char) -> Result<(), Error> {
987 {
988 use std::fmt::Write;
989 write!(self.0, "{v}").expect("writing to String cannot fail");
990 Ok(())
991 }
992 }
993 fn serialize_bool(self, v: bool) -> Result<(), Error> {
994 {
995 use std::fmt::Write;
996 write!(self.0, "{v}").expect("writing to String cannot fail");
997 Ok(())
998 }
999 }
1000 fn serialize_i8(self, v: i8) -> Result<(), Error> {
1001 {
1002 use std::fmt::Write;
1003 write!(self.0, "{v}").expect("writing to String cannot fail");
1004 Ok(())
1005 }
1006 }
1007 fn serialize_i16(self, v: i16) -> Result<(), Error> {
1008 {
1009 use std::fmt::Write;
1010 write!(self.0, "{v}").expect("writing to String cannot fail");
1011 Ok(())
1012 }
1013 }
1014 fn serialize_i32(self, v: i32) -> Result<(), Error> {
1015 {
1016 use std::fmt::Write;
1017 write!(self.0, "{v}").expect("writing to String cannot fail");
1018 Ok(())
1019 }
1020 }
1021 fn serialize_i64(self, v: i64) -> Result<(), Error> {
1022 {
1023 use std::fmt::Write;
1024 write!(self.0, "{v}").expect("writing to String cannot fail");
1025 Ok(())
1026 }
1027 }
1028 fn serialize_u8(self, v: u8) -> Result<(), Error> {
1029 {
1030 use std::fmt::Write;
1031 write!(self.0, "{v}").expect("writing to String cannot fail");
1032 Ok(())
1033 }
1034 }
1035 fn serialize_u16(self, v: u16) -> Result<(), Error> {
1036 {
1037 use std::fmt::Write;
1038 write!(self.0, "{v}").expect("writing to String cannot fail");
1039 Ok(())
1040 }
1041 }
1042 fn serialize_u32(self, v: u32) -> Result<(), Error> {
1043 {
1044 use std::fmt::Write;
1045 write!(self.0, "{v}").expect("writing to String cannot fail");
1046 Ok(())
1047 }
1048 }
1049 fn serialize_u64(self, v: u64) -> Result<(), Error> {
1050 {
1051 use std::fmt::Write;
1052 write!(self.0, "{v}").expect("writing to String cannot fail");
1053 Ok(())
1054 }
1055 }
1056 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<(), Error> {
1057 {
1058 self.0.push_str(variant);
1059 Ok(())
1060 }
1061 }
1062 fn serialize_newtype_struct<T: Serialize + ?Sized>(self, _name: &'static str, value: &T) -> Result<(), Error> {
1063 value.serialize(self)
1064 }
1065 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<(), Error> {
1066 value.serialize(self)
1067 }
1068 fn serialize_f32(self, _v: f32) -> Result<(), Error> {
1069 Err(Error("float map key".into()))
1070 }
1071 fn serialize_f64(self, _v: f64) -> Result<(), Error> {
1072 Err(Error("float map key".into()))
1073 }
1074 fn serialize_bytes(self, _v: &[u8]) -> Result<(), Error> {
1075 Err(Error("bytes map key".into()))
1076 }
1077 fn serialize_none(self) -> Result<(), Error> {
1078 Err(Error("null map key".into()))
1079 }
1080 fn serialize_unit(self) -> Result<(), Error> {
1081 Err(Error("unit map key".into()))
1082 }
1083 fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> {
1084 Err(Error("unit struct map key".into()))
1085 }
1086 fn serialize_newtype_variant<T: Serialize + ?Sized>(
1087 self,
1088 _name: &'static str,
1089 _idx: u32,
1090 _variant: &'static str,
1091 _value: &T,
1092 ) -> Result<(), Error> {
1093 Err(Error("newtype variant map key".into()))
1094 }
1095 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
1096 Err(Error("seq map key".into()))
1097 }
1098 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Error> {
1099 Err(Error("tuple map key".into()))
1100 }
1101 fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct, Error> {
1102 Err(Error("tuple struct map key".into()))
1103 }
1104 fn serialize_tuple_variant(
1105 self,
1106 _name: &'static str,
1107 _idx: u32,
1108 _variant: &'static str,
1109 _len: usize,
1110 ) -> Result<Self::SerializeTupleVariant, Error> {
1111 Err(Error("tuple variant map key".into()))
1112 }
1113 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
1114 Err(Error("map map key".into()))
1115 }
1116 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Error> {
1117 Err(Error("struct map key".into()))
1118 }
1119 fn serialize_struct_variant(
1120 self,
1121 _name: &'static str,
1122 _idx: u32,
1123 _variant: &'static str,
1124 _len: usize,
1125 ) -> Result<Self::SerializeStructVariant, Error> {
1126 Err(Error("struct variant map key".into()))
1127 }
1128}
1129
1130#[cfg(test)]
1131mod test {
1132 use super::*;
1133 use serde_json::json;
1134
1135 fn reference(old: &Value, new: &Value) -> Diff {
1138 fn objects(
1139 old: &Map<String, Value>,
1140 new: &Map<String, Value>,
1141 patch: &mut Map<String, Value>,
1142 forced: &mut bool,
1143 ) {
1144 for key in old.keys() {
1145 if !new.contains_key(key) {
1146 patch.insert(key.clone(), Value::Null);
1147 }
1148 }
1149 for (key, new_val) in new {
1150 let old_val = old.get(key);
1151 if old_val == Some(new_val) {
1152 continue;
1153 }
1154 if let (Some(Value::Object(old_obj)), Value::Object(new_obj)) = (old_val, new_val) {
1155 let mut sub = Map::new();
1156 objects(old_obj, new_obj, &mut sub, forced);
1157 if !sub.is_empty() {
1158 patch.insert(key.clone(), Value::Object(sub));
1159 }
1160 continue;
1161 }
1162 if new_val.is_null() {
1163 *forced = true;
1164 }
1165 patch.insert(key.clone(), new_val.clone());
1166 }
1167 }
1168
1169 if let (Value::Object(old_obj), Value::Object(new_obj)) = (old, new) {
1170 let mut patch = Map::new();
1171 let mut forced = false;
1172 objects(old_obj, new_obj, &mut patch, &mut forced);
1173 Diff {
1174 patch: Value::Object(patch),
1175 forced_snapshot: forced,
1176 }
1177 } else {
1178 Diff {
1179 patch: new.clone(),
1180 forced_snapshot: true,
1181 }
1182 }
1183 }
1184
1185 fn check(old: Value, new: Value) {
1188 let want = reference(&old, &new);
1189 let got = diff(&old, &new);
1190 assert_eq!(got.patch, want.patch, "patch mismatch for {old} -> {new}");
1191 assert_eq!(
1192 got.forced_snapshot, want.forced_snapshot,
1193 "forced mismatch for {old} -> {new}"
1194 );
1195 if !got.forced_snapshot {
1196 let mut applied = old.clone();
1197 json_patch::merge(&mut applied, &got.patch);
1198 assert_eq!(applied, new, "patch did not roundtrip for {old} -> {new}");
1199 }
1200 }
1201
1202 #[test]
1203 fn replacing_scalar_with_empty_object_is_a_change() {
1204 check(json!({ "value": 1 }), json!({ "value": {} }));
1205 check(json!({ "value": null }), json!({ "value": {} }));
1206 let result = diff(&json!(1), &json!({}));
1207 assert!(result.forced_snapshot);
1208 assert_eq!(result.patch, json!({}));
1209 }
1210
1211 #[test]
1212 fn duplicate_serialized_map_keys_force_a_snapshot() {
1213 struct Duplicate;
1214 impl Serialize for Duplicate {
1215 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1216 let mut map = serializer.serialize_map(Some(3))?;
1217 map.serialize_entry("key", &1)?;
1218 map.serialize_entry("other", &2)?;
1219 map.serialize_entry("key", &3)?;
1220 map.end()
1221 }
1222 }
1223 assert!(diff(&json!({ "key": 1, "other": 2 }), &Duplicate).forced_snapshot);
1224 }
1225
1226 #[test]
1227 fn emptying_a_map_removes_every_key() {
1228 check(json!({ "a": 1 }), json!({}));
1231 check(json!({ "a": 1, "b": 2 }), json!({}));
1232 check(json!({ "x": { "a": 1 } }), json!({ "x": {} }));
1233 }
1234
1235 #[test]
1236 fn changed_scalar() {
1237 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1, "b": 3 }));
1238 }
1239
1240 #[test]
1241 fn added_key() {
1242 let result = diff(&json!({ "a": 1 }), &json!({ "a": 1, "b": 2 }));
1243 assert!(!result.forced_snapshot);
1244 assert_eq!(result.patch, json!({ "b": 2 }));
1245 check(json!({ "a": 1 }), json!({ "a": 1, "b": 2 }));
1246 }
1247
1248 #[test]
1249 fn added_null_key_forces_snapshot() {
1250 check(json!({ "a": 1 }), json!({ "a": 1, "x": null }));
1251 check(
1252 json!({ "items": [{ "a": 1 }] }),
1253 json!({ "items": [{ "a": 1, "x": null }] }),
1254 );
1255 }
1256
1257 #[test]
1258 fn removed_key_is_null() {
1259 let result = diff(&json!({ "a": 1, "b": 2 }), &json!({ "a": 1 }));
1260 assert!(!result.forced_snapshot, "removing a key is a clean delete");
1261 assert_eq!(result.patch, json!({ "b": null }));
1262 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1 }));
1263 }
1264
1265 #[test]
1266 fn nested_object_only_includes_changed_keys() {
1267 let result = diff(&json!({ "o": { "x": 1, "y": 2 } }), &json!({ "o": { "x": 1, "y": 9 } }));
1268 assert!(!result.forced_snapshot);
1269 assert_eq!(result.patch, json!({ "o": { "y": 9 } }));
1270 check(json!({ "o": { "x": 1, "y": 2 } }), json!({ "o": { "x": 1, "y": 9 } }));
1271 }
1272
1273 #[test]
1274 fn unchanged_object_is_empty_patch() {
1275 let result = diff(&json!({ "a": 1, "o": { "x": 1 } }), &json!({ "a": 1, "o": { "x": 1 } }));
1276 assert!(!result.forced_snapshot);
1277 assert_eq!(result.patch, json!({}));
1278 }
1279
1280 #[test]
1281 fn changed_array_is_wholesale_delta() {
1282 let result = diff(&json!({ "a": [1, 2] }), &json!({ "a": [1, 2, 3] }));
1283 assert!(!result.forced_snapshot);
1284 assert_eq!(result.patch, json!({ "a": [1, 2, 3] }));
1285 check(json!({ "a": [1, 2] }), json!({ "a": [1, 2, 3] }));
1286 }
1287
1288 #[test]
1289 fn unchanged_array_is_pruned() {
1290 let result = diff(&json!({ "a": [1, 2, 3], "b": 1 }), &json!({ "a": [1, 2, 3], "b": 2 }));
1291 assert_eq!(
1292 result.patch,
1293 json!({ "b": 2 }),
1294 "an unchanged array stays out of the patch"
1295 );
1296 }
1297
1298 #[test]
1299 fn added_array_is_delta() {
1300 check(json!({ "a": 1 }), json!({ "a": 1, "b": [1] }));
1301 }
1302
1303 #[test]
1304 fn nested_array_is_delta() {
1305 check(json!({ "o": { "x": 1 } }), json!({ "o": { "x": 1, "list": [1] } }));
1306 }
1307
1308 #[test]
1309 fn array_of_objects_replaces_wholesale() {
1310 check(
1311 json!({ "items": [{ "id": 1, "v": 1 }, { "id": 2, "v": 2 }] }),
1312 json!({ "items": [{ "id": 1, "v": 9 }, { "id": 2, "v": 2 }] }),
1313 );
1314 }
1315
1316 #[test]
1317 fn set_to_null_forces_snapshot() {
1318 let result = diff(&json!({ "a": 1 }), &json!({ "a": null }));
1320 assert!(result.forced_snapshot);
1321 assert!(reference(&json!({ "a": 1 }), &json!({ "a": null })).forced_snapshot);
1322 }
1323
1324 #[test]
1325 fn nested_null_forces_snapshot() {
1326 let old = json!({ "o": { "x": 1 } });
1327 let new = json!({ "o": { "x": null } });
1328 assert!(diff(&old, &new).forced_snapshot);
1329 assert_eq!(diff(&old, &new).forced_snapshot, reference(&old, &new).forced_snapshot);
1330 }
1331
1332 #[test]
1333 fn replacing_object_with_scalar() {
1334 check(json!({ "a": { "x": 1 } }), json!({ "a": 5 }));
1335 }
1336
1337 #[test]
1338 fn replacing_scalar_with_object() {
1339 check(json!({ "a": 5 }), json!({ "a": { "x": 1 } }));
1340 }
1341
1342 #[test]
1343 fn non_object_root_forces_snapshot() {
1344 let result = diff(&json!(1), &json!(2));
1345 assert!(result.forced_snapshot);
1346 assert_eq!(result.patch, json!(2));
1347 }
1348
1349 #[test]
1350 fn array_root_forces_snapshot() {
1351 let result = diff(&json!([1, 2]), &json!([1, 2, 3]));
1352 assert!(result.forced_snapshot);
1353 assert_eq!(result.patch, json!([1, 2, 3]));
1354 }
1355
1356 #[test]
1357 fn unchanged_scalar_root_is_not_forced() {
1358 let result = diff(&json!(7), &json!(7));
1360 assert!(!result.forced_snapshot);
1361 assert_eq!(result.patch, json!({}));
1362 }
1363
1364 #[test]
1365 fn floats_and_bools_and_strings() {
1366 check(
1367 json!({ "f": 1.5, "b": true, "s": "hi" }),
1368 json!({ "f": 2.5, "b": false, "s": "bye" }),
1369 );
1370 }
1371
1372 #[derive(serde::Serialize, serde::Deserialize, Default, PartialEq, Debug)]
1375 struct Doc {
1376 #[serde(skip_serializing_if = "Option::is_none")]
1377 video: Option<String>,
1378 #[serde(skip_serializing_if = "Option::is_none")]
1379 scte35: Option<u32>,
1380 count: u64,
1381 tags: Vec<String>,
1382 }
1383
1384 fn check_struct(old: &Doc, new: &Doc) {
1386 let old_value = serde_json::to_value(old).unwrap();
1387 let result = diff(&old_value, new);
1388
1389 let new_value = serde_json::to_value(new).unwrap();
1391 let want = reference(&old_value, &new_value);
1392 assert_eq!(result.patch, want.patch, "struct patch differs from oracle");
1393 assert_eq!(result.forced_snapshot, want.forced_snapshot);
1394
1395 if !result.forced_snapshot {
1396 let mut applied = old_value;
1397 json_patch::merge(&mut applied, &result.patch);
1398 assert_eq!(applied, new_value, "struct patch did not roundtrip");
1399 }
1400 }
1401
1402 #[test]
1403 fn struct_field_change() {
1404 check_struct(
1405 &Doc {
1406 count: 1,
1407 tags: vec!["a".into()],
1408 ..Default::default()
1409 },
1410 &Doc {
1411 count: 2,
1412 tags: vec!["a".into()],
1413 ..Default::default()
1414 },
1415 );
1416 }
1417
1418 #[test]
1419 fn struct_option_some_to_none_is_deletion() {
1420 let result = diff(
1422 &serde_json::to_value(Doc {
1423 video: Some("v1".into()),
1424 count: 1,
1425 ..Default::default()
1426 })
1427 .unwrap(),
1428 &Doc {
1429 video: None,
1430 count: 1,
1431 ..Default::default()
1432 },
1433 );
1434 assert!(!result.forced_snapshot, "deleting a skipped key is clean");
1435 assert_eq!(result.patch, json!({ "video": null }));
1436 check_struct(
1437 &Doc {
1438 video: Some("v1".into()),
1439 count: 1,
1440 ..Default::default()
1441 },
1442 &Doc {
1443 video: None,
1444 count: 1,
1445 ..Default::default()
1446 },
1447 );
1448 }
1449
1450 #[test]
1451 fn struct_option_none_to_some_is_addition() {
1452 check_struct(
1453 &Doc {
1454 count: 1,
1455 ..Default::default()
1456 },
1457 &Doc {
1458 scte35: Some(42),
1459 count: 1,
1460 ..Default::default()
1461 },
1462 );
1463 }
1464
1465 #[test]
1466 fn struct_unchanged_is_empty_patch() {
1467 let doc = Doc {
1468 video: Some("v".into()),
1469 scte35: Some(1),
1470 count: 7,
1471 tags: vec!["x".into(), "y".into()],
1472 };
1473 let result = diff(&serde_json::to_value(&doc).unwrap(), &doc);
1474 assert!(!result.forced_snapshot);
1475 assert_eq!(result.patch, json!({}));
1476 }
1477
1478 #[test]
1479 fn struct_vec_changes_wholesale() {
1480 check_struct(
1481 &Doc {
1482 count: 1,
1483 tags: vec!["a".into(), "b".into()],
1484 ..Default::default()
1485 },
1486 &Doc {
1487 count: 1,
1488 tags: vec!["a".into(), "c".into()],
1489 ..Default::default()
1490 },
1491 );
1492 }
1493
1494 #[derive(serde::Serialize)]
1495 struct Nested {
1496 inner: Inner,
1497 name: String,
1498 }
1499 #[derive(serde::Serialize)]
1500 struct Inner {
1501 a: u32,
1502 b: u32,
1503 }
1504
1505 #[test]
1506 fn nested_struct_only_changed_field() {
1507 let old = serde_json::to_value(Nested {
1508 inner: Inner { a: 1, b: 2 },
1509 name: "n".into(),
1510 })
1511 .unwrap();
1512 let new = Nested {
1513 inner: Inner { a: 1, b: 9 },
1514 name: "n".into(),
1515 };
1516 let result = diff(&old, &new);
1517 assert_eq!(result.patch, json!({ "inner": { "b": 9 } }));
1518 assert!(!result.forced_snapshot);
1519 }
1520
1521 #[derive(serde::Serialize)]
1522 enum Tag {
1523 Active,
1524 Idle,
1525 }
1526
1527 #[derive(serde::Serialize)]
1528 struct Stated {
1529 state: Tag,
1530 seq: u32,
1531 }
1532
1533 #[test]
1534 fn unit_enum_variant_is_string() {
1535 let old = serde_json::to_value(Stated {
1537 state: Tag::Active,
1538 seq: 1,
1539 })
1540 .unwrap();
1541 assert_eq!(old, json!({ "state": "Active", "seq": 1 }));
1542 let result = diff(
1543 &old,
1544 &Stated {
1545 state: Tag::Idle,
1546 seq: 1,
1547 },
1548 );
1549 assert!(!result.forced_snapshot);
1550 assert_eq!(result.patch, json!({ "state": "Idle" }));
1551 }
1552
1553 fn check_typed<T: Serialize>(old: &Value, new: &T) {
1556 let new_value = serde_json::to_value(new).unwrap();
1557 let want = reference(old, &new_value);
1558 let got = diff(old, new);
1559 assert_eq!(got.patch, want.patch, "patch differs from oracle");
1560 assert_eq!(got.forced_snapshot, want.forced_snapshot, "forced differs from oracle");
1561 if !got.forced_snapshot {
1562 let mut applied = old.clone();
1563 json_patch::merge(&mut applied, &got.patch);
1564 assert_eq!(applied, new_value, "patch did not roundtrip");
1565 }
1566 }
1567
1568 #[derive(serde::Serialize)]
1569 enum Payload {
1570 Newtype(u32),
1571 Tuple(u32, String),
1572 Struct { x: u32, y: u32 },
1573 }
1574
1575 #[derive(serde::Serialize)]
1576 struct Holder {
1577 payload: Payload,
1578 seq: u32,
1579 }
1580
1581 #[test]
1582 fn newtype_variant_keeps_its_tag() {
1583 let old = serde_json::to_value(Holder {
1585 payload: Payload::Newtype(1),
1586 seq: 0,
1587 })
1588 .unwrap();
1589 assert_eq!(old, json!({ "payload": { "Newtype": 1 }, "seq": 0 }));
1590 let result = diff(
1591 &old,
1592 &Holder {
1593 payload: Payload::Newtype(2),
1594 seq: 0,
1595 },
1596 );
1597 assert_eq!(result.patch, json!({ "payload": { "Newtype": 2 } }));
1598 check_typed(
1599 &old,
1600 &Holder {
1601 payload: Payload::Newtype(2),
1602 seq: 0,
1603 },
1604 );
1605 }
1606
1607 #[test]
1608 fn tuple_variant_keeps_its_tag() {
1609 let old = serde_json::to_value(Holder {
1610 payload: Payload::Tuple(1, "a".into()),
1611 seq: 0,
1612 })
1613 .unwrap();
1614 assert_eq!(old, json!({ "payload": { "Tuple": [1, "a"] }, "seq": 0 }));
1615 check_typed(
1616 &old,
1617 &Holder {
1618 payload: Payload::Tuple(2, "a".into()),
1619 seq: 0,
1620 },
1621 );
1622 }
1623
1624 #[test]
1625 fn struct_variant_keeps_its_tag() {
1626 let old = serde_json::to_value(Holder {
1627 payload: Payload::Struct { x: 1, y: 2 },
1628 seq: 0,
1629 })
1630 .unwrap();
1631 assert_eq!(old, json!({ "payload": { "Struct": { "x": 1, "y": 2 } }, "seq": 0 }));
1632 check_typed(
1633 &old,
1634 &Holder {
1635 payload: Payload::Struct { x: 1, y: 9 },
1636 seq: 0,
1637 },
1638 );
1639 }
1640
1641 #[derive(serde::Deserialize)]
1642 struct Vector {
1643 name: String,
1644 old: Value,
1645 new: Value,
1646 forced: bool,
1647 patch: Option<Value>,
1648 }
1649
1650 #[test]
1653 fn golden_vectors() {
1654 let vectors: Vec<Vector> = serde_json::from_str(include_str!("../tests/vectors.json")).unwrap();
1655 for case in vectors {
1656 let result = diff(&case.old, &case.new);
1657 assert_eq!(result.forced_snapshot, case.forced, "{}: forced_snapshot", case.name);
1658
1659 if let Some(expected) = case.patch {
1660 assert_eq!(result.patch, expected, "{}: patch", case.name);
1661 let mut applied = case.old.clone();
1662 json_patch::merge(&mut applied, &result.patch);
1663 assert_eq!(applied, case.new, "{}: roundtrip", case.name);
1664 }
1665 }
1666 }
1667
1668 #[test]
1671 fn evolving_document_matches_oracle() {
1672 let mut docs = Vec::new();
1673 for tick in 0u64..40 {
1674 docs.push(json!({
1675 "id": "device-1",
1676 "static": { "model": "x", "tags": ["a", "b", "c"] },
1677 "counters": { "n": tick, "errors": tick / 10 },
1678 "reading": (tick as f64 * 0.5),
1679 "flags": { "online": tick % 2 == 0, "charging": tick % 3 == 0 },
1680 "list": [tick, tick + 1],
1681 }));
1682 }
1683 for pair in docs.windows(2) {
1684 check(pair[0].clone(), pair[1].clone());
1685 }
1686 }
1687}