Skip to content

Commit 2033652

Browse files
6293untitaker
andauthored
support for minimum/maximum changes (#13)
Co-authored-by: Markus Unterwaditzer <markus-tarpit+git@unterwaditzer.net>
1 parent adec687 commit 2033652

File tree

3 files changed

+359
-3
lines changed

3 files changed

+359
-3
lines changed

src/diff_walker.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::BTreeSet;
33
use schemars::schema::{InstanceType, RootSchema, Schema, SchemaObject, SingleOrVec};
44
use serde_json::Value;
55

6-
use crate::{Change, ChangeKind, Error, JsonSchemaType};
6+
use crate::{Change, ChangeKind, Error, JsonSchemaType, Range};
77

88
pub struct DiffWalker {
99
pub changes: Vec<Change>,
@@ -143,6 +143,42 @@ impl DiffWalker {
143143
Ok(())
144144
}
145145

146+
fn diff_range(
147+
&mut self,
148+
json_path: &str,
149+
lhs: &mut SchemaObject,
150+
rhs: &mut SchemaObject,
151+
) -> Result<(), Error> {
152+
let mut diff = |lhs, rhs, range| match (lhs, rhs) {
153+
(None, Some(value)) => self.changes.push(Change {
154+
path: json_path.to_owned(),
155+
change: ChangeKind::RangeAdd {
156+
added: range,
157+
value,
158+
},
159+
}),
160+
(Some(value), None) => self.changes.push(Change {
161+
path: json_path.to_owned(),
162+
change: ChangeKind::RangeRemove {
163+
removed: range,
164+
value,
165+
},
166+
}),
167+
(Some(lhs), Some(rhs)) if lhs != rhs => self.changes.push(Change {
168+
path: json_path.to_owned(),
169+
change: ChangeKind::RangeChange {
170+
changed: range,
171+
old_value: lhs,
172+
new_value: rhs,
173+
},
174+
}),
175+
_ => (),
176+
};
177+
diff(lhs.number().minimum, rhs.number().minimum, Range::Minimum);
178+
diff(lhs.number().maximum, rhs.number().maximum, Range::Maximum);
179+
Ok(())
180+
}
181+
146182
fn diff_array_items(
147183
&mut self,
148184
json_path: &str,
@@ -263,6 +299,7 @@ impl DiffWalker {
263299
self.diff_any_of(json_path, lhs, rhs)?;
264300
self.diff_instance_types(json_path, lhs, rhs);
265301
self.diff_properties(json_path, lhs, rhs)?;
302+
self.diff_range(json_path, lhs, rhs)?;
266303
self.diff_additional_properties(json_path, lhs, rhs)?;
267304
self.diff_array_items(json_path, lhs, rhs)?;
268305
Ok(())

src/lib.rs

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,279 @@ mod tests {
602602

603603
assert_debug_snapshot!(diff, @"[]");
604604
}
605+
606+
#[test]
607+
fn add_minimum() {
608+
let lhs = json! {{
609+
"type": "number",
610+
}};
611+
let rhs = json! {{
612+
"type": "number",
613+
"minimum": 1.0
614+
}};
615+
616+
let diff = diff(lhs, rhs).unwrap();
617+
618+
assert_debug_snapshot!(
619+
diff,
620+
@r###"
621+
[
622+
Change {
623+
path: "",
624+
change: RangeAdd {
625+
added: Minimum,
626+
value: 1.0,
627+
},
628+
},
629+
]
630+
"###
631+
);
632+
}
633+
634+
#[test]
635+
fn add_minimum_in_array() {
636+
let lhs = json! {{
637+
"type": "array",
638+
"items": [
639+
{"const": "start_unmerge"},
640+
{"$ref": "#/definitions/Hello"}
641+
],
642+
"definitions": {
643+
"Hello": {
644+
"type": "number",
645+
}
646+
}
647+
}};
648+
649+
let rhs = json! {{
650+
"type": "array",
651+
"items": [
652+
{"const": "start_unmerge"},
653+
{"$ref": "#/definitions/Hello"}
654+
],
655+
"definitions": {
656+
"Hello": {
657+
"type": "number",
658+
"minimum": 1.0
659+
}
660+
}
661+
}};
662+
663+
let diff = diff(lhs, rhs).unwrap();
664+
665+
assert_debug_snapshot!(diff, @r###"
666+
[
667+
Change {
668+
path: ".1",
669+
change: RangeAdd {
670+
added: Minimum,
671+
value: 1.0,
672+
},
673+
},
674+
]
675+
"###);
676+
}
677+
678+
#[test]
679+
fn add_maximum() {
680+
let lhs = json! {{
681+
"type": "number",
682+
}};
683+
let rhs = json! {{
684+
"type": "number",
685+
"maximum": 1.0
686+
}};
687+
688+
let diff = diff(lhs, rhs).unwrap();
689+
690+
assert_debug_snapshot!(
691+
diff,
692+
@r###"
693+
[
694+
Change {
695+
path: "",
696+
change: RangeAdd {
697+
added: Maximum,
698+
value: 1.0,
699+
},
700+
},
701+
]
702+
"###
703+
);
704+
}
705+
706+
#[test]
707+
fn remove_minimum() {
708+
let lhs = json! {{
709+
"type": "number",
710+
"minimum": 1.0
711+
}};
712+
let rhs = json! {{
713+
"type": "number",
714+
}};
715+
716+
let diff = diff(lhs, rhs).unwrap();
717+
718+
assert_debug_snapshot!(
719+
diff,
720+
@r###"
721+
[
722+
Change {
723+
path: "",
724+
change: RangeRemove {
725+
removed: Minimum,
726+
value: 1.0,
727+
},
728+
},
729+
]
730+
"###
731+
);
732+
}
733+
734+
#[test]
735+
fn remove_maximum() {
736+
let lhs = json! {{
737+
"type": "number",
738+
"maximum": 1.0
739+
}};
740+
let rhs = json! {{
741+
"type": "number",
742+
}};
743+
744+
let diff = diff(lhs, rhs).unwrap();
745+
746+
assert_debug_snapshot!(
747+
diff,
748+
@r###"
749+
[
750+
Change {
751+
path: "",
752+
change: RangeRemove {
753+
removed: Maximum,
754+
value: 1.0,
755+
},
756+
},
757+
]
758+
"###
759+
);
760+
}
761+
762+
#[test]
763+
fn change_minimum() {
764+
let lhs = json! {{
765+
"type": "number",
766+
"minimum": 1.0
767+
}};
768+
let rhs = json! {{
769+
"type": "number",
770+
"minimum": 1.3
771+
}};
772+
773+
let diff = diff(lhs, rhs).unwrap();
774+
775+
assert_debug_snapshot!(
776+
diff,
777+
@r###"
778+
[
779+
Change {
780+
path: "",
781+
change: RangeChange {
782+
changed: Minimum,
783+
old_value: 1.0,
784+
new_value: 1.3,
785+
},
786+
},
787+
]
788+
"###
789+
);
790+
}
791+
792+
#[test]
793+
fn change_maximum() {
794+
let lhs = json! {{
795+
"type": "number",
796+
"maximum": 1.0
797+
}};
798+
let rhs = json! {{
799+
"type": "number",
800+
"maximum": 1.3
801+
}};
802+
803+
let diff = diff(lhs, rhs).unwrap();
804+
805+
assert_debug_snapshot!(
806+
diff,
807+
@r###"
808+
[
809+
Change {
810+
path: "",
811+
change: RangeChange {
812+
changed: Maximum,
813+
old_value: 1.0,
814+
new_value: 1.3,
815+
},
816+
},
817+
]
818+
"###
819+
);
820+
}
821+
822+
#[test]
823+
fn change_minimum_and_maximum() {
824+
let lhs = json! {{
825+
"type": "number",
826+
"minimum": 1.0,
827+
"maximum": 2.0,
828+
}};
829+
let rhs = json! {{
830+
"type": "number",
831+
"minimum": 1.5,
832+
"maximum": 2.5,
833+
}};
834+
835+
let diff = diff(lhs, rhs).unwrap();
836+
837+
assert_debug_snapshot!(
838+
diff,
839+
@r###"
840+
[
841+
Change {
842+
path: "",
843+
change: RangeChange {
844+
changed: Minimum,
845+
old_value: 1.0,
846+
new_value: 1.5,
847+
},
848+
},
849+
Change {
850+
path: "",
851+
change: RangeChange {
852+
changed: Maximum,
853+
old_value: 2.0,
854+
new_value: 2.5,
855+
},
856+
},
857+
]
858+
"###
859+
);
860+
}
861+
862+
#[test]
863+
fn unchanged_minimum() {
864+
let lhs = json! {{
865+
"type": "number",
866+
"minimum": 1.3
867+
}};
868+
let rhs = json! {{
869+
"type": "number",
870+
"minimum": 1.3
871+
}};
872+
873+
let diff = diff(lhs, rhs).unwrap();
874+
875+
assert_debug_snapshot!(
876+
diff,
877+
@"[]"
878+
);
879+
}
605880
}

0 commit comments

Comments
 (0)