Skip to content

Commit f1c7458

Browse files
committed
add conditionals
1 parent 1d60302 commit f1c7458

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The validator currently uses C++ regex implementation for pattern matching, requ
3434
- [x] exclusiveMaximum.json
3535
- [x] exclusiveMinimum.json
3636
- [ ] format.json
37-
- [ ] if-then-else.json
37+
- [x] if-then-else.json
3838
- [ ] infinite-loop-detection.json
3939
- [x] items.json
4040
- [x] maxItems.json

src/conditional.zig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const std = @import("std");
2+
const Stack = @import("stack.zig").Stack;
3+
const Errors = @import("errors.zig").Errors;
4+
const schema = @import("schema.zig");
5+
6+
pub fn checks(node: std.json.ObjectMap, data: std.json.Value, stack: *Stack, collect_errors: ?*Errors) !bool {
7+
if (node.get("if")) |if_schema| {
8+
if (try schema.checks(if_schema, data, stack, null)) {
9+
if (node.get("then")) |then_schema| {
10+
if (!try schema.checks(then_schema, data, stack, null)) {
11+
if (collect_errors) |errors| {
12+
try stack.pushPath("then");
13+
defer stack.pop();
14+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = "Invalid for \"then\" condition." });
15+
} else return false;
16+
}
17+
}
18+
} else {
19+
if (node.get("else")) |else_schema| {
20+
if (!try schema.checks(else_schema, data, stack, null)) {
21+
if (collect_errors) |errors| {
22+
try stack.pushPath("else");
23+
defer stack.pop();
24+
try errors.append(.{ .path = try stack.constructPath(errors.arena.allocator()), .msg = "Invalid for \"else\" condition" });
25+
} else return false;
26+
}
27+
}
28+
}
29+
}
30+
31+
return true;
32+
}

src/schema.zig

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,28 @@ const string = @import("string.zig");
88
const array = @import("array.zig");
99
const json_pointer = @import("json_pointer.zig");
1010
const boolean_logic = @import("boolean_logic.zig");
11+
const conditional = @import("conditional.zig");
1112

1213
pub const ErrorSet = std.mem.Allocator.Error || std.fmt.ParseIntError || json_pointer.Error;
1314

1415
pub fn checksFromObject(schema: std.json.ObjectMap, data: std.json.Value, stack: *Stack, collect_errors: ?*Errors) ErrorSet!bool {
15-
var valid = try generic.checks(schema, data, stack, collect_errors);
16-
if (!valid and collect_errors == null) return false;
16+
if (!try generic.checks(schema, data, stack, collect_errors) and collect_errors == null) return false;
1717

18-
valid = switch (data) {
18+
if (!switch (data) {
1919
.integer => |i| try numeric.checks(i64, schema, i, stack, collect_errors),
2020
.float => |f| try numeric.checks(f64, schema, f, stack, collect_errors),
2121
.number_string => unreachable,
2222
.string => |str| try string.checks(schema, str, stack, collect_errors),
2323
.object => try object.checks(schema, data, stack, collect_errors),
2424
.array => try array.checks(schema, data, stack, collect_errors),
2525
else => true,
26-
} and valid;
27-
if (!valid and collect_errors == null) return false;
26+
} and collect_errors == null) return false;
2827

29-
valid = try boolean_logic.checks(schema, data, stack, collect_errors) and valid;
28+
if (!try conditional.checks(schema, data, stack, collect_errors) and collect_errors == null) return false;
3029

31-
return valid;
30+
if (!try boolean_logic.checks(schema, data, stack, collect_errors) and collect_errors == null) return false;
31+
32+
return if (collect_errors) |errors| errors.empty() else true;
3233
}
3334

3435
pub fn checks(schema: std.json.Value, data: std.json.Value, stack: *Stack, collect_errors: ?*Errors) ErrorSet!bool {

src/test_suite.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ test "run test suite" {
6262
"oneOf.json",
6363
"allOf.json",
6464
"not.json",
65+
"if-then-else.json",
6566
// "ref.json",
6667
// "WIP.json",
6768
};

0 commit comments

Comments
 (0)