Skip to content

Commit b2397fb

Browse files
authored
feat: Support format (#45)
Adds support for the `format` validation keyword. Additions of, and changes to, `format`s are considered breaking. Removals are not breaking.
1 parent c3f738a commit b2397fb

10 files changed

+144
-0
lines changed

src/diff_walker.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,37 @@ impl<F: FnMut(Change)> DiffWalker<F> {
356356
Ok(())
357357
}
358358

359+
fn diff_format(&mut self, json_path: &str, lhs: &mut SchemaObject, rhs: &mut SchemaObject) {
360+
match (&lhs.format, &rhs.format) {
361+
(Some(lhs_fmt), Some(rhs_fmt)) if lhs_fmt != rhs_fmt => {
362+
(self.cb)(Change {
363+
path: json_path.to_owned(),
364+
change: ChangeKind::FormatChange {
365+
old_format: lhs_fmt.clone(),
366+
new_format: rhs_fmt.clone(),
367+
},
368+
});
369+
}
370+
(Some(removed_fmt), None) => {
371+
(self.cb)(Change {
372+
path: json_path.to_owned(),
373+
change: ChangeKind::FormatRemove {
374+
removed: removed_fmt.clone(),
375+
},
376+
});
377+
}
378+
(None, Some(added_fmt)) => {
379+
(self.cb)(Change {
380+
path: json_path.to_owned(),
381+
change: ChangeKind::FormatAdd {
382+
added: added_fmt.clone(),
383+
},
384+
});
385+
}
386+
_ => {} // No change or both None
387+
}
388+
}
389+
359390
fn resolve_references(
360391
&self,
361392
lhs: &mut SchemaObject,
@@ -464,6 +495,7 @@ impl<F: FnMut(Change)> DiffWalker<F> {
464495
self.diff_instance_types(json_path, lhs, rhs);
465496
}
466497
self.diff_const(json_path, lhs, rhs);
498+
self.diff_format(json_path, lhs, rhs);
467499
// If we split the types, we don't want to compare type-specific properties
468500
// because they are already compared in the `Self::diff_any_of`
469501
if !is_lhs_split && !is_rhs_split {

src/types.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ pub enum ChangeKind {
107107
/// The property that is now required
108108
property: String,
109109
},
110+
/// A format constraint has been added.
111+
FormatAdd {
112+
/// The format that was added.
113+
added: String,
114+
},
115+
/// A format constraint has been removed.
116+
FormatRemove {
117+
/// The format that was removed.
118+
removed: String,
119+
},
120+
/// A format constraint has been changed.
121+
FormatChange {
122+
/// The old format value.
123+
old_format: String,
124+
/// The new format value.
125+
new_format: String,
126+
},
110127
}
111128

112129
impl ChangeKind {
@@ -150,6 +167,9 @@ impl ChangeKind {
150167
Self::TupleChange { .. } => true,
151168
Self::RequiredRemove { .. } => false,
152169
Self::RequiredAdd { .. } => true,
170+
Self::FormatAdd { .. } => true,
171+
Self::FormatRemove { .. } => false,
172+
Self::FormatChange { .. } => true,
153173
}
154174
}
155175
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"lhs": { "type": "string" },
3+
"rhs": { "type": "string", "format": "email" }
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"lhs": { "type": "string", "format": "uuid" },
3+
"rhs": { "type": "string", "format": "date-time" }
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"lhs": { "type": "string", "format": "uri" },
3+
"rhs": { "type": "string" }
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"lhs": { "type": "string", "format": "date" },
3+
"rhs": { "type": "string", "format": "date" }
4+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: tests/test.rs
3+
assertion_line: 12
4+
expression: diff
5+
info:
6+
lhs:
7+
type: string
8+
rhs:
9+
format: email
10+
type: string
11+
input_file: tests/fixtures/format/format_add.json
12+
---
13+
[
14+
Change {
15+
path: "",
16+
change: FormatAdd {
17+
added: "email",
18+
},
19+
},
20+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
source: tests/test.rs
3+
assertion_line: 12
4+
expression: diff
5+
info:
6+
lhs:
7+
format: uuid
8+
type: string
9+
rhs:
10+
format: date-time
11+
type: string
12+
input_file: tests/fixtures/format/format_change.json
13+
---
14+
[
15+
Change {
16+
path: "",
17+
change: FormatChange {
18+
old_format: "uuid",
19+
new_format: "date-time",
20+
},
21+
},
22+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
source: tests/test.rs
3+
assertion_line: 12
4+
expression: diff
5+
info:
6+
lhs:
7+
format: uri
8+
type: string
9+
rhs:
10+
type: string
11+
input_file: tests/fixtures/format/format_remove.json
12+
---
13+
[
14+
Change {
15+
path: "",
16+
change: FormatRemove {
17+
removed: "uri",
18+
},
19+
},
20+
]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
source: tests/test.rs
3+
assertion_line: 12
4+
expression: diff
5+
info:
6+
lhs:
7+
format: date
8+
type: string
9+
rhs:
10+
format: date
11+
type: string
12+
input_file: tests/fixtures/format/format_unchanged.json
13+
---
14+
[]

0 commit comments

Comments
 (0)