From 4b1a3ff48ae47cadc249f06038ce59eed173a485 Mon Sep 17 00:00:00 2001 From: Tarry Singh Date: Wed, 1 Jan 2025 13:35:17 +0000 Subject: [PATCH] Add union support to mapping helpers in zml/meta.zig. --- zml/meta.zig | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/zml/meta.zig b/zml/meta.zig index 483b03a..b5b5e8e 100644 --- a/zml/meta.zig +++ b/zml/meta.zig @@ -61,6 +61,31 @@ pub fn MapType(From: type, To: type) type { .is_tuple = struct_infos.is_tuple, } }); }, + .@"union" => |union_info| { + const fields = union_info.fields; + var same: bool = true; + var union_fields: [fields.len]std.builtin.Type.UnionField = undefined; + for (union_fields[0..], fields) |*union_field, field| { + const R = map(field.type); + if (R == field.type) { + union_field.* = field; + } else { + union_field.* = .{ + .name = field.name, + .type = R, + .alignment = @alignOf(R), + }; + same = false; + } + } + if (same) return T; + return @Type(.{ .@"union" = .{ + .layout = .auto, + .tag_type = union_info.tag_type, + .fields = union_fields[0..], + .decls = &.{}, + } }); + }, .array => |arr_info| [arr_info.len]map(arr_info.child), .pointer => |ptr_info| switch (ptr_info.size) { .slice => if (ptr_info.is_const) @@ -172,6 +197,14 @@ pub fn mapAlloc(comptime cb: anytype, allocator: std.mem.Allocator, ctx: FnParam else => @field(to, field.name) = @field(from, field.name), } }, + .@"union" => { + switch (from) { + inline else => |_, tag| { + to.* = @unionInit(ToStruct, @tagName(tag), undefined); + try mapAlloc(cb, allocator, ctx, @field(from, @tagName(tag)), &@field(to, @tagName(tag))); + }, + } + }, .array => for (from, to) |f, *t| { try mapAlloc(cb, allocator, ctx, f, t); }, @@ -202,7 +235,7 @@ pub fn mapAlloc(comptime cb: anytype, allocator: std.mem.Allocator, ctx: FnParam } else { to.* = null; }, - .int, .float, .@"enum", .@"union" => to.* = from, + .int, .float, .@"enum" => to.* = from, else => stdx.debug.compileError("zml.meta.mapAlloc doesn't support: {}", .{FromStruct}), } }