discord.zig/src/structures/partial.zig
2024-12-04 20:28:36 -05:00

41 lines
1.7 KiB
Zig

const std = @import("std");
pub fn Partial(comptime T: type) type {
const info = @typeInfo(T);
switch (info) {
.@"struct" => |s| {
comptime var fields: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{};
inline for (s.fields) |field| {
if (field.is_comptime) {
@compileError("Cannot make Partial of " ++ @typeName(T) ++ ", it has a comptime field " ++ field.name);
}
const optional_type = switch (@typeInfo(field.type)) {
.optional => field.type,
else => ?field.type,
};
const default_value: optional_type = null;
const aligned_ptr: *align(field.alignment) const anyopaque = @alignCast(@ptrCast(&default_value));
const optional_field: [1]std.builtin.Type.StructField = [_]std.builtin.Type.StructField{.{
.alignment = field.alignment,
.default_value = aligned_ptr,
.is_comptime = false,
.name = field.name,
.type = optional_type,
}};
fields = fields ++ optional_field;
}
const partial_type_info: std.builtin.Type = .{ .@"struct" = .{
.backing_integer = s.backing_integer,
.decls = &[_]std.builtin.Type.Declaration{},
.fields = fields,
.is_tuple = s.is_tuple,
.layout = s.layout,
} };
return @Type(partial_type_info);
},
else => @compileError("Cannot make Partial of " ++ @typeName(T) ++
", the type must be a struct"),
}
unreachable;
}