Tagged Union - Dynamic field selection

Hi all!

I’m looking to make a tagged union, and set the union based on the type, that I would know at runtime. Here is some code (doesn’t compile) that represents what I’m trying to do. I’m sure I’m just missing something simple, but I cannot get it to work for the life of me!

const myType = union(enum) {
    i8: i8,
    u32: u32,
};

pub fn foo(T: type, v: T) !myType {
    inline for (std.meta.fields(myType)) |fieldInfo| {
        if (fieldInfo.type == T) {
            // Something like this:
            return myType{ .@field(myType, fieldInfo.name) = 5};

            // Or this
            var t: myType = .{ .i8 = 5 };
            @field(t, fieldInfo.name) = v;
            return t;
        }
    }
    return error.UnsupportedType;
}


pub fn main() !void {
    switch (try foo(u32, 6700)) {
            else => |v| try stdout.print("foo(i8, 8) = {any}\n\n", .{v}),
    }
}

what you missed is @unionInit buildin

const std = @import("std");

const myType = union(enum) {
    i8: i8,
    u32: u32,
};

pub fn foo(T: type, v: T) !myType {
    inline for (std.meta.fields(myType)) |fieldInfo| {
        if (fieldInfo.type == T) {
            // Something like this:
            return @unionInit(myType, fieldInfo.name, v);
        }
    }
    return error.UnsupportedType;
}

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    switch (try foo(u32, 6700)) {
        else => |v| try stdout.print("foo(i8, 8) = {any}\n\n", .{v}),
    }
}
6 Likes

Oh my gosh! I went through every single builtin, and somehow managed to miss that one. Thank you so much!

2 Likes