1use std::cell::{Cell, RefCell};
10
11use serde::Serialize;
12use serde::ser::{Impossible, SerializeMap, SerializeSeq, SerializeStruct, Serializer};
13use serde_json::{Map, Value};
14
15pub struct Diff {
17 pub patch: Value,
19
20 pub forced_snapshot: bool,
25}
26
27pub fn diff<T: Serialize>(old: &Value, new: &T) -> Diff {
32 let result = bytes(old, new, &RefCell::new(Scratch::default())).unwrap_or(PatchBytes {
33 patch: Vec::new(),
34 forced_snapshot: true,
35 });
36 Diff {
37 patch: if result.patch.is_empty() {
38 Value::Object(Map::new())
39 } else {
40 serde_json::from_slice(&result.patch).expect("the diff serializer emits JSON")
41 },
42 forced_snapshot: result.forced_snapshot,
43 }
44}
45
46#[derive(Default)]
47pub(crate) struct Scratch {
48 seen: Vec<Vec<String>>,
49 pending: Vec<String>,
50 bytes: Vec<Vec<u8>>,
51 last_capacity: usize,
52}
53
54impl Scratch {
55 fn buffer(&mut self, depth: usize) -> &mut Vec<u8> {
56 if self.bytes.len() <= depth {
57 self.bytes.resize_with(depth + 1, Vec::new);
58 }
59 &mut self.bytes[depth]
60 }
61}
62
63pub(crate) struct PatchBytes {
64 pub patch: Vec<u8>,
65 pub forced_snapshot: bool,
66}
67
68pub(crate) fn bytes<T: Serialize>(old: &Value, new: &T, scratch: &RefCell<Scratch>) -> Result<PatchBytes, String> {
70 let forced = Cell::new(false);
71 let node = new.serialize(Differ {
72 baseline: old,
73 present: true,
74 forced: &forced,
75 scratch,
76 depth: 0,
77 });
78 match node {
79 Ok(Node::Same) => Ok(PatchBytes {
80 patch: Vec::new(),
81 forced_snapshot: forced.get(),
82 }),
83 Ok(Node::Diff) => {
84 let mut scratch = scratch.borrow_mut();
85 let patch = std::mem::take(scratch.buffer(0));
86 scratch.last_capacity = patch.capacity();
87 let forced_snapshot = forced.get() || !patch.starts_with(b"{") || !old.is_object();
88 Ok(PatchBytes { patch, forced_snapshot })
89 }
90 Err(err) => Err(err.0),
91 }
92}
93
94enum Node {
96 Same,
98 Diff,
100}
101
102const NULL: Value = Value::Null;
103
104#[derive(Copy, Clone)]
107struct Differ<'a> {
108 baseline: &'a Value,
109 present: bool,
110 forced: &'a Cell<bool>,
111 scratch: &'a RefCell<Scratch>,
112 depth: usize,
113}
114
115impl<'a> Differ<'a> {
116 fn child(&self, key: &str) -> (Differ<'a>, bool) {
119 let (baseline, existed) = match self.baseline {
120 Value::Object(m) => match m.get(key) {
121 Some(value) => (value, true),
122 None => (&NULL, false),
123 },
124 _ => (&NULL, false),
125 };
126 (
127 Differ {
128 baseline,
129 present: existed,
130 forced: self.forced,
131 scratch: self.scratch,
132 depth: self.depth + 1,
133 },
134 existed,
135 )
136 }
137
138 fn scalar<T: Serialize + ?Sized>(self, value: &T, equal: bool, null: bool) -> Result<Node, Error> {
140 if equal {
141 return Ok(Node::Same);
142 }
143 if null {
144 self.forced.set(true);
145 }
146 let mut scratch = self.scratch.borrow_mut();
147 let capacity = scratch.last_capacity;
148 let bytes = scratch.buffer(self.depth);
149 bytes.clear();
150 if self.depth == 0 {
151 bytes.reserve(capacity);
152 }
153 serde_json::to_writer(bytes, value).map_err(|err| Error(err.to_string()))?;
154 Ok(Node::Diff)
155 }
156}
157
158#[derive(Debug)]
160struct Error(String);
161
162impl std::fmt::Display for Error {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 f.write_str(&self.0)
165 }
166}
167
168impl std::error::Error for Error {}
169
170impl serde::ser::Error for Error {
171 fn custom<M: std::fmt::Display>(msg: M) -> Self {
172 Error(msg.to_string())
173 }
174}
175
176fn to_plain<T: Serialize + ?Sized>(value: &T) -> Result<Value, Error> {
178 serde_json::to_value(value).map_err(|e| Error(e.to_string()))
179}
180
181impl<'a> Serializer for Differ<'a> {
182 type Ok = Node;
183 type Error = Error;
184 type SerializeSeq = SeqDiff<'a>;
185 type SerializeTuple = SeqDiff<'a>;
186 type SerializeTupleStruct = SeqDiff<'a>;
187 type SerializeTupleVariant = VariantSeq<'a>;
188 type SerializeMap = MapDiff<'a>;
189 type SerializeStruct = MapDiff<'a>;
190 type SerializeStructVariant = VariantMap<'a>;
191
192 fn serialize_bool(self, v: bool) -> Result<Node, Error> {
193 self.scalar(&v, self.baseline == &Value::Bool(v), false)
194 }
195 fn serialize_i8(self, v: i8) -> Result<Node, Error> {
196 self.scalar(&v, self.baseline == &Value::from(v), false)
197 }
198 fn serialize_i16(self, v: i16) -> Result<Node, Error> {
199 self.scalar(&v, self.baseline == &Value::from(v), false)
200 }
201 fn serialize_i32(self, v: i32) -> Result<Node, Error> {
202 self.scalar(&v, self.baseline == &Value::from(v), false)
203 }
204 fn serialize_i64(self, v: i64) -> Result<Node, Error> {
205 self.scalar(&v, self.baseline == &Value::from(v), false)
206 }
207 fn serialize_i128(self, v: i128) -> Result<Node, Error> {
208 {
209 let plain = to_plain(&v)?;
210 self.scalar(&plain, self.baseline == &plain, false)
211 }
212 }
213 fn serialize_u8(self, v: u8) -> Result<Node, Error> {
214 self.scalar(&v, self.baseline == &Value::from(v), false)
215 }
216 fn serialize_u16(self, v: u16) -> Result<Node, Error> {
217 self.scalar(&v, self.baseline == &Value::from(v), false)
218 }
219 fn serialize_u32(self, v: u32) -> Result<Node, Error> {
220 self.scalar(&v, self.baseline == &Value::from(v), false)
221 }
222 fn serialize_u64(self, v: u64) -> Result<Node, Error> {
223 self.scalar(&v, self.baseline == &Value::from(v), false)
224 }
225 fn serialize_u128(self, v: u128) -> Result<Node, Error> {
226 {
227 let plain = to_plain(&v)?;
228 self.scalar(&plain, self.baseline == &plain, false)
229 }
230 }
231 fn serialize_f32(self, v: f32) -> Result<Node, Error> {
232 self.scalar(&v, self.baseline == &Value::from(v), false)
233 }
234 fn serialize_f64(self, v: f64) -> Result<Node, Error> {
235 self.scalar(&v, self.baseline == &Value::from(v), false)
236 }
237 fn serialize_char(self, v: char) -> Result<Node, Error> {
238 let mut utf8 = [0; 4];
239 self.scalar(&v, self.baseline.as_str() == Some(v.encode_utf8(&mut utf8)), false)
240 }
241 fn serialize_str(self, v: &str) -> Result<Node, Error> {
242 if matches!(self.baseline, Value::String(b) if b == v) {
245 Ok(Node::Same)
246 } else {
247 self.scalar(&v, false, false)
248 }
249 }
250 fn serialize_bytes(self, v: &[u8]) -> Result<Node, Error> {
251 let mut seq = self.serialize_seq(Some(v.len()))?;
252 for byte in v {
253 SerializeSeq::serialize_element(&mut seq, byte)?;
254 }
255 SerializeSeq::end(seq)
256 }
257 fn serialize_none(self) -> Result<Node, Error> {
258 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
259 }
260 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Node, Error> {
261 value.serialize(self)
262 }
263 fn serialize_unit(self) -> Result<Node, Error> {
264 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
265 }
266 fn serialize_unit_struct(self, _name: &'static str) -> Result<Node, Error> {
267 self.scalar(&Value::Null, self.present && self.baseline.is_null(), true)
268 }
269 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<Node, Error> {
270 self.scalar(&variant, self.baseline.as_str() == Some(variant), false)
271 }
272 fn serialize_newtype_struct<T: Serialize + ?Sized>(self, _name: &'static str, value: &T) -> Result<Node, Error> {
273 value.serialize(self)
274 }
275 fn serialize_newtype_variant<T: Serialize + ?Sized>(
276 self,
277 _name: &'static str,
278 _idx: u32,
279 variant: &'static str,
280 value: &T,
281 ) -> Result<Node, Error> {
282 Variant { name: variant, value }.serialize(self)
286 }
287 fn serialize_seq(self, len: Option<usize>) -> Result<SeqDiff<'a>, Error> {
288 let _ = len;
289 self.scratch.borrow_mut().buffer(self.depth).clear();
290 Ok(SeqDiff {
291 differ: self,
292 changed: false,
293 len: 0,
294 })
295 }
296 fn serialize_tuple(self, len: usize) -> Result<SeqDiff<'a>, Error> {
297 self.serialize_seq(Some(len))
298 }
299 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqDiff<'a>, Error> {
300 self.serialize_seq(Some(len))
301 }
302 fn serialize_tuple_variant(
303 self,
304 _name: &'static str,
305 _idx: u32,
306 variant: &'static str,
307 len: usize,
308 ) -> Result<VariantSeq<'a>, Error> {
309 Ok(VariantSeq {
311 differ: self,
312 variant,
313 items: self.child(variant).0.serialize_seq(Some(len))?,
314 })
315 }
316 fn serialize_map(self, _len: Option<usize>) -> Result<MapDiff<'a>, Error> {
317 self.scratch.borrow_mut().buffer(self.depth).clear();
318 Ok(MapDiff {
319 differ: self,
320 entries: 0,
321 seen_len: 0,
322 ordered: true,
323 added_key: false,
324 })
325 }
326 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapDiff<'a>, Error> {
327 self.serialize_map(Some(len))
328 }
329 fn serialize_struct_variant(
330 self,
331 _name: &'static str,
332 _idx: u32,
333 variant: &'static str,
334 _len: usize,
335 ) -> Result<VariantMap<'a>, Error> {
336 Ok(VariantMap {
338 differ: self,
339 variant,
340 fields: self.child(variant).0.serialize_map(Some(_len))?,
341 })
342 }
343}
344
345struct Variant<'a, T: ?Sized> {
347 name: &'static str,
348 value: &'a T,
349}
350
351impl<T: Serialize + ?Sized> Serialize for Variant<'_, T> {
352 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
353 let mut map = serializer.serialize_map(Some(1))?;
354 map.serialize_entry(self.name, self.value)?;
355 map.end()
356 }
357}
358
359fn finish_variant(differ: Differ<'_>, variant: &'static str, node: Node) -> Result<Node, Error> {
361 let (_, existed) = differ.child(variant);
362 let mut outer = differ.serialize_map(Some(1))?;
363 outer.entry(variant, existed, node)?;
364 SerializeMap::end(outer)
365}
366
367struct VariantSeq<'a> {
368 differ: Differ<'a>,
369 variant: &'static str,
370 items: SeqDiff<'a>,
371}
372
373impl serde::ser::SerializeTupleVariant for VariantSeq<'_> {
374 type Ok = Node;
375 type Error = Error;
376 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
377 SerializeSeq::serialize_element(&mut self.items, value)
378 }
379 fn end(self) -> Result<Node, Error> {
380 finish_variant(self.differ, self.variant, SerializeSeq::end(self.items)?)
381 }
382}
383
384struct VariantMap<'a> {
385 differ: Differ<'a>,
386 variant: &'static str,
387 fields: MapDiff<'a>,
388}
389
390impl serde::ser::SerializeStructVariant for VariantMap<'_> {
391 type Ok = Node;
392 type Error = Error;
393 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
394 SerializeStruct::serialize_field(&mut self.fields, key, value)
395 }
396 fn end(self) -> Result<Node, Error> {
397 finish_variant(self.differ, self.variant, SerializeStruct::end(self.fields)?)
398 }
399}
400
401struct SeqDiff<'a> {
403 differ: Differ<'a>,
404 changed: bool,
405 len: usize,
406}
407
408impl SeqDiff<'_> {
409 fn begin(&mut self, old: &[Value]) -> Result<(), Error> {
410 let mut scratch = self.differ.scratch.borrow_mut();
411 let capacity = scratch.last_capacity;
412 let bytes = scratch.buffer(self.differ.depth);
413 bytes.clear();
414 if self.differ.depth == 0 {
415 bytes.reserve(capacity);
416 }
417 bytes.push(b'[');
418 for item in &old[..self.len] {
419 if bytes.len() > 1 {
420 bytes.push(b',');
421 }
422 serde_json::to_writer(&mut *bytes, item).map_err(|err| Error(err.to_string()))?;
423 }
424 self.changed = true;
425 Ok(())
426 }
427}
428
429impl SerializeSeq for SeqDiff<'_> {
430 type Ok = Node;
431 type Error = Error;
432 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
433 let old = self.differ.baseline.as_array();
434 if !self.changed {
435 let baseline = old.and_then(|old| old.get(self.len)).unwrap_or(&NULL);
436 let forced = Cell::new(false);
438 let equal = matches!(
439 value.serialize(Differ {
440 baseline,
441 present: true,
442 forced: &forced,
443 scratch: self.differ.scratch,
444 depth: self.differ.depth + 1,
445 })?,
446 Node::Same
447 ) && old.is_some_and(|old| self.len < old.len());
448 if !equal {
449 self.begin(old.map(Vec::as_slice).unwrap_or(&[]))?;
450 }
451 }
452 if self.changed {
453 let mut scratch = self.differ.scratch.borrow_mut();
454 let bytes = scratch.buffer(self.differ.depth);
455 if bytes.len() > 1 {
456 bytes.push(b',');
457 }
458 serde_json::to_writer(bytes, value).map_err(|err| Error(err.to_string()))?;
459 }
460 self.len += 1;
461 Ok(())
462 }
463 fn end(mut self) -> Result<Node, Error> {
464 if !self.changed {
465 if let Some(old) = self.differ.baseline.as_array() {
466 if self.len == old.len() {
467 return Ok(Node::Same);
468 }
469 self.begin(old)?;
470 } else {
471 self.begin(&[])?;
472 }
473 }
474 self.differ.scratch.borrow_mut().buffer(self.differ.depth).push(b']');
475 Ok(Node::Diff)
476 }
477}
478
479impl serde::ser::SerializeTuple for SeqDiff<'_> {
480 type Ok = Node;
481 type Error = Error;
482 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
483 SerializeSeq::serialize_element(self, value)
484 }
485 fn end(self) -> Result<Node, Error> {
486 SerializeSeq::end(self)
487 }
488}
489
490impl serde::ser::SerializeTupleStruct for SeqDiff<'_> {
491 type Ok = Node;
492 type Error = Error;
493 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
494 SerializeSeq::serialize_element(self, value)
495 }
496 fn end(self) -> Result<Node, Error> {
497 SerializeSeq::end(self)
498 }
499}
500
501struct MapDiff<'a> {
503 differ: Differ<'a>,
504 entries: usize,
505 seen_len: usize,
506 ordered: bool,
507 added_key: bool,
508}
509
510impl MapDiff<'_> {
511 fn write_entry(&mut self, key: &str, child: Option<usize>) -> Result<(), Error> {
512 let depth = self.differ.depth;
513 let mut scratch = self.differ.scratch.borrow_mut();
514 let capacity = scratch.last_capacity;
515 let bytes = scratch.buffer(depth);
516 if self.entries == 0 {
517 if depth == 0 {
518 bytes.reserve(capacity);
519 }
520 bytes.push(b'{');
521 } else {
522 bytes.push(b',');
523 }
524 serde_json::to_writer(&mut *bytes, key).map_err(|err| Error(err.to_string()))?;
525 bytes.push(b':');
526 if let Some(child) = child {
527 let (parents, children) = scratch.bytes.split_at_mut(child);
528 parents[depth].extend_from_slice(&children[0]);
529 } else {
530 scratch.bytes[depth].extend_from_slice(b"null");
531 }
532 self.entries += 1;
533 Ok(())
534 }
535
536 fn entry(&mut self, key: &str, existed: bool, node: Node) -> Result<(), Error> {
537 self.added_key |= !existed;
538 if let Node::Diff = node {
539 self.write_entry(key, Some(self.differ.depth + 1))?;
540 }
541 let mut scratch = self.differ.scratch.borrow_mut();
542 if scratch.seen.len() <= self.differ.depth {
543 scratch.seen.resize_with(self.differ.depth + 1, Vec::new);
544 }
545 let seen = &mut scratch.seen[self.differ.depth];
546 if self.seen_len > 0 {
547 match seen[self.seen_len - 1].as_str().cmp(key) {
548 std::cmp::Ordering::Equal => return Err(Error("duplicate JSON object key".into())),
549 std::cmp::Ordering::Greater => self.ordered = false,
550 std::cmp::Ordering::Less => {}
551 }
552 }
553 if self.seen_len == seen.len() {
554 seen.push(key.to_owned());
555 } else {
556 seen[self.seen_len].clear();
557 seen[self.seen_len].push_str(key);
558 }
559 self.seen_len += 1;
560 Ok(())
561 }
562
563 fn finish(mut self) -> Result<Node, Error> {
564 if !self.ordered {
565 let mut scratch = self.differ.scratch.borrow_mut();
566 let seen = &mut scratch.seen[self.differ.depth][..self.seen_len];
567 seen.sort_unstable();
568 if seen.windows(2).any(|pair| pair[0] == pair[1]) {
569 return Err(Error("duplicate JSON object key".into()));
570 }
571 }
572 if let Value::Object(base) = self.differ.baseline
573 && (self.added_key || self.seen_len != base.len())
574 {
575 let depth = self.differ.depth;
576 let mut scratch = self.differ.scratch.borrow_mut();
577 let Scratch {
578 seen,
579 bytes,
580 last_capacity,
581 ..
582 } = &mut *scratch;
583 let seen: &mut [String] = match seen.get_mut(depth) {
585 Some(seen) => &mut seen[..self.seen_len],
586 None => &mut [],
587 };
588 let out = &mut bytes[depth];
589 if self.ordered {
590 seen.sort_unstable();
591 }
592 for key in base.keys() {
593 if seen.binary_search_by(|seen| seen.as_str().cmp(key)).is_err() {
594 if self.entries == 0 {
595 if depth == 0 {
596 out.reserve(*last_capacity);
597 }
598 out.push(b'{');
599 } else {
600 out.push(b',');
601 }
602 serde_json::to_writer(&mut *out, key).map_err(|err| Error(err.to_string()))?;
603 out.extend_from_slice(b":null");
604 self.entries += 1;
605 }
606 }
607 }
608 if self.entries == 0 {
609 if self.differ.baseline.is_object() {
610 return Ok(Node::Same);
611 }
612 self.differ
613 .scratch
614 .borrow_mut()
615 .buffer(self.differ.depth)
616 .extend_from_slice(b"{}");
617 return Ok(Node::Diff);
618 }
619 self.differ.scratch.borrow_mut().buffer(self.differ.depth).push(b'}');
620 Ok(Node::Diff)
621 }
622}
623
624impl SerializeMap for MapDiff<'_> {
625 type Ok = Node;
626 type Error = Error;
627 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Error> {
628 let mut scratch = self.differ.scratch.borrow_mut();
629 if scratch.pending.len() <= self.differ.depth {
630 scratch.pending.resize_with(self.differ.depth + 1, String::new);
631 }
632 let pending = &mut scratch.pending[self.differ.depth];
633 pending.clear();
634 key.serialize(KeySer(pending))
635 }
636 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
637 let depth = self.differ.depth;
638 let key = std::mem::take(&mut self.differ.scratch.borrow_mut().pending[depth]);
639 let (child, existed) = self.differ.child(&key);
640 let node = value.serialize(child)?;
641 self.entry(&key, existed, node)?;
642 self.differ.scratch.borrow_mut().pending[depth] = key;
643 Ok(())
644 }
645 fn end(self) -> Result<Node, Error> {
646 self.finish()
647 }
648}
649
650impl SerializeStruct for MapDiff<'_> {
651 type Ok = Node;
652 type Error = Error;
653 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
654 let (child, existed) = self.differ.child(key);
655 let node = value.serialize(child)?;
656 self.entry(key, existed, node)?;
657 Ok(())
658 }
659 fn end(self) -> Result<Node, Error> {
662 self.finish()
663 }
664}
665
666struct KeySer<'a>(&'a mut String);
669
670impl Serializer for KeySer<'_> {
671 type Ok = ();
672 type Error = Error;
673 type SerializeSeq = Impossible<(), Error>;
674 type SerializeTuple = Impossible<(), Error>;
675 type SerializeTupleStruct = Impossible<(), Error>;
676 type SerializeTupleVariant = Impossible<(), Error>;
677 type SerializeMap = Impossible<(), Error>;
678 type SerializeStruct = Impossible<(), Error>;
679 type SerializeStructVariant = Impossible<(), Error>;
680
681 fn serialize_str(self, v: &str) -> Result<(), Error> {
682 {
683 self.0.push_str(v);
684 Ok(())
685 }
686 }
687 fn serialize_char(self, v: char) -> Result<(), Error> {
688 {
689 use std::fmt::Write;
690 write!(self.0, "{v}").expect("writing to String cannot fail");
691 Ok(())
692 }
693 }
694 fn serialize_bool(self, v: bool) -> Result<(), Error> {
695 {
696 use std::fmt::Write;
697 write!(self.0, "{v}").expect("writing to String cannot fail");
698 Ok(())
699 }
700 }
701 fn serialize_i8(self, v: i8) -> Result<(), Error> {
702 {
703 use std::fmt::Write;
704 write!(self.0, "{v}").expect("writing to String cannot fail");
705 Ok(())
706 }
707 }
708 fn serialize_i16(self, v: i16) -> Result<(), Error> {
709 {
710 use std::fmt::Write;
711 write!(self.0, "{v}").expect("writing to String cannot fail");
712 Ok(())
713 }
714 }
715 fn serialize_i32(self, v: i32) -> Result<(), Error> {
716 {
717 use std::fmt::Write;
718 write!(self.0, "{v}").expect("writing to String cannot fail");
719 Ok(())
720 }
721 }
722 fn serialize_i64(self, v: i64) -> Result<(), Error> {
723 {
724 use std::fmt::Write;
725 write!(self.0, "{v}").expect("writing to String cannot fail");
726 Ok(())
727 }
728 }
729 fn serialize_u8(self, v: u8) -> Result<(), Error> {
730 {
731 use std::fmt::Write;
732 write!(self.0, "{v}").expect("writing to String cannot fail");
733 Ok(())
734 }
735 }
736 fn serialize_u16(self, v: u16) -> Result<(), Error> {
737 {
738 use std::fmt::Write;
739 write!(self.0, "{v}").expect("writing to String cannot fail");
740 Ok(())
741 }
742 }
743 fn serialize_u32(self, v: u32) -> Result<(), Error> {
744 {
745 use std::fmt::Write;
746 write!(self.0, "{v}").expect("writing to String cannot fail");
747 Ok(())
748 }
749 }
750 fn serialize_u64(self, v: u64) -> Result<(), Error> {
751 {
752 use std::fmt::Write;
753 write!(self.0, "{v}").expect("writing to String cannot fail");
754 Ok(())
755 }
756 }
757 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<(), Error> {
758 {
759 self.0.push_str(variant);
760 Ok(())
761 }
762 }
763 fn serialize_newtype_struct<T: Serialize + ?Sized>(self, _name: &'static str, value: &T) -> Result<(), Error> {
764 value.serialize(self)
765 }
766 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<(), Error> {
767 value.serialize(self)
768 }
769 fn serialize_f32(self, _v: f32) -> Result<(), Error> {
770 Err(Error("float map key".into()))
771 }
772 fn serialize_f64(self, _v: f64) -> Result<(), Error> {
773 Err(Error("float map key".into()))
774 }
775 fn serialize_bytes(self, _v: &[u8]) -> Result<(), Error> {
776 Err(Error("bytes map key".into()))
777 }
778 fn serialize_none(self) -> Result<(), Error> {
779 Err(Error("null map key".into()))
780 }
781 fn serialize_unit(self) -> Result<(), Error> {
782 Err(Error("unit map key".into()))
783 }
784 fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> {
785 Err(Error("unit struct map key".into()))
786 }
787 fn serialize_newtype_variant<T: Serialize + ?Sized>(
788 self,
789 _name: &'static str,
790 _idx: u32,
791 _variant: &'static str,
792 _value: &T,
793 ) -> Result<(), Error> {
794 Err(Error("newtype variant map key".into()))
795 }
796 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
797 Err(Error("seq map key".into()))
798 }
799 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Error> {
800 Err(Error("tuple map key".into()))
801 }
802 fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct, Error> {
803 Err(Error("tuple struct map key".into()))
804 }
805 fn serialize_tuple_variant(
806 self,
807 _name: &'static str,
808 _idx: u32,
809 _variant: &'static str,
810 _len: usize,
811 ) -> Result<Self::SerializeTupleVariant, Error> {
812 Err(Error("tuple variant map key".into()))
813 }
814 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
815 Err(Error("map map key".into()))
816 }
817 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Error> {
818 Err(Error("struct map key".into()))
819 }
820 fn serialize_struct_variant(
821 self,
822 _name: &'static str,
823 _idx: u32,
824 _variant: &'static str,
825 _len: usize,
826 ) -> Result<Self::SerializeStructVariant, Error> {
827 Err(Error("struct variant map key".into()))
828 }
829}
830
831#[cfg(test)]
832mod test {
833 use super::*;
834 use serde_json::json;
835
836 fn reference(old: &Value, new: &Value) -> Diff {
839 fn objects(
840 old: &Map<String, Value>,
841 new: &Map<String, Value>,
842 patch: &mut Map<String, Value>,
843 forced: &mut bool,
844 ) {
845 for key in old.keys() {
846 if !new.contains_key(key) {
847 patch.insert(key.clone(), Value::Null);
848 }
849 }
850 for (key, new_val) in new {
851 let old_val = old.get(key);
852 if old_val == Some(new_val) {
853 continue;
854 }
855 if let (Some(Value::Object(old_obj)), Value::Object(new_obj)) = (old_val, new_val) {
856 let mut sub = Map::new();
857 objects(old_obj, new_obj, &mut sub, forced);
858 if !sub.is_empty() {
859 patch.insert(key.clone(), Value::Object(sub));
860 }
861 continue;
862 }
863 if new_val.is_null() {
864 *forced = true;
865 }
866 patch.insert(key.clone(), new_val.clone());
867 }
868 }
869
870 if let (Value::Object(old_obj), Value::Object(new_obj)) = (old, new) {
871 let mut patch = Map::new();
872 let mut forced = false;
873 objects(old_obj, new_obj, &mut patch, &mut forced);
874 Diff {
875 patch: Value::Object(patch),
876 forced_snapshot: forced,
877 }
878 } else {
879 Diff {
880 patch: new.clone(),
881 forced_snapshot: true,
882 }
883 }
884 }
885
886 fn check(old: Value, new: Value) {
889 let want = reference(&old, &new);
890 let got = diff(&old, &new);
891 assert_eq!(got.patch, want.patch, "patch mismatch for {old} -> {new}");
892 assert_eq!(
893 got.forced_snapshot, want.forced_snapshot,
894 "forced mismatch for {old} -> {new}"
895 );
896 if !got.forced_snapshot {
897 let mut applied = old.clone();
898 json_patch::merge(&mut applied, &got.patch);
899 assert_eq!(applied, new, "patch did not roundtrip for {old} -> {new}");
900 }
901 }
902
903 #[test]
904 fn replacing_scalar_with_empty_object_is_a_change() {
905 check(json!({ "value": 1 }), json!({ "value": {} }));
906 check(json!({ "value": null }), json!({ "value": {} }));
907 let result = diff(&json!(1), &json!({}));
908 assert!(result.forced_snapshot);
909 assert_eq!(result.patch, json!({}));
910 }
911
912 #[test]
913 fn duplicate_serialized_map_keys_force_a_snapshot() {
914 struct Duplicate;
915 impl Serialize for Duplicate {
916 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
917 let mut map = serializer.serialize_map(Some(3))?;
918 map.serialize_entry("key", &1)?;
919 map.serialize_entry("other", &2)?;
920 map.serialize_entry("key", &3)?;
921 map.end()
922 }
923 }
924 assert!(diff(&json!({ "key": 1, "other": 2 }), &Duplicate).forced_snapshot);
925 }
926
927 #[test]
928 fn emptying_a_map_removes_every_key() {
929 check(json!({ "a": 1 }), json!({}));
932 check(json!({ "a": 1, "b": 2 }), json!({}));
933 check(json!({ "x": { "a": 1 } }), json!({ "x": {} }));
934 }
935
936 #[test]
937 fn changed_scalar() {
938 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1, "b": 3 }));
939 }
940
941 #[test]
942 fn added_key() {
943 let result = diff(&json!({ "a": 1 }), &json!({ "a": 1, "b": 2 }));
944 assert!(!result.forced_snapshot);
945 assert_eq!(result.patch, json!({ "b": 2 }));
946 check(json!({ "a": 1 }), json!({ "a": 1, "b": 2 }));
947 }
948
949 #[test]
950 fn added_null_key_forces_snapshot() {
951 check(json!({ "a": 1 }), json!({ "a": 1, "x": null }));
952 check(
953 json!({ "items": [{ "a": 1 }] }),
954 json!({ "items": [{ "a": 1, "x": null }] }),
955 );
956 }
957
958 #[test]
959 fn removed_key_is_null() {
960 let result = diff(&json!({ "a": 1, "b": 2 }), &json!({ "a": 1 }));
961 assert!(!result.forced_snapshot, "removing a key is a clean delete");
962 assert_eq!(result.patch, json!({ "b": null }));
963 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1 }));
964 }
965
966 #[test]
967 fn nested_object_only_includes_changed_keys() {
968 let result = diff(&json!({ "o": { "x": 1, "y": 2 } }), &json!({ "o": { "x": 1, "y": 9 } }));
969 assert!(!result.forced_snapshot);
970 assert_eq!(result.patch, json!({ "o": { "y": 9 } }));
971 check(json!({ "o": { "x": 1, "y": 2 } }), json!({ "o": { "x": 1, "y": 9 } }));
972 }
973
974 #[test]
975 fn unchanged_object_is_empty_patch() {
976 let result = diff(&json!({ "a": 1, "o": { "x": 1 } }), &json!({ "a": 1, "o": { "x": 1 } }));
977 assert!(!result.forced_snapshot);
978 assert_eq!(result.patch, json!({}));
979 }
980
981 #[test]
982 fn changed_array_is_wholesale_delta() {
983 let result = diff(&json!({ "a": [1, 2] }), &json!({ "a": [1, 2, 3] }));
984 assert!(!result.forced_snapshot);
985 assert_eq!(result.patch, json!({ "a": [1, 2, 3] }));
986 check(json!({ "a": [1, 2] }), json!({ "a": [1, 2, 3] }));
987 }
988
989 #[test]
990 fn unchanged_array_is_pruned() {
991 let result = diff(&json!({ "a": [1, 2, 3], "b": 1 }), &json!({ "a": [1, 2, 3], "b": 2 }));
992 assert_eq!(
993 result.patch,
994 json!({ "b": 2 }),
995 "an unchanged array stays out of the patch"
996 );
997 }
998
999 #[test]
1000 fn added_array_is_delta() {
1001 check(json!({ "a": 1 }), json!({ "a": 1, "b": [1] }));
1002 }
1003
1004 #[test]
1005 fn nested_array_is_delta() {
1006 check(json!({ "o": { "x": 1 } }), json!({ "o": { "x": 1, "list": [1] } }));
1007 }
1008
1009 #[test]
1010 fn array_of_objects_replaces_wholesale() {
1011 check(
1012 json!({ "items": [{ "id": 1, "v": 1 }, { "id": 2, "v": 2 }] }),
1013 json!({ "items": [{ "id": 1, "v": 9 }, { "id": 2, "v": 2 }] }),
1014 );
1015 }
1016
1017 #[test]
1018 fn set_to_null_forces_snapshot() {
1019 let result = diff(&json!({ "a": 1 }), &json!({ "a": null }));
1021 assert!(result.forced_snapshot);
1022 assert!(reference(&json!({ "a": 1 }), &json!({ "a": null })).forced_snapshot);
1023 }
1024
1025 #[test]
1026 fn nested_null_forces_snapshot() {
1027 let old = json!({ "o": { "x": 1 } });
1028 let new = json!({ "o": { "x": null } });
1029 assert!(diff(&old, &new).forced_snapshot);
1030 assert_eq!(diff(&old, &new).forced_snapshot, reference(&old, &new).forced_snapshot);
1031 }
1032
1033 #[test]
1034 fn replacing_object_with_scalar() {
1035 check(json!({ "a": { "x": 1 } }), json!({ "a": 5 }));
1036 }
1037
1038 #[test]
1039 fn replacing_scalar_with_object() {
1040 check(json!({ "a": 5 }), json!({ "a": { "x": 1 } }));
1041 }
1042
1043 #[test]
1044 fn non_object_root_forces_snapshot() {
1045 let result = diff(&json!(1), &json!(2));
1046 assert!(result.forced_snapshot);
1047 assert_eq!(result.patch, json!(2));
1048 }
1049
1050 #[test]
1051 fn array_root_forces_snapshot() {
1052 let result = diff(&json!([1, 2]), &json!([1, 2, 3]));
1053 assert!(result.forced_snapshot);
1054 assert_eq!(result.patch, json!([1, 2, 3]));
1055 }
1056
1057 #[test]
1058 fn unchanged_scalar_root_is_not_forced() {
1059 let result = diff(&json!(7), &json!(7));
1061 assert!(!result.forced_snapshot);
1062 assert_eq!(result.patch, json!({}));
1063 }
1064
1065 #[test]
1066 fn floats_and_bools_and_strings() {
1067 check(
1068 json!({ "f": 1.5, "b": true, "s": "hi" }),
1069 json!({ "f": 2.5, "b": false, "s": "bye" }),
1070 );
1071 }
1072
1073 #[derive(serde::Serialize, serde::Deserialize, Default, PartialEq, Debug)]
1076 struct Doc {
1077 #[serde(skip_serializing_if = "Option::is_none")]
1078 video: Option<String>,
1079 #[serde(skip_serializing_if = "Option::is_none")]
1080 scte35: Option<u32>,
1081 count: u64,
1082 tags: Vec<String>,
1083 }
1084
1085 fn check_struct(old: &Doc, new: &Doc) {
1087 let old_value = serde_json::to_value(old).unwrap();
1088 let result = diff(&old_value, new);
1089
1090 let new_value = serde_json::to_value(new).unwrap();
1092 let want = reference(&old_value, &new_value);
1093 assert_eq!(result.patch, want.patch, "struct patch differs from oracle");
1094 assert_eq!(result.forced_snapshot, want.forced_snapshot);
1095
1096 if !result.forced_snapshot {
1097 let mut applied = old_value;
1098 json_patch::merge(&mut applied, &result.patch);
1099 assert_eq!(applied, new_value, "struct patch did not roundtrip");
1100 }
1101 }
1102
1103 #[test]
1104 fn struct_field_change() {
1105 check_struct(
1106 &Doc {
1107 count: 1,
1108 tags: vec!["a".into()],
1109 ..Default::default()
1110 },
1111 &Doc {
1112 count: 2,
1113 tags: vec!["a".into()],
1114 ..Default::default()
1115 },
1116 );
1117 }
1118
1119 #[test]
1120 fn struct_option_some_to_none_is_deletion() {
1121 let result = diff(
1123 &serde_json::to_value(Doc {
1124 video: Some("v1".into()),
1125 count: 1,
1126 ..Default::default()
1127 })
1128 .unwrap(),
1129 &Doc {
1130 video: None,
1131 count: 1,
1132 ..Default::default()
1133 },
1134 );
1135 assert!(!result.forced_snapshot, "deleting a skipped key is clean");
1136 assert_eq!(result.patch, json!({ "video": null }));
1137 check_struct(
1138 &Doc {
1139 video: Some("v1".into()),
1140 count: 1,
1141 ..Default::default()
1142 },
1143 &Doc {
1144 video: None,
1145 count: 1,
1146 ..Default::default()
1147 },
1148 );
1149 }
1150
1151 #[test]
1152 fn struct_option_none_to_some_is_addition() {
1153 check_struct(
1154 &Doc {
1155 count: 1,
1156 ..Default::default()
1157 },
1158 &Doc {
1159 scte35: Some(42),
1160 count: 1,
1161 ..Default::default()
1162 },
1163 );
1164 }
1165
1166 #[test]
1167 fn struct_unchanged_is_empty_patch() {
1168 let doc = Doc {
1169 video: Some("v".into()),
1170 scte35: Some(1),
1171 count: 7,
1172 tags: vec!["x".into(), "y".into()],
1173 };
1174 let result = diff(&serde_json::to_value(&doc).unwrap(), &doc);
1175 assert!(!result.forced_snapshot);
1176 assert_eq!(result.patch, json!({}));
1177 }
1178
1179 #[test]
1180 fn struct_vec_changes_wholesale() {
1181 check_struct(
1182 &Doc {
1183 count: 1,
1184 tags: vec!["a".into(), "b".into()],
1185 ..Default::default()
1186 },
1187 &Doc {
1188 count: 1,
1189 tags: vec!["a".into(), "c".into()],
1190 ..Default::default()
1191 },
1192 );
1193 }
1194
1195 #[derive(serde::Serialize)]
1196 struct Nested {
1197 inner: Inner,
1198 name: String,
1199 }
1200 #[derive(serde::Serialize)]
1201 struct Inner {
1202 a: u32,
1203 b: u32,
1204 }
1205
1206 #[test]
1207 fn nested_struct_only_changed_field() {
1208 let old = serde_json::to_value(Nested {
1209 inner: Inner { a: 1, b: 2 },
1210 name: "n".into(),
1211 })
1212 .unwrap();
1213 let new = Nested {
1214 inner: Inner { a: 1, b: 9 },
1215 name: "n".into(),
1216 };
1217 let result = diff(&old, &new);
1218 assert_eq!(result.patch, json!({ "inner": { "b": 9 } }));
1219 assert!(!result.forced_snapshot);
1220 }
1221
1222 #[derive(serde::Serialize)]
1223 enum Tag {
1224 Active,
1225 Idle,
1226 }
1227
1228 #[derive(serde::Serialize)]
1229 struct Stated {
1230 state: Tag,
1231 seq: u32,
1232 }
1233
1234 #[test]
1235 fn unit_enum_variant_is_string() {
1236 let old = serde_json::to_value(Stated {
1238 state: Tag::Active,
1239 seq: 1,
1240 })
1241 .unwrap();
1242 assert_eq!(old, json!({ "state": "Active", "seq": 1 }));
1243 let result = diff(
1244 &old,
1245 &Stated {
1246 state: Tag::Idle,
1247 seq: 1,
1248 },
1249 );
1250 assert!(!result.forced_snapshot);
1251 assert_eq!(result.patch, json!({ "state": "Idle" }));
1252 }
1253
1254 fn check_typed<T: Serialize>(old: &Value, new: &T) {
1257 let new_value = serde_json::to_value(new).unwrap();
1258 let want = reference(old, &new_value);
1259 let got = diff(old, new);
1260 assert_eq!(got.patch, want.patch, "patch differs from oracle");
1261 assert_eq!(got.forced_snapshot, want.forced_snapshot, "forced differs from oracle");
1262 if !got.forced_snapshot {
1263 let mut applied = old.clone();
1264 json_patch::merge(&mut applied, &got.patch);
1265 assert_eq!(applied, new_value, "patch did not roundtrip");
1266 }
1267 }
1268
1269 #[derive(serde::Serialize)]
1270 enum Payload {
1271 Newtype(u32),
1272 Tuple(u32, String),
1273 Struct { x: u32, y: u32 },
1274 }
1275
1276 #[derive(serde::Serialize)]
1277 struct Holder {
1278 payload: Payload,
1279 seq: u32,
1280 }
1281
1282 #[test]
1283 fn newtype_variant_keeps_its_tag() {
1284 let old = serde_json::to_value(Holder {
1286 payload: Payload::Newtype(1),
1287 seq: 0,
1288 })
1289 .unwrap();
1290 assert_eq!(old, json!({ "payload": { "Newtype": 1 }, "seq": 0 }));
1291 let result = diff(
1292 &old,
1293 &Holder {
1294 payload: Payload::Newtype(2),
1295 seq: 0,
1296 },
1297 );
1298 assert_eq!(result.patch, json!({ "payload": { "Newtype": 2 } }));
1299 check_typed(
1300 &old,
1301 &Holder {
1302 payload: Payload::Newtype(2),
1303 seq: 0,
1304 },
1305 );
1306 }
1307
1308 #[test]
1309 fn tuple_variant_keeps_its_tag() {
1310 let old = serde_json::to_value(Holder {
1311 payload: Payload::Tuple(1, "a".into()),
1312 seq: 0,
1313 })
1314 .unwrap();
1315 assert_eq!(old, json!({ "payload": { "Tuple": [1, "a"] }, "seq": 0 }));
1316 check_typed(
1317 &old,
1318 &Holder {
1319 payload: Payload::Tuple(2, "a".into()),
1320 seq: 0,
1321 },
1322 );
1323 }
1324
1325 #[test]
1326 fn struct_variant_keeps_its_tag() {
1327 let old = serde_json::to_value(Holder {
1328 payload: Payload::Struct { x: 1, y: 2 },
1329 seq: 0,
1330 })
1331 .unwrap();
1332 assert_eq!(old, json!({ "payload": { "Struct": { "x": 1, "y": 2 } }, "seq": 0 }));
1333 check_typed(
1334 &old,
1335 &Holder {
1336 payload: Payload::Struct { x: 1, y: 9 },
1337 seq: 0,
1338 },
1339 );
1340 }
1341
1342 #[derive(serde::Deserialize)]
1343 struct Vector {
1344 name: String,
1345 old: Value,
1346 new: Value,
1347 forced: bool,
1348 patch: Option<Value>,
1349 }
1350
1351 #[test]
1354 fn golden_vectors() {
1355 let vectors: Vec<Vector> = serde_json::from_str(include_str!("../tests/vectors.json")).unwrap();
1356 for case in vectors {
1357 let result = diff(&case.old, &case.new);
1358 assert_eq!(result.forced_snapshot, case.forced, "{}: forced_snapshot", case.name);
1359
1360 if let Some(expected) = case.patch {
1361 assert_eq!(result.patch, expected, "{}: patch", case.name);
1362 let mut applied = case.old.clone();
1363 json_patch::merge(&mut applied, &result.patch);
1364 assert_eq!(applied, case.new, "{}: roundtrip", case.name);
1365 }
1366 }
1367 }
1368
1369 #[test]
1372 fn evolving_document_matches_oracle() {
1373 let mut docs = Vec::new();
1374 for tick in 0u64..40 {
1375 docs.push(json!({
1376 "id": "device-1",
1377 "static": { "model": "x", "tags": ["a", "b", "c"] },
1378 "counters": { "n": tick, "errors": tick / 10 },
1379 "reading": (tick as f64 * 0.5),
1380 "flags": { "online": tick % 2 == 0, "charging": tick % 3 == 0 },
1381 "list": [tick, tick + 1],
1382 }));
1383 }
1384 for pair in docs.windows(2) {
1385 check(pair[0].clone(), pair[1].clone());
1386 }
1387 }
1388}