diff --git a/src/parser.zig b/src/parser.zig index addc0fd..ad2021f 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -24,6 +24,11 @@ pub const NodeType = enum { debug, partialdef, partial, + querystring, +}; + +pub const QueryStringNode = struct { + modifications: []const []const u8, // array de "key=value" ou "key=None" }; pub const PartialDefNode = struct { @@ -172,6 +177,7 @@ pub const Node = struct { lorem: ?LoremNode = null, partialdef: ?PartialDefNode = null, partial: ?PartialNode = null, + querystring: ?QueryStringNode = null, csrf_token: bool = false, debug: bool = false, @@ -277,6 +283,10 @@ pub const Node = struct { .partial => if (self.partial) |p| { allocator.free(p.name); }, + .querystring => if (self.querystring) |qs| { + for (qs.modifications) |m| allocator.free(m); + allocator.free(qs.modifications); + }, } } }; @@ -403,7 +413,7 @@ pub const Parser = struct { return Node{ .type = .partialdef, .partialdef = .{ - .name = try allocator.dupe(u8, name), + .name = name, .body = try body.toOwnedSlice(allocator), .raw_open = raw_open, .raw_close = raw_close, @@ -1195,6 +1205,7 @@ pub const Parser = struct { const raw_open = node.tag.?.raw; const duped_name = try allocator.dupe(u8, partial_name); + errdefer allocator.free(duped_name); allocator.free(node.tag.?.name); allocator.free(node.tag.?.args); @@ -1652,6 +1663,58 @@ pub const Parser = struct { continue; } + if (std.mem.eql(u8, tag_name, "querystring")) { + const args = node.tag.?.args; + + var modifications = std.ArrayList([]const u8){}; + defer modifications.deinit(allocator); + + var i: usize = 0; + while (i < args.len) { + while (i < args.len and std.ascii.isWhitespace(args[i])) : (i += 1) {} + + if (i >= args.len) break; + + const start = i; + var in_quote = false; + var quote_char: u8 = 0; + if (args[i] == '"' or args[i] == '\'') { + in_quote = true; + quote_char = args[i]; + i += 1; + } + + while (i < args.len) { + if (in_quote) { + if (args[i] == quote_char) { + i += 1; + break; + } + } else { + if (std.ascii.isWhitespace(args[i])) break; + } + i += 1; + } + + const mod_str = std.mem.trim(u8, args[start..i], " \t\r\n\"'"); + try modifications.append(allocator, try allocator.dupe(u8, mod_str)); + } + + allocator.free(node.tag.?.name); + allocator.free(node.tag.?.args); + + std.debug.print("3.0 - na real sou um querystring\n", .{}); + std.debug.print("===================================\n", .{}); + + try list.append(allocator, Node{ + .type = .querystring, + .querystring = .{ + .modifications = try modifications.toOwnedSlice(allocator), + }, + }); + 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, ' ')) { diff --git a/src/parser_test.zig b/src/parser_test.zig index 80a1a2c..c51dc50 100644 --- a/src/parser_test.zig +++ b/src/parser_test.zig @@ -772,3 +772,37 @@ test "parse partial uso" { try testing.expect(nodes[1].type == .partial); try testing.expectEqualStrings("cabecalho", nodes[1].partial.?.name); } + +test "parse querystring simples" { + const allocator = testing.allocator; + const template = "Link: {% querystring \"page=2\" %}"; + const nodes = try parser.parse(allocator, template); + defer { + for (nodes) |node| node.deinit(allocator); + allocator.free(nodes); + } + + try testing.expectEqual(@as(usize, 2), nodes.len); + try testing.expect(nodes[1].type == .querystring); + const qs = nodes[1].querystring.?; + try testing.expectEqual(@as(usize, 1), qs.modifications.len); + try testing.expectEqualStrings("page=2", qs.modifications[0]); +} + +test "parse querystring múltiplos" { + const allocator = testing.allocator; + const template = "{% querystring \"ordenar=-nome\" \"pagina\" None %}"; + 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 == .querystring); + const qs = nodes[0].querystring.?; + try testing.expectEqual(@as(usize, 3), qs.modifications.len); + try testing.expectEqualStrings("ordenar=-nome", qs.modifications[0]); + try testing.expectEqualStrings("pagina", qs.modifications[1]); + try testing.expectEqualStrings("None", qs.modifications[2]); +} diff --git a/todo.md b/todo.md index a071a4c..190bc34 100644 --- a/todo.md +++ b/todo.md @@ -18,7 +18,7 @@ - [x] now - [x] partial - [x] partialdef -- [ ] querystring +- [x] querystring - [ ] regroup - [ ] resetcycle - [x] spaceless @@ -111,7 +111,7 @@ ___ - [x] debug - [x] lorem - [x] partial / partialdef -- [ ] querystring +- [x] querystring - [ ] regroup - [ ] resetcycle - [ ] templatetag