diff --git a/src/diff_walker.rs b/src/diff_walker.rs index 37d755f..ad2b47d 100644 --- a/src/diff_walker.rs +++ b/src/diff_walker.rs @@ -356,6 +356,37 @@ impl DiffWalker { Ok(()) } + fn diff_format(&mut self, json_path: &str, lhs: &mut SchemaObject, rhs: &mut SchemaObject) { + match (&lhs.format, &rhs.format) { + (Some(lhs_fmt), Some(rhs_fmt)) if lhs_fmt != rhs_fmt => { + (self.cb)(Change { + path: json_path.to_owned(), + change: ChangeKind::FormatChange { + old_format: lhs_fmt.clone(), + new_format: rhs_fmt.clone(), + }, + }); + } + (Some(removed_fmt), None) => { + (self.cb)(Change { + path: json_path.to_owned(), + change: ChangeKind::FormatRemove { + removed: removed_fmt.clone(), + }, + }); + } + (None, Some(added_fmt)) => { + (self.cb)(Change { + path: json_path.to_owned(), + change: ChangeKind::FormatAdd { + added: added_fmt.clone(), + }, + }); + } + _ => {} // No change or both None + } + } + fn resolve_references( &self, lhs: &mut SchemaObject, @@ -464,6 +495,7 @@ impl DiffWalker { self.diff_instance_types(json_path, lhs, rhs); } self.diff_const(json_path, lhs, rhs); + self.diff_format(json_path, lhs, rhs); // If we split the types, we don't want to compare type-specific properties // because they are already compared in the `Self::diff_any_of` if !is_lhs_split && !is_rhs_split { diff --git a/src/types.rs b/src/types.rs index 4f9dc2d..bf213f5 100644 --- a/src/types.rs +++ b/src/types.rs @@ -107,6 +107,23 @@ pub enum ChangeKind { /// The property that is now required property: String, }, + /// A format constraint has been added. + FormatAdd { + /// The format that was added. + added: String, + }, + /// A format constraint has been removed. + FormatRemove { + /// The format that was removed. + removed: String, + }, + /// A format constraint has been changed. + FormatChange { + /// The old format value. + old_format: String, + /// The new format value. + new_format: String, + }, } impl ChangeKind { @@ -150,6 +167,9 @@ impl ChangeKind { Self::TupleChange { .. } => true, Self::RequiredRemove { .. } => false, Self::RequiredAdd { .. } => true, + Self::FormatAdd { .. } => true, + Self::FormatRemove { .. } => false, + Self::FormatChange { .. } => true, } } } diff --git a/tests/fixtures/format/format_add.json b/tests/fixtures/format/format_add.json new file mode 100644 index 0000000..cf29407 --- /dev/null +++ b/tests/fixtures/format/format_add.json @@ -0,0 +1,4 @@ +{ + "lhs": { "type": "string" }, + "rhs": { "type": "string", "format": "email" } +} \ No newline at end of file diff --git a/tests/fixtures/format/format_change.json b/tests/fixtures/format/format_change.json new file mode 100644 index 0000000..dac2d75 --- /dev/null +++ b/tests/fixtures/format/format_change.json @@ -0,0 +1,4 @@ +{ + "lhs": { "type": "string", "format": "uuid" }, + "rhs": { "type": "string", "format": "date-time" } +} \ No newline at end of file diff --git a/tests/fixtures/format/format_remove.json b/tests/fixtures/format/format_remove.json new file mode 100644 index 0000000..c9f2095 --- /dev/null +++ b/tests/fixtures/format/format_remove.json @@ -0,0 +1,4 @@ +{ + "lhs": { "type": "string", "format": "uri" }, + "rhs": { "type": "string" } +} \ No newline at end of file diff --git a/tests/fixtures/format/format_unchanged.json b/tests/fixtures/format/format_unchanged.json new file mode 100644 index 0000000..355a1da --- /dev/null +++ b/tests/fixtures/format/format_unchanged.json @@ -0,0 +1,4 @@ +{ + "lhs": { "type": "string", "format": "date" }, + "rhs": { "type": "string", "format": "date" } +} \ No newline at end of file diff --git a/tests/snapshots/test__from_fixtures@format__format_add.json.snap b/tests/snapshots/test__from_fixtures@format__format_add.json.snap new file mode 100644 index 0000000..9b737c9 --- /dev/null +++ b/tests/snapshots/test__from_fixtures@format__format_add.json.snap @@ -0,0 +1,20 @@ +--- +source: tests/test.rs +assertion_line: 12 +expression: diff +info: + lhs: + type: string + rhs: + format: email + type: string +input_file: tests/fixtures/format/format_add.json +--- +[ + Change { + path: "", + change: FormatAdd { + added: "email", + }, + }, +] diff --git a/tests/snapshots/test__from_fixtures@format__format_change.json.snap b/tests/snapshots/test__from_fixtures@format__format_change.json.snap new file mode 100644 index 0000000..ebcbb22 --- /dev/null +++ b/tests/snapshots/test__from_fixtures@format__format_change.json.snap @@ -0,0 +1,22 @@ +--- +source: tests/test.rs +assertion_line: 12 +expression: diff +info: + lhs: + format: uuid + type: string + rhs: + format: date-time + type: string +input_file: tests/fixtures/format/format_change.json +--- +[ + Change { + path: "", + change: FormatChange { + old_format: "uuid", + new_format: "date-time", + }, + }, +] diff --git a/tests/snapshots/test__from_fixtures@format__format_remove.json.snap b/tests/snapshots/test__from_fixtures@format__format_remove.json.snap new file mode 100644 index 0000000..6bac7ff --- /dev/null +++ b/tests/snapshots/test__from_fixtures@format__format_remove.json.snap @@ -0,0 +1,20 @@ +--- +source: tests/test.rs +assertion_line: 12 +expression: diff +info: + lhs: + format: uri + type: string + rhs: + type: string +input_file: tests/fixtures/format/format_remove.json +--- +[ + Change { + path: "", + change: FormatRemove { + removed: "uri", + }, + }, +] diff --git a/tests/snapshots/test__from_fixtures@format__format_unchanged.json.snap b/tests/snapshots/test__from_fixtures@format__format_unchanged.json.snap new file mode 100644 index 0000000..9de69cd --- /dev/null +++ b/tests/snapshots/test__from_fixtures@format__format_unchanged.json.snap @@ -0,0 +1,14 @@ +--- +source: tests/test.rs +assertion_line: 12 +expression: diff +info: + lhs: + format: date + type: string + rhs: + format: date + type: string +input_file: tests/fixtures/format/format_unchanged.json +--- +[]