Skip to content

Commit 1d60302

Browse files
author
Pascal Post
committed
boolean logic added
1 parent fd56a95 commit 1d60302

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ The validator currently uses C++ regex implementation for pattern matching, requ
2222
- [ ] draft-07 tests
2323
- [x] additionalItems.json
2424
- [x] additionalProperties.json
25-
- [ ] allOf.json
26-
- [ ] anyOf.json
27-
- [ ] boolean_schema.json
25+
- [x] allOf.json
26+
- [x] anyOf.json
27+
- [x] boolean_schema.json
2828
- [x] const.json
2929
- [ ] contains.json
3030
- [ ] default.json
@@ -46,8 +46,8 @@ The validator currently uses C++ regex implementation for pattern matching, requ
4646
- [x] minProperties.json
4747
- [x] minimum.json
4848
- [x] multipleOf.json
49-
- [ ] not.json
50-
- [ ] oneOf.json
49+
- [x] not.json
50+
- [x] oneOf.json
5151
- [x] pattern.json
5252
- [x] patternProperties.json
5353
- [x] properties.json

src/boolean_logic.zig

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,72 @@ pub fn checks(node: std.json.ObjectMap, data: std.json.Value, stack: *Stack, col
2323
}
2424
}
2525

26+
if (node.get("anyOf")) |anyOf| {
27+
std.debug.assert(anyOf == .array);
28+
29+
try stack.pushPath("anyOf");
30+
defer stack.pop();
31+
32+
var valid = false;
33+
for (anyOf.array.items, 0..) |item, idx| {
34+
try stack.pushIndex(idx);
35+
defer stack.pop();
36+
37+
if (try schema.checks(item, data, stack, null)) {
38+
valid = true;
39+
break;
40+
}
41+
}
42+
43+
if (!valid) {
44+
if (collect_errors) |errors| {
45+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = "None of anyOf valid." });
46+
} else return false;
47+
}
48+
}
49+
50+
if (node.get("oneOf")) |oneOf| {
51+
std.debug.assert(oneOf == .array);
52+
53+
try stack.pushPath("oneOf");
54+
defer stack.pop();
55+
56+
var valid_idx: ?usize = null;
57+
for (oneOf.array.items, 0..) |item, idx| {
58+
try stack.pushIndex(idx);
59+
defer stack.pop();
60+
61+
if (try schema.checks(item, data, stack, null)) {
62+
if (valid_idx) |first_valid_idx| {
63+
if (collect_errors) |errors| {
64+
const msg = try std.fmt.allocPrint(errors.arena.allocator(), "oneOf valid for more than one schemas: stopped checking after valid schemas ({}, {}).", .{ first_valid_idx, idx });
65+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = msg });
66+
} else return false;
67+
}
68+
69+
valid_idx = idx;
70+
}
71+
}
72+
73+
if (valid_idx == null) {
74+
if (collect_errors) |errors| {
75+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = "None of oneOf valid." });
76+
} else return false;
77+
}
78+
}
79+
80+
if (node.get("not")) |not| {
81+
std.debug.assert(not == .object or not == .bool);
82+
83+
try stack.pushPath("not");
84+
defer stack.pop();
85+
86+
if (try schema.checks(not, data, stack, null)) {
87+
if (collect_errors) |errors| {
88+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = "Failed required unsuccessfull validation against schema specified as \"not\"." });
89+
} else return false;
90+
}
91+
}
92+
2693
return if (collect_errors) |errors| errors.empty() else true;
2794
}

src/test_suite.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ test "run test suite" {
5757
"properties.json",
5858
"enum.json",
5959
"uniqueItems.json",
60-
// "allOf.json",
60+
"anyOf.json",
61+
"boolean_schema.json",
62+
"oneOf.json",
63+
"allOf.json",
64+
"not.json",
6165
// "ref.json",
6266
// "WIP.json",
6367
};

0 commit comments

Comments
 (0)