Skip to content

Instantly share code, notes, and snippets.

@hauleth
Created January 10, 2024 16:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hauleth/59508f222a3f1ffd3ec4865825817323 to your computer and use it in GitHub Desktop.
Save hauleth/59508f222a3f1ffd3ec4865825817323 to your computer and use it in GitHub Desktop.
Zig template engine
const std = @import("std");
const Type = std.builtin.Type;
pub fn Templates(comptime entries: anytype) type {
const type_info = @typeInfo(@TypeOf(entries)).Struct;
var enum_fields: [type_info.fields.len]Type.EnumField = undefined;
for (type_info.fields, 0..) |field, idx| {
enum_fields[idx] = .{
.name = field.name,
.value = idx,
};
}
const enum_type = @Type(.{ .Enum = .{
.tag_type = usize,
.fields = &enum_fields,
.decls = &.{},
.is_exhaustive = true,
} });
return struct {
pub const Name = enum_type;
pub fn get(name: []const u8) ?Name {
return std.meta.stringToEnum(Name, name);
}
pub fn size(name: Name, args: anytype) u64 {
inline for (type_info.fields) |field| {
if (std.mem.eql(u8, @tagName(name), field.name)) {
const template = @field(entries, field.name);
return std.fmt.count(template, args);
}
}
unreachable;
}
pub fn write(name: Name, writer: anytype, args: anytype) !void {
inline for (type_info.fields) |field| {
if (std.mem.eql(u8, @tagName(name), field.name)) {
const template = @field(entries, field.name);
return std.fmt.format(writer, template, args);
}
}
}
pub fn allocPrint(name: Name, allocator: std.mem.Allocator, args: anytype) ![]u8 {
inline for (type_info.fields) |field| {
if (std.mem.eql(u8, name, field.name)) {
const template = @field(entries, field.name);
return std.fmt.allocPrint(allocator, template, args);
}
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment