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 seen[depth][..self.seen_len];
584 let out = &mut bytes[depth];
585 if self.ordered {
586 seen.sort_unstable();
587 }
588 for key in base.keys() {
589 if seen.binary_search_by(|seen| seen.as_str().cmp(key)).is_err() {
590 if self.entries == 0 {
591 if depth == 0 {
592 out.reserve(*last_capacity);
593 }
594 out.push(b'{');
595 } else {
596 out.push(b',');
597 }
598 serde_json::to_writer(&mut *out, key).map_err(|err| Error(err.to_string()))?;
599 out.extend_from_slice(b":null");
600 self.entries += 1;
601 }
602 }
603 }
604 if self.entries == 0 {
605 if self.differ.baseline.is_object() {
606 return Ok(Node::Same);
607 }
608 self.differ
609 .scratch
610 .borrow_mut()
611 .buffer(self.differ.depth)
612 .extend_from_slice(b"{}");
613 return Ok(Node::Diff);
614 }
615 self.differ.scratch.borrow_mut().buffer(self.differ.depth).push(b'}');
616 Ok(Node::Diff)
617 }
618}
619
620impl SerializeMap for MapDiff<'_> {
621 type Ok = Node;
622 type Error = Error;
623 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Error> {
624 let mut scratch = self.differ.scratch.borrow_mut();
625 if scratch.pending.len() <= self.differ.depth {
626 scratch.pending.resize_with(self.differ.depth + 1, String::new);
627 }
628 let pending = &mut scratch.pending[self.differ.depth];
629 pending.clear();
630 key.serialize(KeySer(pending))
631 }
632 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
633 let depth = self.differ.depth;
634 let key = std::mem::take(&mut self.differ.scratch.borrow_mut().pending[depth]);
635 let (child, existed) = self.differ.child(&key);
636 let node = value.serialize(child)?;
637 self.entry(&key, existed, node)?;
638 self.differ.scratch.borrow_mut().pending[depth] = key;
639 Ok(())
640 }
641 fn end(self) -> Result<Node, Error> {
642 self.finish()
643 }
644}
645
646impl SerializeStruct for MapDiff<'_> {
647 type Ok = Node;
648 type Error = Error;
649 fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
650 let (child, existed) = self.differ.child(key);
651 let node = value.serialize(child)?;
652 self.entry(key, existed, node)?;
653 Ok(())
654 }
655 fn end(self) -> Result<Node, Error> {
658 self.finish()
659 }
660}
661
662struct KeySer<'a>(&'a mut String);
665
666impl Serializer for KeySer<'_> {
667 type Ok = ();
668 type Error = Error;
669 type SerializeSeq = Impossible<(), Error>;
670 type SerializeTuple = Impossible<(), Error>;
671 type SerializeTupleStruct = Impossible<(), Error>;
672 type SerializeTupleVariant = Impossible<(), Error>;
673 type SerializeMap = Impossible<(), Error>;
674 type SerializeStruct = Impossible<(), Error>;
675 type SerializeStructVariant = Impossible<(), Error>;
676
677 fn serialize_str(self, v: &str) -> Result<(), Error> {
678 {
679 self.0.push_str(v);
680 Ok(())
681 }
682 }
683 fn serialize_char(self, v: char) -> Result<(), Error> {
684 {
685 use std::fmt::Write;
686 write!(self.0, "{v}").expect("writing to String cannot fail");
687 Ok(())
688 }
689 }
690 fn serialize_bool(self, v: bool) -> Result<(), Error> {
691 {
692 use std::fmt::Write;
693 write!(self.0, "{v}").expect("writing to String cannot fail");
694 Ok(())
695 }
696 }
697 fn serialize_i8(self, v: i8) -> Result<(), Error> {
698 {
699 use std::fmt::Write;
700 write!(self.0, "{v}").expect("writing to String cannot fail");
701 Ok(())
702 }
703 }
704 fn serialize_i16(self, v: i16) -> Result<(), Error> {
705 {
706 use std::fmt::Write;
707 write!(self.0, "{v}").expect("writing to String cannot fail");
708 Ok(())
709 }
710 }
711 fn serialize_i32(self, v: i32) -> Result<(), Error> {
712 {
713 use std::fmt::Write;
714 write!(self.0, "{v}").expect("writing to String cannot fail");
715 Ok(())
716 }
717 }
718 fn serialize_i64(self, v: i64) -> Result<(), Error> {
719 {
720 use std::fmt::Write;
721 write!(self.0, "{v}").expect("writing to String cannot fail");
722 Ok(())
723 }
724 }
725 fn serialize_u8(self, v: u8) -> Result<(), Error> {
726 {
727 use std::fmt::Write;
728 write!(self.0, "{v}").expect("writing to String cannot fail");
729 Ok(())
730 }
731 }
732 fn serialize_u16(self, v: u16) -> Result<(), Error> {
733 {
734 use std::fmt::Write;
735 write!(self.0, "{v}").expect("writing to String cannot fail");
736 Ok(())
737 }
738 }
739 fn serialize_u32(self, v: u32) -> Result<(), Error> {
740 {
741 use std::fmt::Write;
742 write!(self.0, "{v}").expect("writing to String cannot fail");
743 Ok(())
744 }
745 }
746 fn serialize_u64(self, v: u64) -> Result<(), Error> {
747 {
748 use std::fmt::Write;
749 write!(self.0, "{v}").expect("writing to String cannot fail");
750 Ok(())
751 }
752 }
753 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<(), Error> {
754 {
755 self.0.push_str(variant);
756 Ok(())
757 }
758 }
759 fn serialize_newtype_struct<T: Serialize + ?Sized>(self, _name: &'static str, value: &T) -> Result<(), Error> {
760 value.serialize(self)
761 }
762 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<(), Error> {
763 value.serialize(self)
764 }
765 fn serialize_f32(self, _v: f32) -> Result<(), Error> {
766 Err(Error("float map key".into()))
767 }
768 fn serialize_f64(self, _v: f64) -> Result<(), Error> {
769 Err(Error("float map key".into()))
770 }
771 fn serialize_bytes(self, _v: &[u8]) -> Result<(), Error> {
772 Err(Error("bytes map key".into()))
773 }
774 fn serialize_none(self) -> Result<(), Error> {
775 Err(Error("null map key".into()))
776 }
777 fn serialize_unit(self) -> Result<(), Error> {
778 Err(Error("unit map key".into()))
779 }
780 fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> {
781 Err(Error("unit struct map key".into()))
782 }
783 fn serialize_newtype_variant<T: Serialize + ?Sized>(
784 self,
785 _name: &'static str,
786 _idx: u32,
787 _variant: &'static str,
788 _value: &T,
789 ) -> Result<(), Error> {
790 Err(Error("newtype variant map key".into()))
791 }
792 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
793 Err(Error("seq map key".into()))
794 }
795 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Error> {
796 Err(Error("tuple map key".into()))
797 }
798 fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct, Error> {
799 Err(Error("tuple struct map key".into()))
800 }
801 fn serialize_tuple_variant(
802 self,
803 _name: &'static str,
804 _idx: u32,
805 _variant: &'static str,
806 _len: usize,
807 ) -> Result<Self::SerializeTupleVariant, Error> {
808 Err(Error("tuple variant map key".into()))
809 }
810 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
811 Err(Error("map map key".into()))
812 }
813 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Error> {
814 Err(Error("struct map key".into()))
815 }
816 fn serialize_struct_variant(
817 self,
818 _name: &'static str,
819 _idx: u32,
820 _variant: &'static str,
821 _len: usize,
822 ) -> Result<Self::SerializeStructVariant, Error> {
823 Err(Error("struct variant map key".into()))
824 }
825}
826
827#[cfg(test)]
828mod test {
829 use super::*;
830 use serde_json::json;
831
832 fn reference(old: &Value, new: &Value) -> Diff {
835 fn objects(
836 old: &Map<String, Value>,
837 new: &Map<String, Value>,
838 patch: &mut Map<String, Value>,
839 forced: &mut bool,
840 ) {
841 for key in old.keys() {
842 if !new.contains_key(key) {
843 patch.insert(key.clone(), Value::Null);
844 }
845 }
846 for (key, new_val) in new {
847 let old_val = old.get(key);
848 if old_val == Some(new_val) {
849 continue;
850 }
851 if let (Some(Value::Object(old_obj)), Value::Object(new_obj)) = (old_val, new_val) {
852 let mut sub = Map::new();
853 objects(old_obj, new_obj, &mut sub, forced);
854 if !sub.is_empty() {
855 patch.insert(key.clone(), Value::Object(sub));
856 }
857 continue;
858 }
859 if new_val.is_null() {
860 *forced = true;
861 }
862 patch.insert(key.clone(), new_val.clone());
863 }
864 }
865
866 if let (Value::Object(old_obj), Value::Object(new_obj)) = (old, new) {
867 let mut patch = Map::new();
868 let mut forced = false;
869 objects(old_obj, new_obj, &mut patch, &mut forced);
870 Diff {
871 patch: Value::Object(patch),
872 forced_snapshot: forced,
873 }
874 } else {
875 Diff {
876 patch: new.clone(),
877 forced_snapshot: true,
878 }
879 }
880 }
881
882 fn check(old: Value, new: Value) {
885 let want = reference(&old, &new);
886 let got = diff(&old, &new);
887 assert_eq!(got.patch, want.patch, "patch mismatch for {old} -> {new}");
888 assert_eq!(
889 got.forced_snapshot, want.forced_snapshot,
890 "forced mismatch for {old} -> {new}"
891 );
892 if !got.forced_snapshot {
893 let mut applied = old.clone();
894 json_patch::merge(&mut applied, &got.patch);
895 assert_eq!(applied, new, "patch did not roundtrip for {old} -> {new}");
896 }
897 }
898
899 #[test]
900 fn replacing_scalar_with_empty_object_is_a_change() {
901 check(json!({ "value": 1 }), json!({ "value": {} }));
902 check(json!({ "value": null }), json!({ "value": {} }));
903 let result = diff(&json!(1), &json!({}));
904 assert!(result.forced_snapshot);
905 assert_eq!(result.patch, json!({}));
906 }
907
908 #[test]
909 fn duplicate_serialized_map_keys_force_a_snapshot() {
910 struct Duplicate;
911 impl Serialize for Duplicate {
912 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
913 let mut map = serializer.serialize_map(Some(3))?;
914 map.serialize_entry("key", &1)?;
915 map.serialize_entry("other", &2)?;
916 map.serialize_entry("key", &3)?;
917 map.end()
918 }
919 }
920 assert!(diff(&json!({ "key": 1, "other": 2 }), &Duplicate).forced_snapshot);
921 }
922
923 #[test]
924 fn changed_scalar() {
925 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1, "b": 3 }));
926 }
927
928 #[test]
929 fn added_key() {
930 let result = diff(&json!({ "a": 1 }), &json!({ "a": 1, "b": 2 }));
931 assert!(!result.forced_snapshot);
932 assert_eq!(result.patch, json!({ "b": 2 }));
933 check(json!({ "a": 1 }), json!({ "a": 1, "b": 2 }));
934 }
935
936 #[test]
937 fn added_null_key_forces_snapshot() {
938 check(json!({ "a": 1 }), json!({ "a": 1, "x": null }));
939 check(
940 json!({ "items": [{ "a": 1 }] }),
941 json!({ "items": [{ "a": 1, "x": null }] }),
942 );
943 }
944
945 #[test]
946 fn removed_key_is_null() {
947 let result = diff(&json!({ "a": 1, "b": 2 }), &json!({ "a": 1 }));
948 assert!(!result.forced_snapshot, "removing a key is a clean delete");
949 assert_eq!(result.patch, json!({ "b": null }));
950 check(json!({ "a": 1, "b": 2 }), json!({ "a": 1 }));
951 }
952
953 #[test]
954 fn nested_object_only_includes_changed_keys() {
955 let result = diff(&json!({ "o": { "x": 1, "y": 2 } }), &json!({ "o": { "x": 1, "y": 9 } }));
956 assert!(!result.forced_snapshot);
957 assert_eq!(result.patch, json!({ "o": { "y": 9 } }));
958 check(json!({ "o": { "x": 1, "y": 2 } }), json!({ "o": { "x": 1, "y": 9 } }));
959 }
960
961 #[test]
962 fn unchanged_object_is_empty_patch() {
963 let result = diff(&json!({ "a": 1, "o": { "x": 1 } }), &json!({ "a": 1, "o": { "x": 1 } }));
964 assert!(!result.forced_snapshot);
965 assert_eq!(result.patch, json!({}));
966 }
967
968 #[test]
969 fn changed_array_is_wholesale_delta() {
970 let result = diff(&json!({ "a": [1, 2] }), &json!({ "a": [1, 2, 3] }));
971 assert!(!result.forced_snapshot);
972 assert_eq!(result.patch, json!({ "a": [1, 2, 3] }));
973 check(json!({ "a": [1, 2] }), json!({ "a": [1, 2, 3] }));
974 }
975
976 #[test]
977 fn unchanged_array_is_pruned() {
978 let result = diff(&json!({ "a": [1, 2, 3], "b": 1 }), &json!({ "a": [1, 2, 3], "b": 2 }));
979 assert_eq!(
980 result.patch,
981 json!({ "b": 2 }),
982 "an unchanged array stays out of the patch"
983 );
984 }
985
986 #[test]
987 fn added_array_is_delta() {
988 check(json!({ "a": 1 }), json!({ "a": 1, "b": [1] }));
989 }
990
991 #[test]
992 fn nested_array_is_delta() {
993 check(json!({ "o": { "x": 1 } }), json!({ "o": { "x": 1, "list": [1] } }));
994 }
995
996 #[test]
997 fn array_of_objects_replaces_wholesale() {
998 check(
999 json!({ "items": [{ "id": 1, "v": 1 }, { "id": 2, "v": 2 }] }),
1000 json!({ "items": [{ "id": 1, "v": 9 }, { "id": 2, "v": 2 }] }),
1001 );
1002 }
1003
1004 #[test]
1005 fn set_to_null_forces_snapshot() {
1006 let result = diff(&json!({ "a": 1 }), &json!({ "a": null }));
1008 assert!(result.forced_snapshot);
1009 assert!(reference(&json!({ "a": 1 }), &json!({ "a": null })).forced_snapshot);
1010 }
1011
1012 #[test]
1013 fn nested_null_forces_snapshot() {
1014 let old = json!({ "o": { "x": 1 } });
1015 let new = json!({ "o": { "x": null } });
1016 assert!(diff(&old, &new).forced_snapshot);
1017 assert_eq!(diff(&old, &new).forced_snapshot, reference(&old, &new).forced_snapshot);
1018 }
1019
1020 #[test]
1021 fn replacing_object_with_scalar() {
1022 check(json!({ "a": { "x": 1 } }), json!({ "a": 5 }));
1023 }
1024
1025 #[test]
1026 fn replacing_scalar_with_object() {
1027 check(json!({ "a": 5 }), json!({ "a": { "x": 1 } }));
1028 }
1029
1030 #[test]
1031 fn non_object_root_forces_snapshot() {
1032 let result = diff(&json!(1), &json!(2));
1033 assert!(result.forced_snapshot);
1034 assert_eq!(result.patch, json!(2));
1035 }
1036
1037 #[test]
1038 fn array_root_forces_snapshot() {
1039 let result = diff(&json!([1, 2]), &json!([1, 2, 3]));
1040 assert!(result.forced_snapshot);
1041 assert_eq!(result.patch, json!([1, 2, 3]));
1042 }
1043
1044 #[test]
1045 fn unchanged_scalar_root_is_not_forced() {
1046 let result = diff(&json!(7), &json!(7));
1048 assert!(!result.forced_snapshot);
1049 assert_eq!(result.patch, json!({}));
1050 }
1051
1052 #[test]
1053 fn floats_and_bools_and_strings() {
1054 check(
1055 json!({ "f": 1.5, "b": true, "s": "hi" }),
1056 json!({ "f": 2.5, "b": false, "s": "bye" }),
1057 );
1058 }
1059
1060 #[derive(serde::Serialize, serde::Deserialize, Default, PartialEq, Debug)]
1063 struct Doc {
1064 #[serde(skip_serializing_if = "Option::is_none")]
1065 video: Option<String>,
1066 #[serde(skip_serializing_if = "Option::is_none")]
1067 scte35: Option<u32>,
1068 count: u64,
1069 tags: Vec<String>,
1070 }
1071
1072 fn check_struct(old: &Doc, new: &Doc) {
1074 let old_value = serde_json::to_value(old).unwrap();
1075 let result = diff(&old_value, new);
1076
1077 let new_value = serde_json::to_value(new).unwrap();
1079 let want = reference(&old_value, &new_value);
1080 assert_eq!(result.patch, want.patch, "struct patch differs from oracle");
1081 assert_eq!(result.forced_snapshot, want.forced_snapshot);
1082
1083 if !result.forced_snapshot {
1084 let mut applied = old_value;
1085 json_patch::merge(&mut applied, &result.patch);
1086 assert_eq!(applied, new_value, "struct patch did not roundtrip");
1087 }
1088 }
1089
1090 #[test]
1091 fn struct_field_change() {
1092 check_struct(
1093 &Doc {
1094 count: 1,
1095 tags: vec!["a".into()],
1096 ..Default::default()
1097 },
1098 &Doc {
1099 count: 2,
1100 tags: vec!["a".into()],
1101 ..Default::default()
1102 },
1103 );
1104 }
1105
1106 #[test]
1107 fn struct_option_some_to_none_is_deletion() {
1108 let result = diff(
1110 &serde_json::to_value(Doc {
1111 video: Some("v1".into()),
1112 count: 1,
1113 ..Default::default()
1114 })
1115 .unwrap(),
1116 &Doc {
1117 video: None,
1118 count: 1,
1119 ..Default::default()
1120 },
1121 );
1122 assert!(!result.forced_snapshot, "deleting a skipped key is clean");
1123 assert_eq!(result.patch, json!({ "video": null }));
1124 check_struct(
1125 &Doc {
1126 video: Some("v1".into()),
1127 count: 1,
1128 ..Default::default()
1129 },
1130 &Doc {
1131 video: None,
1132 count: 1,
1133 ..Default::default()
1134 },
1135 );
1136 }
1137
1138 #[test]
1139 fn struct_option_none_to_some_is_addition() {
1140 check_struct(
1141 &Doc {
1142 count: 1,
1143 ..Default::default()
1144 },
1145 &Doc {
1146 scte35: Some(42),
1147 count: 1,
1148 ..Default::default()
1149 },
1150 );
1151 }
1152
1153 #[test]
1154 fn struct_unchanged_is_empty_patch() {
1155 let doc = Doc {
1156 video: Some("v".into()),
1157 scte35: Some(1),
1158 count: 7,
1159 tags: vec!["x".into(), "y".into()],
1160 };
1161 let result = diff(&serde_json::to_value(&doc).unwrap(), &doc);
1162 assert!(!result.forced_snapshot);
1163 assert_eq!(result.patch, json!({}));
1164 }
1165
1166 #[test]
1167 fn struct_vec_changes_wholesale() {
1168 check_struct(
1169 &Doc {
1170 count: 1,
1171 tags: vec!["a".into(), "b".into()],
1172 ..Default::default()
1173 },
1174 &Doc {
1175 count: 1,
1176 tags: vec!["a".into(), "c".into()],
1177 ..Default::default()
1178 },
1179 );
1180 }
1181
1182 #[derive(serde::Serialize)]
1183 struct Nested {
1184 inner: Inner,
1185 name: String,
1186 }
1187 #[derive(serde::Serialize)]
1188 struct Inner {
1189 a: u32,
1190 b: u32,
1191 }
1192
1193 #[test]
1194 fn nested_struct_only_changed_field() {
1195 let old = serde_json::to_value(Nested {
1196 inner: Inner { a: 1, b: 2 },
1197 name: "n".into(),
1198 })
1199 .unwrap();
1200 let new = Nested {
1201 inner: Inner { a: 1, b: 9 },
1202 name: "n".into(),
1203 };
1204 let result = diff(&old, &new);
1205 assert_eq!(result.patch, json!({ "inner": { "b": 9 } }));
1206 assert!(!result.forced_snapshot);
1207 }
1208
1209 #[derive(serde::Serialize)]
1210 enum Tag {
1211 Active,
1212 Idle,
1213 }
1214
1215 #[derive(serde::Serialize)]
1216 struct Stated {
1217 state: Tag,
1218 seq: u32,
1219 }
1220
1221 #[test]
1222 fn unit_enum_variant_is_string() {
1223 let old = serde_json::to_value(Stated {
1225 state: Tag::Active,
1226 seq: 1,
1227 })
1228 .unwrap();
1229 assert_eq!(old, json!({ "state": "Active", "seq": 1 }));
1230 let result = diff(
1231 &old,
1232 &Stated {
1233 state: Tag::Idle,
1234 seq: 1,
1235 },
1236 );
1237 assert!(!result.forced_snapshot);
1238 assert_eq!(result.patch, json!({ "state": "Idle" }));
1239 }
1240
1241 fn check_typed<T: Serialize>(old: &Value, new: &T) {
1244 let new_value = serde_json::to_value(new).unwrap();
1245 let want = reference(old, &new_value);
1246 let got = diff(old, new);
1247 assert_eq!(got.patch, want.patch, "patch differs from oracle");
1248 assert_eq!(got.forced_snapshot, want.forced_snapshot, "forced differs from oracle");
1249 if !got.forced_snapshot {
1250 let mut applied = old.clone();
1251 json_patch::merge(&mut applied, &got.patch);
1252 assert_eq!(applied, new_value, "patch did not roundtrip");
1253 }
1254 }
1255
1256 #[derive(serde::Serialize)]
1257 enum Payload {
1258 Newtype(u32),
1259 Tuple(u32, String),
1260 Struct { x: u32, y: u32 },
1261 }
1262
1263 #[derive(serde::Serialize)]
1264 struct Holder {
1265 payload: Payload,
1266 seq: u32,
1267 }
1268
1269 #[test]
1270 fn newtype_variant_keeps_its_tag() {
1271 let old = serde_json::to_value(Holder {
1273 payload: Payload::Newtype(1),
1274 seq: 0,
1275 })
1276 .unwrap();
1277 assert_eq!(old, json!({ "payload": { "Newtype": 1 }, "seq": 0 }));
1278 let result = diff(
1279 &old,
1280 &Holder {
1281 payload: Payload::Newtype(2),
1282 seq: 0,
1283 },
1284 );
1285 assert_eq!(result.patch, json!({ "payload": { "Newtype": 2 } }));
1286 check_typed(
1287 &old,
1288 &Holder {
1289 payload: Payload::Newtype(2),
1290 seq: 0,
1291 },
1292 );
1293 }
1294
1295 #[test]
1296 fn tuple_variant_keeps_its_tag() {
1297 let old = serde_json::to_value(Holder {
1298 payload: Payload::Tuple(1, "a".into()),
1299 seq: 0,
1300 })
1301 .unwrap();
1302 assert_eq!(old, json!({ "payload": { "Tuple": [1, "a"] }, "seq": 0 }));
1303 check_typed(
1304 &old,
1305 &Holder {
1306 payload: Payload::Tuple(2, "a".into()),
1307 seq: 0,
1308 },
1309 );
1310 }
1311
1312 #[test]
1313 fn struct_variant_keeps_its_tag() {
1314 let old = serde_json::to_value(Holder {
1315 payload: Payload::Struct { x: 1, y: 2 },
1316 seq: 0,
1317 })
1318 .unwrap();
1319 assert_eq!(old, json!({ "payload": { "Struct": { "x": 1, "y": 2 } }, "seq": 0 }));
1320 check_typed(
1321 &old,
1322 &Holder {
1323 payload: Payload::Struct { x: 1, y: 9 },
1324 seq: 0,
1325 },
1326 );
1327 }
1328
1329 #[derive(serde::Deserialize)]
1330 struct Vector {
1331 name: String,
1332 old: Value,
1333 new: Value,
1334 forced: bool,
1335 patch: Option<Value>,
1336 }
1337
1338 #[test]
1341 fn golden_vectors() {
1342 let vectors: Vec<Vector> = serde_json::from_str(include_str!("../tests/vectors.json")).unwrap();
1343 for case in vectors {
1344 let result = diff(&case.old, &case.new);
1345 assert_eq!(result.forced_snapshot, case.forced, "{}: forced_snapshot", case.name);
1346
1347 if let Some(expected) = case.patch {
1348 assert_eq!(result.patch, expected, "{}: patch", case.name);
1349 let mut applied = case.old.clone();
1350 json_patch::merge(&mut applied, &result.patch);
1351 assert_eq!(applied, case.new, "{}: roundtrip", case.name);
1352 }
1353 }
1354 }
1355
1356 #[test]
1359 fn evolving_document_matches_oracle() {
1360 let mut docs = Vec::new();
1361 for tick in 0u64..40 {
1362 docs.push(json!({
1363 "id": "device-1",
1364 "static": { "model": "x", "tags": ["a", "b", "c"] },
1365 "counters": { "n": tick, "errors": tick / 10 },
1366 "reading": (tick as f64 * 0.5),
1367 "flags": { "online": tick % 2 == 0, "charging": tick % 3 == 0 },
1368 "list": [tick, tick + 1],
1369 }));
1370 }
1371 for pair in docs.windows(2) {
1372 check(pair[0].clone(), pair[1].clone());
1373 }
1374 }
1375}