srctree

Gregory Mullen parent 604694eb 3606156e
make buildable templates nullable

src/context.zig added: 30, removed: 21, total 9
@@ -57,7 +57,7 @@ pub fn sendPage(ctx: *Context, page: anytype) Error!void {
const loggedin = if (ctx.request.auth.valid()) "<a href=\"#\">Logged In</a>" else "Public";
const T = @TypeOf(page.*);
if (@hasField(T, "data") and @hasField(@TypeOf(page.data), "body_header")) {
page.data.body_header.nav.nav_auth = loggedin;
page.data.body_header.?.nav.?.nav_auth = loggedin;
}
 
const page_compiled = try page.build(ctx.alloc);
 
src/template-compiler.zig added: 30, removed: 21, total 9
@@ -138,11 +138,11 @@ fn emitVars(a: Allocator, fdata: []const u8, current: *AbstTree) !void {
if (std.mem.indexOf(u8, data, "<")) |offset| {
data = data[offset..];
if (Template.Directive.init(data)) |drct| {
data = data[drct.tag_block.len..];
const s_name = makeStructName(drct.noun);
var f_name = makeFieldName(drct.noun);
switch (drct.verb) {
.variable => |_| {
data = data[drct.tag_block.len..];
var buffer: [0xFF]u8 = undefined;
var kind = try bufPrint(&buffer, ": []const u8,\n", .{});
 
@@ -155,7 +155,7 @@ fn emitVars(a: Allocator, fdata: []const u8, current: *AbstTree) !void {
kind = try bufPrint(&buffer, ": ?[]const u8 = null,\n", .{});
},
.template => |_| {
kind = try bufPrint(&buffer, ": {s},\n", .{s_name});
kind = try bufPrint(&buffer, ": ?{s},\n", .{s_name});
f_name = makeFieldName(drct.noun[1 .. drct.noun.len - 5]);
},
.blob => unreachable,
@@ -166,7 +166,6 @@ fn emitVars(a: Allocator, fdata: []const u8, current: *AbstTree) !void {
try current.append(f_name, kind);
},
else => |verb| {
data = data[drct.tag_block.len..];
var this = try AbstTree.init(a, s_name, current);
const gop = try tree.getOrPut(this.name);
if (!gop.found_existing) {
 
src/template/directive.zig added: 30, removed: 21, total 9
@@ -34,7 +34,7 @@ pub const Otherwise = union(enum) {
ignore: void,
delete: void,
default: []const u8,
template: Template.Template,
template: *const Template.Template,
blob: []const u8,
};
 
@@ -396,7 +396,7 @@ pub fn forEachTyped(self: Directive, T: type, data: T, out: anytype) anyerror!vo
pub fn withTyped(self: Directive, T: type, block: T, out: anytype) anyerror!void {
var p = PageRuntime(T){
.data = block,
.template = if (self.otherwise == .template) self.otherwise.template else .{
.template = if (self.otherwise == .template) self.otherwise.template.* else .{
.name = self.noun,
.blob = trim(u8, self.otherwise.blob, whitespace),
},
@@ -404,19 +404,19 @@ pub fn withTyped(self: Directive, T: type, block: T, out: anytype) anyerror!void
try p.format("", .{}, out);
}
 
fn getDynamic(name: []const u8) ?Template.Template {
fn getDynamic(name: []const u8) ?*const Template.Template {
for (0..dynamic.*.len) |i| {
if (eql(u8, dynamic.*[i].name, name)) {
return dynamic.*[i];
return &dynamic.*[i];
}
}
return null;
}
 
fn getBuiltin(name: []const u8) ?Template.Template {
fn getBuiltin(name: []const u8) ?*const Template.Template {
for (0..builtin.len) |i| {
if (eql(u8, builtin[i].name, name)) {
return builtin[i];
return &builtin[i];
}
}
return null;
@@ -462,9 +462,10 @@ pub fn formatTyped(d: Directive, comptime T: type, ctx: T, out: anytype) !void {
.ignore => return error.IgnoreDirective,
.required => return error.VariableMissing,
.delete => {},
.template => |subt| {
.template => |template| {
if (T == usize) unreachable;
inline for (std.meta.fields(T)) |field|
if (@typeInfo(T) != .Struct) unreachable;
inline for (std.meta.fields(T)) |field| {
switch (@typeInfo(field.type)) {
.Optional => |otype| {
if (otype.child == []const u8) continue;
@@ -473,7 +474,7 @@ pub fn formatTyped(d: Directive, comptime T: type, ctx: T, out: anytype) !void {
const realname = local[0..makeFieldName(noun[1 .. noun.len - 5], &local)];
if (std.mem.eql(u8, field.name, realname)) {
if (@field(ctx, field.name)) |subdata| {
var subpage = subt.pageOf(otype.child, subdata);
var subpage = template.pageOf(otype.child, subdata);
try subpage.format("{}", .{}, out);
} else std.debug.print(
"sub template data was null for {s}\n",
@@ -484,13 +485,21 @@ pub fn formatTyped(d: Directive, comptime T: type, ctx: T, out: anytype) !void {
.Struct => {
if (std.mem.eql(u8, field.name, noun)) {
const subdata = @field(ctx, field.name);
var subpage = subt.pageOf(@TypeOf(subdata), subdata);
var subpage = template.pageOf(@TypeOf(subdata), subdata);
try subpage.format("{}", .{}, out);
}
},
else => {}, //@compileLog(field.type),
};
}
}
},
//inline for (std.meta.fields(T)) |field| {
// if (eql(u8, field.name, noun)) {
// const subdata = @field(ctx, field.name);
// var page = template.pageOf(@TypeOf(subdata), subdata);
// try page.format("{}", .{}, out);
// }
//}
.blob => unreachable,
}
}
 
src/template/page.zig added: 30, removed: 21, total 9
@@ -2,6 +2,7 @@ const std = @import("std");
const is_test = @import("builtin").is_test;
const Allocator = std.mem.Allocator;
const eql = std.mem.eql;
const indexOfScalar = std.mem.indexOfScalar;
 
const Templates = @import("../template.zig");
const Template = Templates.Template;
@@ -29,7 +30,7 @@ pub fn PageRuntime(comptime PageDataType: type) type {
//var ctx = self.data;
var blob = self.template.blob;
while (blob.len > 0) {
if (std.mem.indexOf(u8, blob, "<")) |offset| {
if (indexOfScalar(u8, blob, '<')) |offset| {
try out.writeAll(blob[0..offset]);
blob = blob[offset..];
if (Directive.init(blob)) |drct| {
@@ -78,7 +79,7 @@ pub fn Page(comptime template: Template, comptime PageDataType: type) type {
pub fn format(self: Self, comptime _: []const u8, _: std.fmt.FormatOptions, out: anytype) !void {
var blob = Self.PageTemplate.blob;
while (blob.len > 0) {
if (std.mem.indexOf(u8, blob, "<")) |offset| {
if (indexOfScalar(u8, blob, '<')) |offset| {
try out.writeAll(blob[0..offset]);
blob = blob[offset..];