- Added comprehensive module-level documentation explaining architecture - Added doc comments to all public and key internal functions - Improved inline comments focusing on 'why' not 'what' - Updated CLAUDE.md with code comments rule - Bump version to 0.2.0
280 lines
12 KiB
Zig
280 lines
12 KiB
Zig
//! Auto-generated by pugz.compileTemplates()
|
|
//! Do not edit manually - regenerate by running: zig build
|
|
|
|
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const ArrayList = std.ArrayList(u8);
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Helpers
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
const esc_lut: [256]?[]const u8 = blk: {
|
|
var t: [256]?[]const u8 = .{null} ** 256;
|
|
t['&'] = "&";
|
|
t['<'] = "<";
|
|
t['>'] = ">";
|
|
t['"'] = """;
|
|
t['\''] = "'";
|
|
break :blk t;
|
|
};
|
|
|
|
fn esc(o: *ArrayList, a: Allocator, s: []const u8) Allocator.Error!void {
|
|
var i: usize = 0;
|
|
for (s, 0..) |c, j| {
|
|
if (esc_lut[c]) |e| {
|
|
if (j > i) try o.appendSlice(a, s[i..j]);
|
|
try o.appendSlice(a, e);
|
|
i = j + 1;
|
|
}
|
|
}
|
|
if (i < s.len) try o.appendSlice(a, s[i..]);
|
|
}
|
|
|
|
fn truthy(v: anytype) bool {
|
|
return switch (@typeInfo(@TypeOf(v))) {
|
|
.bool => v,
|
|
.optional => v != null,
|
|
.pointer => |p| if (p.size == .slice) v.len > 0 else true,
|
|
.int, .comptime_int => v != 0,
|
|
else => true,
|
|
};
|
|
}
|
|
|
|
var int_buf: [32]u8 = undefined;
|
|
|
|
fn strVal(v: anytype) []const u8 {
|
|
const T = @TypeOf(v);
|
|
switch (@typeInfo(T)) {
|
|
.pointer => |p| switch (p.size) {
|
|
.slice => return v,
|
|
.one => {
|
|
// For pointer-to-array, slice it
|
|
const child_info = @typeInfo(p.child);
|
|
if (child_info == .array) {
|
|
const arr_info = child_info.array;
|
|
const ptr: [*]const arr_info.child = @ptrCast(v);
|
|
return ptr[0..arr_info.len];
|
|
}
|
|
return strVal(v.*);
|
|
},
|
|
else => @compileError("unsupported pointer type"),
|
|
},
|
|
.array => @compileError("arrays must be passed by pointer"),
|
|
.int, .comptime_int => return std.fmt.bufPrint(&int_buf, "{d}", .{v}) catch "0",
|
|
.optional => return if (v) |val| strVal(val) else "",
|
|
else => @compileError("strVal: unsupported type " ++ @typeName(T)),
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Templates
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
pub fn simple_2(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<div><h1 class=\"header\">");
|
|
try esc(&o, a, strVal(@field(d, "header")));
|
|
try o.appendSlice(a, "</h1><h2 class=\"header2\">");
|
|
try esc(&o, a, strVal(@field(d, "header2")));
|
|
try o.appendSlice(a, "</h2><h3 class=\"header3\">");
|
|
try esc(&o, a, strVal(@field(d, "header3")));
|
|
try o.appendSlice(a, "</h3><h4 class=\"header4\">");
|
|
try esc(&o, a, strVal(@field(d, "header4")));
|
|
try o.appendSlice(a, "</h4><h5 class=\"header5\">");
|
|
try esc(&o, a, strVal(@field(d, "header5")));
|
|
try o.appendSlice(a, "</h5><h6 class=\"header6\">");
|
|
try esc(&o, a, strVal(@field(d, "header6")));
|
|
try o.appendSlice(a, "</h6><ul class=\"list\">");
|
|
for (@field(d, "list")) |item| {
|
|
try o.appendSlice(a, "<li class=\"item\">");
|
|
try esc(&o, a, strVal(item));
|
|
try o.appendSlice(a, "</li>");
|
|
}
|
|
try o.appendSlice(a, "</ul></div>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn simple_1(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<div class=\"simple-1\" style=\"background-color: blue; border: 1px solid black\"><div class=\"colors\"><span class=\"hello\">Hello ");
|
|
try esc(&o, a, strVal(@field(d, "name")));
|
|
try o.appendSlice(a, "!<strong>You have ");
|
|
try esc(&o, a, strVal(@field(d, "messageCount")));
|
|
try o.appendSlice(a, " messages!</strong></span>");
|
|
if (@hasField(@TypeOf(d), "colors") and truthy(@field(d, "colors"))) {
|
|
try o.appendSlice(a, "<ul>");
|
|
for (@field(d, "colors")) |color| {
|
|
try o.appendSlice(a, "<li class=\"color\">");
|
|
try esc(&o, a, strVal(color));
|
|
try o.appendSlice(a, "</li>");
|
|
}
|
|
try o.appendSlice(a, "</ul>");
|
|
} else {
|
|
try o.appendSlice(a, "<div>No colors!</div>");
|
|
}
|
|
try o.appendSlice(a, "</div>");
|
|
if (@hasField(@TypeOf(d), "primary") and truthy(@field(d, "primary"))) {
|
|
try o.appendSlice(a, "<button class=\"primary\" type=\"button\">Click me!</button>");
|
|
} else {
|
|
try o.appendSlice(a, "<button class=\"secondary\" type=\"button\">Click me!</button>");
|
|
}
|
|
try o.appendSlice(a, "</div>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn simple_0(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<h1>Hello, ");
|
|
try esc(&o, a, strVal(@field(d, "name")));
|
|
try o.appendSlice(a, "</h1>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn projects_escaped(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<!DOCTYPE html><html><head><title>");
|
|
try esc(&o, a, strVal(@field(d, "title")));
|
|
try o.appendSlice(a, "</title></head><body><p>");
|
|
try esc(&o, a, strVal(@field(d, "text")));
|
|
try o.appendSlice(a, "</p>");
|
|
if (@field(d, "projects").len > 0) {
|
|
for (@field(d, "projects")) |project| {
|
|
try o.appendSlice(a, "<a");
|
|
try o.appendSlice(a, " href=\"");
|
|
try o.appendSlice(a, strVal(project.url));
|
|
try o.appendSlice(a, "\"");
|
|
try o.appendSlice(a, "></a><project class=\"name\"></project><p>");
|
|
try esc(&o, a, strVal(project.description));
|
|
try o.appendSlice(a, "</p>");
|
|
}
|
|
} else {
|
|
try o.appendSlice(a, "<p>No projects</p>");
|
|
}
|
|
try o.appendSlice(a, "</body></html>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn friends(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\" /><title>Friends</title></head><body><div class=\"friends\">");
|
|
for (@field(d, "friends")) |friend| {
|
|
try o.appendSlice(a, "<div class=\"friend\"><ul><li>Name: ");
|
|
try esc(&o, a, strVal(friend.name));
|
|
try o.appendSlice(a, "</li><li>Balance: ");
|
|
try esc(&o, a, strVal(friend.balance));
|
|
try o.appendSlice(a, "</li><li>Age: ");
|
|
try esc(&o, a, strVal(friend.age));
|
|
try o.appendSlice(a, "</li><li>Address: ");
|
|
try esc(&o, a, strVal(friend.address));
|
|
try o.appendSlice(a, "</li><li>Image:<img");
|
|
try o.appendSlice(a, " src=\"");
|
|
try o.appendSlice(a, strVal(friend.picture));
|
|
try o.appendSlice(a, "\"");
|
|
try o.appendSlice(a, " /></li><li>Company: ");
|
|
try esc(&o, a, strVal(friend.company));
|
|
try o.appendSlice(a, "</li><li>Email:<a");
|
|
try o.appendSlice(a, " href=\"");
|
|
try o.appendSlice(a, strVal(friend.emailHref));
|
|
try o.appendSlice(a, "\"");
|
|
try o.appendSlice(a, "></a><friend class=\"email\"></friend></li><li>About: ");
|
|
try esc(&o, a, strVal(friend.about));
|
|
try o.appendSlice(a, "</li>");
|
|
if (truthy(friend.tags)) {
|
|
try o.appendSlice(a, "<li>Tags:<ul>");
|
|
for (if (@typeInfo(@TypeOf(friend.tags)) == .optional) (friend.tags orelse &.{}) else friend.tags) |tag| {
|
|
try o.appendSlice(a, "<li>");
|
|
try esc(&o, a, strVal(tag));
|
|
try o.appendSlice(a, "</li>");
|
|
}
|
|
try o.appendSlice(a, "</ul></li>");
|
|
}
|
|
if (truthy(friend.friends)) {
|
|
try o.appendSlice(a, "<li>Friends:<ul>");
|
|
for (if (@typeInfo(@TypeOf(friend.friends)) == .optional) (friend.friends orelse &.{}) else friend.friends) |subFriend| {
|
|
try o.appendSlice(a, "<li>");
|
|
try esc(&o, a, strVal(subFriend.name));
|
|
try o.appendSlice(a, " (");
|
|
try esc(&o, a, strVal(subFriend.id));
|
|
try o.appendSlice(a, ")</li>");
|
|
}
|
|
try o.appendSlice(a, "</ul></li>");
|
|
}
|
|
try o.appendSlice(a, "</ul></div>");
|
|
}
|
|
try o.appendSlice(a, "</div></body></html>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn search_results(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
try o.appendSlice(a, "<div class=\"search-results view-gallery\">");
|
|
for (@field(d, "searchRecords")) |searchRecord| {
|
|
try o.appendSlice(a, "<div class=\"search-item\"><div class=\"search-item-container drop-shadow\"><div class=\"img-container\"><img");
|
|
try o.appendSlice(a, " src=\"");
|
|
try o.appendSlice(a, strVal(searchRecord.imgUrl));
|
|
try o.appendSlice(a, "\"");
|
|
try o.appendSlice(a, " /></div><h4 class=\"title\"><a");
|
|
try o.appendSlice(a, " href=\"");
|
|
try o.appendSlice(a, strVal(searchRecord.viewItemUrl));
|
|
try o.appendSlice(a, "\"");
|
|
try o.appendSlice(a, ">");
|
|
try esc(&o, a, strVal(searchRecord.title));
|
|
try o.appendSlice(a, "</a></h4>");
|
|
try esc(&o, a, strVal(searchRecord.description));
|
|
if (truthy(searchRecord.featured)) {
|
|
try o.appendSlice(a, "<div>Featured!</div>");
|
|
}
|
|
if (truthy(searchRecord.sizes)) {
|
|
try o.appendSlice(a, "<div>Sizes available:<ul>");
|
|
for (if (@typeInfo(@TypeOf(searchRecord.sizes)) == .optional) (searchRecord.sizes orelse &.{}) else searchRecord.sizes) |size| {
|
|
try o.appendSlice(a, "<li>");
|
|
try esc(&o, a, strVal(size));
|
|
try o.appendSlice(a, "</li>");
|
|
}
|
|
try o.appendSlice(a, "</ul></div>");
|
|
}
|
|
try o.appendSlice(a, "</div></div>");
|
|
}
|
|
try o.appendSlice(a, "</div>");
|
|
return o.items;
|
|
}
|
|
|
|
pub fn if_expression(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|
var o: ArrayList = .empty;
|
|
for (@field(d, "accounts")) |account| {
|
|
try o.appendSlice(a, "<div>");
|
|
if (std.mem.eql(u8, strVal(account.status), "closed")) {
|
|
try o.appendSlice(a, "<div>Your account has been closed!</div>");
|
|
}
|
|
if (std.mem.eql(u8, strVal(account.status), "suspended")) {
|
|
try o.appendSlice(a, "<div>Your account has been temporarily suspended</div>");
|
|
}
|
|
if (std.mem.eql(u8, strVal(account.status), "open")) {
|
|
try o.appendSlice(a, "<div>Bank balance:");
|
|
if (truthy(account.negative)) {
|
|
try o.appendSlice(a, "<span class=\"negative\">");
|
|
try esc(&o, a, strVal(account.balanceFormatted));
|
|
try o.appendSlice(a, "</span>");
|
|
} else {
|
|
try o.appendSlice(a, "<span class=\"positive\">");
|
|
try esc(&o, a, strVal(account.balanceFormatted));
|
|
try o.appendSlice(a, "</span>");
|
|
}
|
|
try o.appendSlice(a, "</div>");
|
|
}
|
|
try o.appendSlice(a, "</div>");
|
|
}
|
|
return o.items;
|
|
}
|
|
|
|
pub const template_names = [_][]const u8{
|
|
"simple_2",
|
|
"simple_1",
|
|
"simple_0",
|
|
"projects_escaped",
|
|
"friends",
|
|
"search_results",
|
|
"if_expression",
|
|
};
|