diff --git a/src/template/lib.zig b/src/template/lib.zig index c5fb6b6..4e8803c 100644 --- a/src/template/lib.zig +++ b/src/template/lib.zig @@ -215,6 +215,17 @@ fn print(writer: anytype, arg: anytype) !void { const ExpressionError = error{ IndexOutOfBounds, NullOptional }; +fn Deref(comptime T: type, comptime field: []const u8) type { + if (std.meta.trait.isIndexable(T) and std.mem.eql(u8, field, "len")) return usize; + switch (@typeInfo(T)) { + .Pointer => return Deref(std.meta.Child(T), field), + .Struct => |info| for (info.fields) |f| { + if (std.mem.eql(u8, field, f.name)) return f.field_type; + } else @compileError("Field " ++ field ++ " does not exist on type " ++ @typeName(T)), + else => @compileError("Cannot retrieve field " ++ field ++ " from type " ++ @typeName(T)), + } +} + fn EvaluateExpression( comptime expression: Expression, comptime Args: type, @@ -227,9 +238,7 @@ fn EvaluateExpression( .context => Context, .deref => |expr| { const T = EvaluateExpression(expr.container, Args, Captures, Context); - for (@typeInfo(T).Struct.fields) |f| { - if (std.mem.eql(u8, expr.field, f.name)) return f.field_type; - } else @compileError("Field " ++ expr.field ++ " does not exist on type " ++ @typeName(T)); + return Deref(T, expr.field); }, .equals => bool, .builtin => |call| switch (call.*) { @@ -300,12 +309,14 @@ fn AddCapture(comptime Root: type, comptime name: []const u8, comptime Val: type .alignment = @alignOf(Val), }}; - return @Type(.{ .Struct = .{ + const Result = @Type(.{ .Struct = .{ .layout = .Auto, .fields = fields, .decls = &.{}, .is_tuple = false, } }); + + return Result; } fn addCapture(root: anytype, comptime name: []const u8, val: anytype) AddCapture(@TypeOf(root), name, @TypeOf(val)) {