Compare commits
No commits in common. "b314b0fd0f8f4690c780458817732f74f268104d" and "b807ff876853fb33697bbfb670a07faa4e724c2a" have entirely different histories.
b314b0fd0f
...
b807ff8768
1 changed files with 23 additions and 53 deletions
42
src/srf.zig
42
src/srf.zig
|
|
@ -459,9 +459,13 @@ pub const Record = struct {
|
||||||
inx = try self.setField(inx, f.name, f.type, f.default_value_ptr, field_val);
|
inx = try self.setField(inx, f.name, f.type, f.default_value_ptr, field_val);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.@"union" => {
|
.@"union" => |info| {
|
||||||
const active_tag_name = @tagName(val);
|
const active_tag_name = @tagName(val);
|
||||||
const key = if (@hasDecl(U, "srf_tag_field"))
|
comptime var has_decl = false;
|
||||||
|
inline for (info.decls) |d| {
|
||||||
|
if (comptime std.mem.eql(u8, "srf_tag_field", d.name)) has_decl = true;
|
||||||
|
}
|
||||||
|
const key = if (has_decl)
|
||||||
U.srf_tag_field
|
U.srf_tag_field
|
||||||
else
|
else
|
||||||
"active_tag";
|
"active_tag";
|
||||||
|
|
@ -519,10 +523,6 @@ pub const Record = struct {
|
||||||
|
|
||||||
/// Coerce Record to a type. Does not handle fields with arrays
|
/// Coerce Record to a type. Does not handle fields with arrays
|
||||||
pub fn to(self: Record, comptime T: type) !T {
|
pub fn to(self: Record, comptime T: type) !T {
|
||||||
const ti = @typeInfo(T);
|
|
||||||
|
|
||||||
switch (ti) {
|
|
||||||
.@"struct" => {
|
|
||||||
// SAFETY: all fields updated below or error is returned
|
// SAFETY: all fields updated below or error is returned
|
||||||
var obj: T = undefined;
|
var obj: T = undefined;
|
||||||
inline for (std.meta.fields(T)) |type_field| {
|
inline for (std.meta.fields(T)) |type_field| {
|
||||||
|
|
@ -541,27 +541,6 @@ pub const Record = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
},
|
|
||||||
.@"union" => {
|
|
||||||
const active_tag_name = if (@hasDecl(T, "srf_tag_field"))
|
|
||||||
T.srf_tag_field
|
|
||||||
else
|
|
||||||
"active_tag";
|
|
||||||
if (self.firstFieldByName(active_tag_name)) |srf_field| {
|
|
||||||
if (srf_field.value == null or srf_field.value.? != .string)
|
|
||||||
return error.ActiveTagValueMustBeAString;
|
|
||||||
const active_tag = srf_field.value.?.string;
|
|
||||||
inline for (std.meta.fields(T)) |f| {
|
|
||||||
if (std.mem.eql(u8, active_tag, f.name)) {
|
|
||||||
return @unionInit(T, f.name, try self.to(f.type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error.ActiveTagDoesNotExist;
|
|
||||||
} else return error.ActiveTagFieldNotFound;
|
|
||||||
},
|
|
||||||
else => @compileError("Deserialization not supported on " ++ @tagName(ti) ++ " types"),
|
|
||||||
}
|
|
||||||
return error.CoercionNotPossible;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1338,15 +1317,6 @@ test "unions" {
|
||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
try std.testing.expectEqualStrings(expect, compact_from);
|
try std.testing.expectEqualStrings(expect, compact_from);
|
||||||
|
|
||||||
var compact_reader = std.Io.Reader.fixed(expect);
|
|
||||||
const parsed = try parse(&compact_reader, std.testing.allocator, .{});
|
|
||||||
defer parsed.deinit();
|
|
||||||
|
|
||||||
const rec1 = try parsed.records.items[0].to(MixedData);
|
|
||||||
try std.testing.expectEqualDeep(data[0], rec1);
|
|
||||||
const rec2 = try parsed.records.items[1].to(MixedData);
|
|
||||||
try std.testing.expectEqualDeep(data[1], rec2);
|
|
||||||
}
|
}
|
||||||
test "compact format length-prefixed string as last field" {
|
test "compact format length-prefixed string as last field" {
|
||||||
// When a length-prefixed value is the last field on the line,
|
// When a length-prefixed value is the last field on the line,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue