Skip to content

Commit 4a1a838

Browse files
authored
feat: Add support for changes to "required" properties (#19)
1 parent bfdbe82 commit 4a1a838

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

src/diff_walker.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,36 @@ impl DiffWalker {
260260
Ok(())
261261
}
262262

263+
fn diff_required(
264+
&mut self,
265+
json_path: &str,
266+
lhs: &mut SchemaObject,
267+
rhs: &mut SchemaObject,
268+
) -> Result<(), Error> {
269+
let lhs_required = &lhs.object().required;
270+
let rhs_required = &rhs.object().required;
271+
272+
for removed in lhs_required.difference(rhs_required) {
273+
self.changes.push(Change {
274+
path: json_path.to_owned(),
275+
change: ChangeKind::RequiredRemove {
276+
property: removed.clone(),
277+
},
278+
});
279+
}
280+
281+
for added in rhs_required.difference(lhs_required) {
282+
self.changes.push(Change {
283+
path: json_path.to_owned(),
284+
change: ChangeKind::RequiredAdd {
285+
property: added.clone(),
286+
},
287+
});
288+
}
289+
290+
Ok(())
291+
}
292+
263293
fn resolve_ref<'a>(root_schema: &'a RootSchema, reference: &str) -> Option<&'a Schema> {
264294
if let Some(definition_name) = reference.strip_prefix("#/definitions/") {
265295
let schema_object = root_schema.definitions.get(definition_name)?;
@@ -302,6 +332,7 @@ impl DiffWalker {
302332
self.diff_range(json_path, lhs, rhs)?;
303333
self.diff_additional_properties(json_path, lhs, rhs)?;
304334
self.diff_array_items(json_path, lhs, rhs)?;
335+
self.diff_required(json_path, lhs, rhs)?;
305336
Ok(())
306337
}
307338
}

src/lib.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,4 +877,55 @@ mod tests {
877877
@"[]"
878878
);
879879
}
880+
881+
#[test]
882+
fn drop_required() {
883+
let lhs = json! {{
884+
"required": ["value"]
885+
}};
886+
let rhs = json! {{
887+
"required": [],
888+
}};
889+
890+
let diff = diff(lhs, rhs).unwrap();
891+
892+
assert_debug_snapshot!(
893+
diff,
894+
@r###"
895+
[
896+
Change {
897+
path: "",
898+
change: RequiredRemove {
899+
property: "value",
900+
},
901+
},
902+
]
903+
"###
904+
);
905+
}
906+
907+
#[test]
908+
fn add_required() {
909+
let lhs = json! {{
910+
"required": []
911+
}};
912+
let rhs = json! {{
913+
"required": ["value"],
914+
}};
915+
916+
let diff = diff(lhs, rhs).unwrap();
917+
assert_debug_snapshot!(
918+
diff,
919+
@r###"
920+
[
921+
Change {
922+
path: "",
923+
change: RequiredAdd {
924+
property: "value",
925+
},
926+
},
927+
]
928+
"###
929+
);
930+
}
880931
}

src/types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ pub enum ChangeKind {
9292
/// The new length of the tuple
9393
new_length: usize,
9494
},
95+
/// A previously required property has been removed
96+
RequiredRemove {
97+
/// The property that is no longer required
98+
property: String,
99+
},
100+
/// A previously optional property has been made required
101+
RequiredAdd {
102+
/// The property that is now required
103+
property: String,
104+
},
95105
}
96106

97107
impl ChangeKind {
@@ -128,6 +138,8 @@ impl ChangeKind {
128138
Self::TupleToArray { .. } => false,
129139
Self::ArrayToTuple { .. } => true,
130140
Self::TupleChange { .. } => true,
141+
Self::RequiredRemove { .. } => false,
142+
Self::RequiredAdd { .. } => true,
131143
}
132144
}
133145
}

0 commit comments

Comments
 (0)