Add tests for deserialization
This commit is contained in:
parent
aa632ace8b
commit
c7dcded04a
1 changed files with 95 additions and 72 deletions
|
@ -207,7 +207,7 @@ fn DeserializerContext(comptime Result: type, comptime From: type, comptime Cont
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(self: *@This()) !Result {
|
pub fn finish(self: *@This()) !Result {
|
||||||
return (try self.deserialize(Result, &.{})).?;
|
return (try self.deserialize(Result, &.{})) orelse error.MissingField;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getSerializedField(self: *@This(), comptime field_ref: FieldRef) ?From {
|
fn getSerializedField(self: *@This(), comptime field_ref: FieldRef) ?From {
|
||||||
|
@ -233,7 +233,7 @@ fn DeserializerContext(comptime Result: type, comptime From: type, comptime Cont
|
||||||
const maybe_value = try self.deserialize(F, new_field_ref);
|
const maybe_value = try self.deserialize(F, new_field_ref);
|
||||||
if (maybe_value) |value| {
|
if (maybe_value) |value| {
|
||||||
// TODO: errdefer cleanup
|
// TODO: errdefer cleanup
|
||||||
if (result != null) return error.DuplicateUnionField;
|
if (result != null) return error.DuplicateUnionMember;
|
||||||
result = @unionInit(T, field.name, value);
|
result = @unionInit(T, field.name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,12 +258,10 @@ fn DeserializerContext(comptime Result: type, comptime From: type, comptime Cont
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
any_missing = true;
|
any_missing = true;
|
||||||
std.debug.print("\nMissing field {s}\n", .{util.comptimeJoin(".", new_field_ref)});
|
|
||||||
//return error.MissingStructField;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (any_missing) {
|
if (any_missing) {
|
||||||
return if (any_explicit) error.MissingStructField else null;
|
return if (any_explicit) error.MissingField else null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -292,85 +290,110 @@ const bool_map = std.ComptimeStringMap(bool, .{
|
||||||
.{ "0", false },
|
.{ "0", false },
|
||||||
});
|
});
|
||||||
|
|
||||||
test {
|
test "Deserializer" {
|
||||||
const T = struct {
|
|
||||||
foo: usize,
|
|
||||||
bar: bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
const TDefault = struct {
|
|
||||||
foo: usize = 0,
|
|
||||||
bar: bool = false,
|
|
||||||
};
|
|
||||||
_ = TDefault;
|
|
||||||
|
|
||||||
|
// Happy case - simple
|
||||||
{
|
{
|
||||||
|
const T = struct { foo: usize, bar: bool };
|
||||||
|
|
||||||
var ds = Deserializer(T, []const u8){};
|
var ds = Deserializer(T, []const u8){};
|
||||||
try ds.setSerializedField("foo", "123");
|
try ds.setSerializedField("foo", "123");
|
||||||
try ds.setSerializedField("bar", "true");
|
try ds.setSerializedField("bar", "true");
|
||||||
try std.testing.expectEqual(T{ .foo = 123, .bar = true }, try ds.finish());
|
try std.testing.expectEqual(T{ .foo = 123, .bar = true }, try ds.finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns error if nonexistent field set
|
||||||
{
|
{
|
||||||
|
const T = struct { foo: usize, bar: bool };
|
||||||
|
|
||||||
var ds = Deserializer(T, []const u8){};
|
var ds = Deserializer(T, []const u8){};
|
||||||
try ds.setSerializedField("foo", "123");
|
try std.testing.expectError(error.UnknownField, ds.setSerializedField("baz", "123"));
|
||||||
try std.testing.expectError(error.MissingStructField, ds.finish());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//const int = Intermediary(T, QueryStringOptions){
|
// Substruct dereferencing
|
||||||
//.age = "123",
|
{
|
||||||
//.@"sub_struct.foo" = "abc",
|
const T = struct {
|
||||||
//.@"sub_struct.bar" = "abc",
|
foo: struct { bar: bool, baz: bool },
|
||||||
//.@"foo_union" = "abc",
|
};
|
||||||
//};
|
|
||||||
//std.debug.print("{any}\n", .{int});
|
|
||||||
//std.debug.print("{any}\n", .{deserialize(T, QueryStringOptions, &.{}, int)});
|
|
||||||
|
|
||||||
//const int2 = Intermediary(T, FormDataOptions){
|
var ds = Deserializer(T, []const u8){};
|
||||||
//.age = .{ .value = "123" },
|
try ds.setSerializedField("foo.bar", "true");
|
||||||
//.@"sub_struct.foo" = .{ .value = "123" },
|
try ds.setSerializedField("foo.baz", "true");
|
||||||
//.@"sub_struct.bar" = .{ .value = "123" },
|
try std.testing.expectEqual(T{ .foo = .{ .bar = true, .baz = true } }, try ds.finish());
|
||||||
////.@"foo_union" = .{
|
}
|
||||||
//.value = "abc",
|
|
||||||
//},
|
|
||||||
//};
|
|
||||||
//std.debug.print("{any}\n", .{int2});
|
|
||||||
//
|
|
||||||
|
|
||||||
// const T = struct {
|
// Union embedding
|
||||||
// age: usize,
|
{
|
||||||
// sub_struct: ?struct {
|
const T = struct {
|
||||||
// x: union(enum) {
|
foo: union(enum) { bar: bool, baz: bool },
|
||||||
// foo: []const u8,
|
};
|
||||||
// bar: []const u8,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// sub_union: union(enum) {
|
|
||||||
// foo_union: []const u8,
|
|
||||||
// bar_union: []const u8,
|
|
||||||
// },
|
|
||||||
// time: ?@import("./DateTime.zig"),
|
|
||||||
// };
|
|
||||||
// inline for (comptime getRecursiveFieldList(T, &.{}, .{})) |list| {
|
|
||||||
// std.debug.print("{s}\n", .{util.comptimeJoin(".", list)});
|
|
||||||
// }
|
|
||||||
// // var ds = Deserializer(struct {
|
|
||||||
// age: usize,
|
|
||||||
// sub_struct: ?struct {
|
|
||||||
// x: union(enum) {
|
|
||||||
// foo: []const u8,
|
|
||||||
// bar: []const u8,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// sub_union: union(enum) {
|
|
||||||
// foo_union: []const u8,
|
|
||||||
// bar_union: []const u8,
|
|
||||||
// },
|
|
||||||
// time: ?@import("./DateTime.zig"),
|
|
||||||
// }, []const u8){ .context = .{} };
|
|
||||||
//try ds.setSerializedField("age", "123");
|
|
||||||
//try ds.setSerializedField("foo_union", "123");
|
|
||||||
//try ds.setSerializedField("sub_struct.foo", "123");
|
|
||||||
//try ds.setSerializedField("sub_struct.bar", "123");
|
|
||||||
|
|
||||||
//std.debug.print("{any}\n", .{try ds.finish()});
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try ds.setSerializedField("bar", "true");
|
||||||
|
try std.testing.expectEqual(T{ .foo = .{ .bar = true } }, try ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns error if multiple union fields specified
|
||||||
|
{
|
||||||
|
const T = struct {
|
||||||
|
foo: union(enum) { bar: bool, baz: bool },
|
||||||
|
};
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try ds.setSerializedField("bar", "true");
|
||||||
|
try ds.setSerializedField("baz", "true");
|
||||||
|
try std.testing.expectError(error.DuplicateUnionMember, ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uses default values if fields aren't provided
|
||||||
|
{
|
||||||
|
const T = struct { foo: usize = 123, bar: bool = true };
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try std.testing.expectEqual(T{ .foo = 123, .bar = true }, try ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns an error if fields aren't provided and no default exists
|
||||||
|
{
|
||||||
|
const T = struct { foo: usize, bar: bool };
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try ds.setSerializedField("foo", "123");
|
||||||
|
try std.testing.expectError(error.MissingField, ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles optional containers
|
||||||
|
{
|
||||||
|
const T = struct {
|
||||||
|
foo: ?struct { bar: usize = 3, baz: usize } = null,
|
||||||
|
qux: ?union(enum) { quux: usize } = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try std.testing.expectEqual(T{ .foo = null, .qux = null }, try ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const T = struct {
|
||||||
|
foo: ?struct { bar: usize = 3, baz: usize } = null,
|
||||||
|
qux: ?union(enum) { quux: usize } = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try ds.setSerializedField("foo.baz", "3");
|
||||||
|
try ds.setSerializedField("quux", "3");
|
||||||
|
try std.testing.expectEqual(T{ .foo = .{ .bar = 3, .baz = 3 }, .qux = .{ .quux = 3 } }, try ds.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const T = struct {
|
||||||
|
foo: ?struct { bar: usize = 3, baz: usize } = null,
|
||||||
|
qux: ?union(enum) { quux: usize } = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var ds = Deserializer(T, []const u8){};
|
||||||
|
try ds.setSerializedField("foo.bar", "3");
|
||||||
|
try ds.setSerializedField("quux", "3");
|
||||||
|
try std.testing.expectError(error.MissingField, ds.finish());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue