update: csrf_token and lorem

This commit is contained in:
Lucas F. 2026-01-03 21:00:11 -03:00
parent bbab647430
commit b09da93f0d
3 changed files with 175 additions and 3 deletions

View file

@ -19,6 +19,14 @@ pub const NodeType = enum {
cycle,
firstof,
load,
csrf_token,
lorem,
};
pub const LoremNode = struct {
count: ?[]const u8 = null, // "3" ou null
method: ?[]const u8 = null, // "p" ou "w" ou null
format: ?[]const u8 = null, // "html" ou null
};
pub const LoadNode = struct {
@ -147,6 +155,8 @@ pub const Node = struct {
cycle: ?CycleNode = null,
firstof: ?FirstOfNode = null,
load: ?LoadNode = null,
lorem: ?LoremNode = null,
csrf_token: bool = false,
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
switch (self.type) {
@ -235,6 +245,12 @@ pub const Node = struct {
for (l.libraries) |lib| allocator.free(lib);
allocator.free(l.libraries);
},
.csrf_token => {},
.lorem => if (self.lorem) |l| {
if (l.count) |c| allocator.free(c);
if (l.method) |m| allocator.free(m);
if (l.format) |f| allocator.free(f);
},
}
}
};
@ -1090,6 +1106,48 @@ pub const Parser = struct {
continue;
}
if (std.mem.eql(u8, tag_name, "lorem")) {
const args = node.tag.?.args;
var count: ?[]const u8 = null;
var method: ?[]const u8 = null;
var format: ?[]const u8 = null;
var parts = std.mem.splitScalar(u8, args, ' ');
while (parts.next()) |part| {
const trimmed = std.mem.trim(u8, part, " \t\r\n");
if (trimmed.len == 0) continue;
const num: usize = std.fmt.parseInt(usize, trimmed, 10) catch 0;
if (num > 0) {
std.debug.print("trimmed: {s}\n", .{trimmed});
count = try allocator.dupe(u8, trimmed);
}
if (std.mem.eql(u8, trimmed, "p") or std.mem.eql(u8, trimmed, "w")) {
std.debug.print("trimmed: {s}\n", .{trimmed});
method = try allocator.dupe(u8, trimmed);
} else if (std.mem.eql(u8, trimmed, "html")) {
std.debug.print("trimmed: {s}\n", .{trimmed});
format = try allocator.dupe(u8, trimmed);
}
}
allocator.free(node.tag.?.name);
allocator.free(node.tag.?.args);
try list.append(allocator, Node{
.type = .lorem,
.lorem = .{
.count = count,
.method = method,
.format = format,
},
});
continue;
}
if (std.mem.eql(u8, tag_name, "filter")) {
const filters_raw = node.tag.?.args;
const raw_open = node.tag.?.raw;
@ -1457,6 +1515,25 @@ pub const Parser = struct {
continue;
}
if (std.mem.eql(u8, tag_name, "csrf_token")) {
// Verifica se tem argumentos (não deve ter)
if (node.tag.?.args.len > 0 and !std.mem.allEqual(u8, node.tag.?.args, ' ')) {
return error.InvalidCsrfTokenArgs;
}
allocator.free(node.tag.?.name);
allocator.free(node.tag.?.args);
std.debug.print("3.0 - na real sou um csrf_token\n", .{});
std.debug.print("===================================\n", .{});
try list.append(allocator, Node{
.type = .csrf_token,
.csrf_token = true,
});
continue;
}
// Para tags normais
std.debug.print("===================================\n", .{});
try list.append(allocator, node);

View file

@ -643,3 +643,69 @@ test "parse load com múltiplas" {
try testing.expectEqualStrings("admin_urls", l.libraries[0]);
try testing.expectEqualStrings("static", l.libraries[1]);
}
test "parse csrf_token simples" {
const allocator = testing.allocator;
const template = "<form>{% csrf_token %}</form>";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 3), nodes.len);
try testing.expect(nodes[0].type == .text);
try testing.expectEqualStrings("<form>", nodes[0].text.?.content);
try testing.expect(nodes[1].type == .csrf_token);
try testing.expect(nodes[2].type == .text);
try testing.expectEqualStrings("</form>", nodes[2].text.?.content);
}
test "parse csrf_token sozinho" {
const allocator = testing.allocator;
const template = "{% csrf_token %}";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 1), nodes.len);
try testing.expect(nodes[0].type == .csrf_token);
}
test "parse lorem padrão" {
const allocator = testing.allocator;
const template = "{% lorem %}";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 1), nodes.len);
try testing.expect(nodes[0].type == .lorem);
const l = nodes[0].lorem.?;
try testing.expect(l.count == null);
try testing.expect(l.method == null);
try testing.expect(l.format == null);
}
test "parse lorem com argumentos" {
const allocator = testing.allocator;
const template = "{% lorem 5 p html %}";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 1), nodes.len);
try testing.expect(nodes[0].type == .lorem);
const l = nodes[0].lorem.?;
try testing.expectEqualStrings("5", l.count.?);
try testing.expectEqualStrings("p", l.method.?);
try testing.expectEqualStrings("html", l.format.?);
}