From f09689d5395920d98f595f7ae57bcaf7a2121656 Mon Sep 17 00:00:00 2001 From: "Lucas F." Date: Sat, 17 Jan 2026 17:37:36 -0300 Subject: [PATCH] fix: clone --- src/parser.zig | 798 ++++++++++++++++++++++++++++++------------------- 1 file changed, 495 insertions(+), 303 deletions(-) diff --git a/src/parser.zig b/src/parser.zig index e77ecd7..773a31d 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -435,310 +435,502 @@ pub const Node = struct { }; }, .tag => { - return Node{ - .type = .tag, - .tag = .{ - .args = try allocator.dupe(u8, self.tag.?.args), - .raw = try allocator.dupe(u8, self.tag.?.raw), - .body = try allocator.dupe(u8, self.tag.?.body), - }, - }; - }, - .debug => return Node{ .type = .tag, .tag = .{ .debug = true } }, - // .firstof => { - // const values_copy = try allocator.alloc([]const u8, self.firstof.?.values.len); - // errdefer allocator.free(values_copy); - // - // for (self.firstof.?.values, 0..) |f, i| { - // values_copy[i] = try allocator.dupe(u8, f); - // } - // - // return Node{ .type = .firstof, .firstof = .{ .values = values_copy } }; - // }, + switch (self.tag.?.kind) { + .debug => return Node{ .type = .tag, .tag = .{ + .kind = .debug, + .args = "", + .body = .{ .debug = true }, + .raw = self.tag.?.raw, + } }, + .firstof => { + const values_copy = try allocator.alloc([]const u8, self.tag.?.body.firstof.values.len); + errdefer allocator.free(values_copy); - // .if_block => { - // const true_body_copy = try allocator.alloc(Node, self.@"if".?.true_body.len); - // errdefer allocator.free(true_body_copy); - // - // for (self.@"if".?.true_body, 0..) |child, j| { - // true_body_copy[j] = try child.clone(allocator); - // } - // - // const false_body_copy = try allocator.alloc(Node, self.@"if".?.false_body.len); - // errdefer allocator.free(false_body_copy); - // - // for (self.@"if".?.false_body, 0..) |child, j| { - // false_body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .if_block, - // .@"if" = .{ - // .condition = try allocator.dupe(u8, self.@"if".?.condition), - // .true_body = true_body_copy, - // .false_body = false_body_copy, - // .raw_open = try allocator.dupe(u8, self.@"if".?.raw_open), - // .raw_close = try allocator.dupe(u8, self.@"if".?.raw_close), - // }, - // }; - // }, - // - // .for_block => { - // const body_copy = try allocator.alloc(Node, self.@"for".?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.@"for".?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // const empty_body_copy = try allocator.alloc(Node, self.@"for".?.empty_body.len); - // errdefer allocator.free(empty_body_copy); - // - // for (self.@"for".?.empty_body, 0..) |child, j| { - // empty_body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .for_block, - // .@"for" = .{ - // .loop_var = try allocator.dupe(u8, self.@"for".?.loop_var), - // .iterable = try allocator.dupe(u8, self.@"for".?.iterable), - // .body = body_copy, - // .empty_body = empty_body_copy, - // .raw_open = try allocator.dupe(u8, self.@"for".?.raw_open), - // .raw_close = try allocator.dupe(u8, self.@"for".?.raw_close), - // }, - // }; - // }, - // - // .block => { - // const body_copy = try allocator.alloc(Node, self.block.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.block.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .block, - // .block = .{ - // .name = try allocator.dupe(u8, self.block.?.name), - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.block.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.block.?.raw_close), - // }, - // }; - // }, - // - // .extends => { - // return Node{ - // .type = .extends, - // .extends = .{ - // .parent_name = try allocator.dupe(u8, self.extends.?.parent_name), - // }, - // }; - // }, - // - // .super => { - // return Node{ - // .type = .super, - // }; - // }, - // .include => { - // return Node{ - // .type = .include, - // .include = .{ - // .template_name = try allocator.dupe(u8, self.include.?.template_name), - // }, - // }; - // }, - // .with_block => { - // const body_copy = try allocator.alloc(Node, self.with.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.with.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // const assignments_copy = try allocator.alloc(Assignment, self.with.?.assignments.len); - // errdefer allocator.free(assignments_copy); - // - // for (self.with.?.assignments, 0..) |f, i| { - // assignments_copy[i] = .{ - // .key = try allocator.dupe(u8, f.key), - // .value_expr = try allocator.dupe(u8, f.value_expr), - // .is_literal = f.is_literal, - // }; - // } - // - // return Node{ - // .type = .with_block, - // .with = .{ - // .assignments = assignments_copy, - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.with.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.with.?.raw_close), - // }, - // }; - // }, - // .now => { - // return Node{ .type = .now, .now = .{ .format = try allocator.dupe(u8, self.now.?.format) } }; - // }, - // .filter_block => { - // const body_copy = try allocator.alloc(Node, self.filter_block.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.filter_block.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .filter_block, - // .filter_block = .{ - // .filters = try allocator.dupe(u8, self.filter_block.?.filters), - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.filter_block.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.filter_block.?.raw_close), - // }, - // }; - // }, - // .autoescape => { - // const body_copy = try allocator.alloc(Node, self.autoescape.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.autoescape.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .autoescape, - // .autoescape = .{ - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.autoescape.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.autoescape.?.raw_close), - // .enabled = self.autoescape.?.enabled, - // }, - // }; - // }, - // .spaceless => { - // const body_copy = try allocator.alloc(Node, self.spaceless.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.spaceless.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ - // .type = .spaceless, - // .spaceless = .{ - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.spaceless.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.spaceless.?.raw_close), - // }, - // }; - // }, - // .url => { - // const args_copy = try allocator.alloc([]const u8, self.url.?.args.len); - // errdefer allocator.free(args_copy); - // - // for (self.url.?.args, 0..) |f, i| { - // args_copy[i] = try allocator.dupe(u8, f); - // } - // - // return Node{ .type = .url, .url = .{ - // .name = try allocator.dupe(u8, self.url.?.name), - // .args = args_copy, - // } }; - // }, - // .cycle => { - // const values_copy = try allocator.alloc([]const u8, self.cycle.?.values.len); - // errdefer allocator.free(values_copy); - // - // for (self.cycle.?.values, 0..) |f, i| { - // values_copy[i] = try allocator.dupe(u8, f); - // } - // - // return Node{ .type = .cycle, .cycle = .{ .values = values_copy } }; - // }, - // .load => { - // const libraries_copy = try allocator.alloc([]const u8, self.load.?.libraries.len); - // errdefer allocator.free(libraries_copy); - // - // for (self.load.?.libraries, 0..) |f, i| { - // libraries_copy[i] = try allocator.dupe(u8, f); - // } - // - // return Node{ .type = .load, .load = .{ .libraries = libraries_copy } }; - // }, - // .csrf_token => { - // return Node{ - // .type = .csrf_token, - // }; - // }, - // .lorem => { - // return Node{ - // .type = .lorem, - // .lorem = .{ - // .count = if (self.lorem.?.count) |c| try allocator.dupe(u8, c) else null, - // .method = if (self.lorem.?.method) |m| try allocator.dupe(u8, m) else null, - // .format = if (self.lorem.?.format) |f| try allocator.dupe(u8, f) else null, - // }, - // }; - // }, - // .partialdef => { - // const body_copy = try allocator.alloc(Node, self.partialdef.?.body.len); - // errdefer allocator.free(body_copy); - // - // for (self.partialdef.?.body, 0..) |child, j| { - // body_copy[j] = try child.clone(allocator); - // } - // - // return Node{ .type = .partialdef, .partialdef = .{ - // .name = try allocator.dupe(u8, self.partialdef.?.name), - // .body = body_copy, - // .raw_open = try allocator.dupe(u8, self.partialdef.?.raw_open), - // .raw_close = try allocator.dupe(u8, self.partialdef.?.raw_close), - // } }; - // }, - // .partial => { - // return Node{ .type = .partial, .partial = .{ - // .name = try allocator.dupe(u8, self.partial.?.name), - // } }; - // }, - // .querystring => { - // const modifications = try allocator.alloc([]const u8, self.querystring.?.modifications.len); - // errdefer allocator.free(modifications); - // - // for (self.querystring.?.modifications, 0..) |f, i| { - // modifications[i] = try allocator.dupe(u8, f); - // } - // - // return Node{ .type = .querystring, .querystring = .{ - // .modifications = modifications, - // } }; - // }, - // .regroup => { - // return Node{ .type = .regroup, .regroup = .{ - // .source = try allocator.dupe(u8, self.regroup.?.source), - // .by = try allocator.dupe(u8, self.regroup.?.by), - // .as_var = try allocator.dupe(u8, self.regroup.?.as_var), - // } }; - // }, - // .resetcycle => { - // return Node{ .type = .resetcycle, .resetcycle = .{ - // .cycle_name = if (self.resetcycle.?.cycle_name) |n| try allocator.dupe(u8, n) else null, - // } }; - // }, - // .widthratio => { - // return Node{ .type = .widthratio, .widthratio = .{ - // .value = try allocator.dupe(u8, self.widthratio.?.value), - // .max_value = try allocator.dupe(u8, self.widthratio.?.max_value), - // .divisor = if (self.widthratio.?.divisor) |d| try allocator.dupe(u8, d) else null, - // } }; - // }, - // .templatetag => { - // return Node{ .type = .templatetag, .templatetag = .{ .kind = self.templatetag.?.kind } }; - // }, + for (self.tag.?.body.firstof.values, 0..) |f, i| { + values_copy[i] = try allocator.dupe(u8, f); + } + + return Node{ .type = .tag, .tag = .{ + .kind = .firstof, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ .firstof = .{ .values = values_copy } }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + } }; + }, + .if_block => { + const true_body_copy = try allocator.alloc(Node, self.tag.?.body.@"if".true_body.len); + errdefer allocator.free(true_body_copy); + + for (self.tag.?.body.@"if".true_body, 0..) |child, j| { + true_body_copy[j] = try child.clone(allocator); + } + + const false_body_copy = try allocator.alloc(Node, self.tag.?.body.@"if".false_body.len); + errdefer allocator.free(false_body_copy); + + for (self.tag.?.body.@"if".false_body, 0..) |child, j| { + false_body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .if_block, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ + .@"if" = .{ + .condition = try allocator.dupe(u8, self.tag.?.body.@"if".condition), + .true_body = true_body_copy, + .false_body = false_body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.@"if".raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.@"if".raw_close), + }, + }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + }, + }; + }, + .for_block => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.@"for".body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.@"for".body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + const empty_body_copy = try allocator.alloc(Node, self.tag.?.body.@"for".empty_body.len); + errdefer allocator.free(empty_body_copy); + + for (self.tag.?.body.@"for".empty_body, 0..) |child, j| { + empty_body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .for_block, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ + .@"for" = .{ + .loop_var = try allocator.dupe(u8, self.tag.?.body.@"for".loop_var), + .iterable = try allocator.dupe(u8, self.tag.?.body.@"for".iterable), + .body = body_copy, + .empty_body = empty_body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.@"for".raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.@"for".raw_close), + }, + }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + }, + }; + }, + .block => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.block.body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.block.body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .block, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ + .block = .{ + .name = try allocator.dupe(u8, self.tag.?.body.block.name), + .body = body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.block.raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.block.raw_close), + }, + }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + }, + }; + }, + .extends => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .extends, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ + .extends = .{ + .parent_name = try allocator.dupe(u8, self.tag.?.body.extends.parent_name), + }, + }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + }, + }; + }, + .super => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .super, + .args = try allocator.dupe(u8, self.tag.?.args), + .body = .{ .super = true }, + .raw = try allocator.dupe(u8, self.tag.?.raw), + }, + }; + }, + .include => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .include, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + .body = .{ + .include = .{ + .template_path = try allocator.dupe(u8, self.tag.?.body.include.template_path), + }, + }, + }, + }; + }, + .with_block => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.with.body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.with.body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + const assignments_copy = try allocator.alloc(Assignment, self.tag.?.body.with.assignments.len); + errdefer allocator.free(assignments_copy); + + for (self.tag.?.body.with.assignments, 0..) |f, i| { + assignments_copy[i] = .{ + .key = try allocator.dupe(u8, f.key), + .value_expr = try allocator.dupe(u8, f.value_expr), + .is_literal = f.is_literal, + }; + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .with_block, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .with = .{ + .assignments = assignments_copy, + .body = body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.with.raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.with.raw_close), + }, + }, + }, + }; + }, + .now => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .now, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .now = .{ + .format = try allocator.dupe(u8, self.tag.?.body.now.format), + }, + }, + }, + }; + }, + .autoescape => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.autoescape.body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.autoescape.body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .autoescape, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .autoescape = .{ + .body = body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.autoescape.raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.autoescape.raw_close), + .enabled = self.tag.?.body.autoescape.enabled, + }, + }, + }, + }; + }, + .spaceless => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.spaceless.body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.spaceless.body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .spaceless, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .spaceless = .{ + .body = body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.spaceless.raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.spaceless.raw_close), + }, + }, + }, + }; + }, + .url => { + const args_copy = try allocator.alloc([]const u8, self.tag.?.body.url.args.len); + errdefer allocator.free(args_copy); + + for (self.tag.?.body.url.args, 0..) |f, i| { + args_copy[i] = try allocator.dupe(u8, f); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .url, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .url = .{ + .name = try allocator.dupe(u8, self.tag.?.body.url.name), + .args = args_copy, + }, + }, + }, + }; + }, + .cycle => { + const values_copy = try allocator.alloc([]const u8, self.tag.?.body.cycle.values.len); + errdefer allocator.free(values_copy); + + for (self.tag.?.body.cycle.values, 0..) |f, i| { + values_copy[i] = try allocator.dupe(u8, f); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .cycle, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .cycle = .{ + .values = values_copy, + }, + }, + }, + }; + }, + .load => { + const libraries_copy = try allocator.alloc([]const u8, self.tag.?.body.load.libraries.len); + errdefer allocator.free(libraries_copy); + + for (self.tag.?.body.load.libraries, 0..) |f, i| { + libraries_copy[i] = try allocator.dupe(u8, f); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .load, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .load = .{ + .libraries = libraries_copy, + }, + }, + }, + }; + }, + .lorem => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .lorem, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .lorem = .{ + .count = if (self.tag.?.body.lorem.count) |c| try allocator.dupe(u8, c) else null, + .method = if (self.tag.?.body.lorem.method) |m| try allocator.dupe(u8, m) else null, + .format = if (self.tag.?.body.lorem.format) |f| try allocator.dupe(u8, f) else null, + }, + }, + }, + }; + }, + .partialdef => { + const body_copy = try allocator.alloc(Node, self.tag.?.body.partialdef.body.len); + errdefer allocator.free(body_copy); + + for (self.tag.?.body.partialdef.body, 0..) |child, j| { + body_copy[j] = try child.clone(allocator); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .partialdef, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .partialdef = .{ + .name = try allocator.dupe(u8, self.tag.?.body.partialdef.name), + .body = body_copy, + .raw_open = try allocator.dupe(u8, self.tag.?.body.partialdef.raw_open), + .raw_close = try allocator.dupe(u8, self.tag.?.body.partialdef.raw_close), + }, + }, + }, + }; + }, + .partial => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .partial, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .partial = .{ + .name = try allocator.dupe(u8, self.tag.?.body.partial.name), + }, + }, + }, + }; + }, + .querystring => { + const modifications_copy = try allocator.alloc([]const u8, self.tag.?.body.querystring.modifications.len); + errdefer allocator.free(modifications_copy); + + for (self.tag.?.body.querystring.modifications, 0..) |f, i| { + modifications_copy[i] = try allocator.dupe(u8, f); + } + + return Node{ + .type = .tag, + .tag = .{ + .kind = .querystring, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .querystring = .{ + .modifications = modifications_copy, + }, + }, + }, + }; + }, + .regroup => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .regroup, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .regroup = .{ + .source = try allocator.dupe(u8, self.tag.?.body.regroup.source), + .by = try allocator.dupe(u8, self.tag.?.body.regroup.by), + .as_var = try allocator.dupe(u8, self.tag.?.body.regroup.as_var), + }, + }, + }, + }; + }, + .resetcycle => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .resetcycle, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .resetcycle = .{ + .cycle_name = if (self.tag.?.body.resetcycle.cycle_name) |n| try allocator.dupe(u8, n) else null, + }, + }, + }, + }; + }, + .widthratio => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .widthratio, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .widthratio = .{ + .value = try allocator.dupe(u8, self.tag.?.body.widthratio.value), + .max_value = try allocator.dupe(u8, self.tag.?.body.widthratio.max_value), + .divisor = if (self.tag.?.body.widthratio.divisor) |d| try allocator.dupe(u8, d) else null, + }, + }, + }, + }; + }, + .templatetag => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .templatetag, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + + .body = .{ + .templatetag = .{ + .kind = self.tag.?.body.templatetag.kind, + }, + }, + }, + }; + }, + .csrf_token => { + return Node{ + .type = .tag, + .tag = .{ + .kind = .csrf_token, + .args = try allocator.dupe(u8, self.tag.?.args), + .raw = try allocator.dupe(u8, self.tag.?.raw), + .body = .{ + .csrf_token = true, + }, + }, + }; + }, + else => unreachable, + } + }, } } };