Deduplicate union fields

This commit is contained in:
jaina heartles 2022-12-16 01:03:23 -08:00
parent 8b1ff1149f
commit cd311cfa3c

View file

@ -82,39 +82,42 @@ const DynamicField = struct {
};
pub const SerializationOptions = struct {
embed_unions: bool,
isScalar: fn (type) bool,
};
pub const default_options = SerializationOptions{
.embed_unions = true,
.isScalar = defaultIsScalar,
};
fn StaticIntermediary(comptime Result: type, comptime From: type, comptime options: SerializationOptions) type {
const field_refs = getStaticFieldList(Result, &.{}, options);
var fields: [field_refs.len + 1]std.builtin.Type.StructField = undefined;
for (field_refs) |ref, i| {
fields[i] = .{
.name = util.comptimeJoin(".", ref),
// avert compiler crash by having at least one field
var fields = [_]std.builtin.Type.StructField{.{
.name = "__dummy",
.default_value = &{},
.field_type = void,
.is_comptime = false,
.alignment = 0,
}} ** (field_refs.len + 1);
var count: usize = 1;
outer: for (field_refs) |ref| {
const name = util.comptimeJoin(".", ref);
for (fields[0..count]) |f| if (std.mem.eql(u8, f.name, name)) continue :outer;
fields[count] = .{
.name = name,
.field_type = ?From,
.default_value = &@as(?From, null),
.is_comptime = false,
.alignment = @alignOf(?From),
};
count += 1;
}
fields[fields.len - 1] = .{
.name = "__dummy",
.default_value = &1,
.field_type = usize,
.is_comptime = false,
.alignment = @alignOf(usize),
};
return @Type(.{ .Struct = .{
.layout = .Auto,
.fields = &fields,
.fields = fields[0..count],
.decls = &.{},
.is_tuple = false,
} });
@ -123,28 +126,33 @@ fn StaticIntermediary(comptime Result: type, comptime From: type, comptime optio
fn DynamicIntermediary(comptime Result: type, comptime From: type, comptime options: SerializationOptions) type {
const field_refs = getDynamicFieldList(Result, &.{}, options);
var fields: [field_refs.len + 1]std.builtin.Type.StructField = undefined;
for (field_refs) |f, i| {
const T = std.ArrayListUnmanaged(Intermediary(f.child_type, From, options));
fields[i] = .{
.name = util.comptimeJoin(".", f.ref),
var fields = [_]std.builtin.Type.StructField{.{
.name = "__dummy",
.default_value = &{},
.field_type = void,
.is_comptime = false,
.alignment = 0,
}} ** (field_refs.len + 1);
var count: usize = 1;
outer: for (field_refs) |ref| {
const name = util.comptimeJoin(".", ref.ref);
for (fields[0..count]) |f| if (std.mem.eql(u8, f.name, name)) continue :outer;
const T = std.ArrayListUnmanaged(Intermediary(ref.child_type, From, options));
fields[count] = .{
.name = name,
.default_value = &T{},
.field_type = T,
.is_comptime = false,
.alignment = @alignOf(T),
};
count += 1;
}
fields[fields.len - 1] = .{
.name = "__dummy",
.default_value = &1,
.field_type = usize,
.is_comptime = false,
.alignment = @alignOf(usize),
};
return @Type(.{ .Struct = .{
.layout = .Auto,
.fields = &fields,
.fields = fields[0..count],
.decls = &.{},
.is_tuple = false,
} });