| ... | @@ -56,7 +56,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -56,7 +56,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 56 | try writer.writeAll(v[1 .. v.len - 1]); | 56 | try writer.writeAll(v[1 .. v.len - 1]); |
| 57 | }, | 57 | }, |
| 58 | .replacement => |v| { | 58 | .replacement => |v| { |
| 59 | const x = if (comptime std.mem.eql(u8, v[0], "this")) search(data, v[1..]) else search(ctx, v); | 59 | const x = if (comptime std.mem.eql(u8, v[0], "this")) search(v[1..], data) else search(v, ctx); |
| 60 | const TO = @TypeOf(x); | 60 | const TO = @TypeOf(x); |
| 61 | | 61 | |
| 62 | if (comptime std.meta.trait.isZigString(TO)) { | 62 | if (comptime std.meta.trait.isZigString(TO)) { |
| ... | @@ -76,7 +76,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -76,7 +76,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 76 | switch (v.name) { | 76 | switch (v.name) { |
| 77 | .each => { | 77 | .each => { |
| 78 | comptime assertEqual(v.args.len, 1); | 78 | comptime assertEqual(v.args.len, 1); |
| 79 | const x = comptime search(data, v.args[0]); | 79 | const x = search(v.args[0], data); |
| 80 | inline for (x) |item| { | 80 | inline for (x) |item| { |
| 81 | inline for (v.body) |val| { | 81 | inline for (v.body) |val| { |
| 82 | try do(writer, val, item, ctx, indent, flag1); | 82 | try do(writer, val, item, ctx, indent, flag1); |
| ... | @@ -85,7 +85,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -85,7 +85,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 85 | }, | 85 | }, |
| 86 | .@"if" => { | 86 | .@"if" => { |
| 87 | comptime assertEqual(v.args.len, 1); | 87 | comptime assertEqual(v.args.len, 1); |
| 88 | const x = comptime search(data, v.args[0]); | 88 | const x = search(v.args[0], data); |
| 89 | if (x) { | 89 | if (x) { |
| 90 | inline for (v.body) |val| { | 90 | inline for (v.body) |val| { |
| 91 | try do(writer, val, data, ctx, indent, flag1); | 91 | try do(writer, val, data, ctx, indent, flag1); |
| ... | @@ -94,7 +94,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -94,7 +94,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 94 | }, | 94 | }, |
| 95 | .ifnot => { | 95 | .ifnot => { |
| 96 | comptime assertEqual(v.args.len, 1); | 96 | comptime assertEqual(v.args.len, 1); |
| 97 | const x = comptime search(data, v.args[0]); | 97 | const x = search(v.args[0], data); |
| 98 | if (!x) { | 98 | if (!x) { |
| 99 | inline for (v.body) |val| { | 99 | inline for (v.body) |val| { |
| 100 | try do(writer, val, data, ctx, indent, flag1); | 100 | try do(writer, val, data, ctx, indent, flag1); |
| ... | @@ -103,8 +103,8 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -103,8 +103,8 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 103 | }, | 103 | }, |
| 104 | .ifequal => { | 104 | .ifequal => { |
| 105 | comptime assertEqual(v.args.len, 2); | 105 | comptime assertEqual(v.args.len, 2); |
| 106 | const x = comptime search(data, v.args[0]); | 106 | const x = search(v.args[0], data); |
| 107 | const y = comptime search(data, v.args[1]); | 107 | const y = search(v.args[1], data); |
| 108 | if (x == y) { | 108 | if (x == y) { |
| 109 | inline for (v.body) |val| { | 109 | inline for (v.body) |val| { |
| 110 | try do(writer, val, data, ctx, indent, flag1); | 110 | try do(writer, val, data, ctx, indent, flag1); |
| ... | @@ -113,8 +113,8 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -113,8 +113,8 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 113 | }, | 113 | }, |
| 114 | .ifnotequal => { | 114 | .ifnotequal => { |
| 115 | comptime assertEqual(v.args.len, 2); | 115 | comptime assertEqual(v.args.len, 2); |
| 116 | const x = comptime search(data, v.args[0]); | 116 | const x = search(v.args[0], data); |
| 117 | const y = comptime search(data, v.args[1]); | 117 | const y = search(v.args[1], data); |
| 118 | if (x != y) { | 118 | if (x != y) { |
| 119 | inline for (v.body) |val| { | 119 | inline for (v.body) |val| { |
| 120 | try do(writer, val, data, ctx, indent, flag1); | 120 | try do(writer, val, data, ctx, indent, flag1); |
| ... | @@ -127,8 +127,25 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -127,8 +127,25 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 127 | } | 127 | } |
| 128 | } | 128 | } |
| 129 | | 129 | |
| 130 | fn search(comptime T: anytype, comptime args: []const []const u8) @TypeOf(if (args.len == 1) @field(T, args[0]) else search(@field(T, args[0]), args[1..])) { | 130 | fn search(comptime args: []const []const u8, ctx: anytype) FieldSearch(@TypeOf(ctx), args) { |
| 131 | return if (args.len == 1) @field(T, args[0]) else search(@field(T, args[0]), args[1..]); | 131 | const f = @field(ctx, args[0]); |
| | 132 | if (args.len == 1) return f; |
| | 133 | return search(args[1..], f); |
| | 134 | } |
| | 135 | |
| | 136 | fn FieldSearch(comptime T: type, comptime args: []const []const u8) type { |
| | 137 | return if (args.len == 1) Field(T, args[0]) else FieldSearch(Field(T, args[0]), args[1..]); |
| | 138 | } |
| | 139 | |
| | 140 | fn Field(comptime T: type, comptime field_name: []const u8) type { |
| | 141 | inline for (std.meta.fields(T)) |fld| { |
| | 142 | if (std.mem.eql(u8, fld.name, field_name)) return fld.field_type; |
| | 143 | } |
| | 144 | if (std.meta.trait.isIndexable(T) and std.mem.eql(u8, field_name, "len")) { |
| | 145 | return usize; |
| | 146 | } |
| | 147 | @compileLog(field_name); |
| | 148 | @compileLog(std.meta.fieldNames(T)); |
| 132 | } | 149 | } |
| 133 | | 150 | |
| 134 | fn entityLookupBefore(in: []const u8) ?htmlentities.Entity { | 151 | fn entityLookupBefore(in: []const u8) ?htmlentities.Entity { |