From 9bde4370a61c872d322e2064e6cc92f8bcb99bad Mon Sep 17 00:00:00 2001 From: "Lucas F." Date: Mon, 12 Jan 2026 09:08:40 -0300 Subject: [PATCH] update: misc --- todo.md | 93 +++++++-------------------------------------------------- 1 file changed, 10 insertions(+), 83 deletions(-) diff --git a/todo.md b/todo.md index 2ef6247..1efd645 100644 --- a/todo.md +++ b/todo.md @@ -130,88 +130,15 @@ ___ - Loops com forloop - Tudo testado -4 -Filtros +- Renderer básico — variáveis simples {{ nome }} (já quase pronto acima) +- Filtros em variáveis — {{ nome|upper }}, {{ idade|add:5 }} +- Escaping automático — tudo escapa por default, {{ valor|safe }} não escapa +- Tags básicas — {% if %}, {% for %}, {% block %} +- Extends / include +- Autoescape on/off - - - -na verdade o pushScope não tava não, a versão final que vc me mandou depois que se inspirou no tokamak foi essa: -``` -const std = @import("std"); - -pub const Value = union(enum) { - null, - bool: bool, - int: i64, - float: f64, - string: []const u8, - list: []const Value, - dict: std.StringHashMapUnmanaged(Value), - - pub fn deinit(self: Value) void { - _ = self; // nada — a arena libera tudo - } -}; - -pub const Context = struct { - arena: std.heap.ArenaAllocator, - map: std.StringHashMapUnmanaged(Value), - - pub fn init(child_allocator: std.mem.Allocator) Context { - const arena = std.heap.ArenaAllocator.init(child_allocator); - return .{ - .arena = arena, - .map = .{}, - }; - } - - pub fn allocator(self: *Context) std.mem.Allocator { - return self.arena.allocator(); - } - - pub fn deinit(self: *Context) void { - self.arena.deinit(); - } - - pub fn set(self: *Context, key: []const u8, value: Value) !void { - const gop = try self.map.getOrPut(self.allocator(), key); - if (gop.found_existing) { - // opcional: deinit value antigo se necessário - // mas como arena libera tudo, não precisa - } else { - gop.key_ptr.* = try self.allocator().dupe(u8, key); - } - gop.value_ptr.* = value; - } - - pub fn get(self: *const Context, key: []const u8) ?Value { - return self.map.get(key); - } -}; - -``` -ao colocar isso ordered_dict: []struct { key: []const u8, val: Value }, vc ferrou em todos os switches de Value que agora tem que prever o que fazer com orderdered_dict - -Conclusão sobre o getA melhor abordagem, considerando Zig, é: -Manter o get(comptime T: type, key) — é seguro, performático, e em uso real fica natural - -```zig -const idade: i64 = ctx.get("idade") orelse 0; -const nome: []const u8 = ctx.get("nome") orelse "Desconhecido"; -``` - -É verboso no teste, mas em código real é claro e seguro.Ou podemos fazer uma versão com optional: - -```zig -pub fn get(self: *const Context, comptime T: type, key: []const u8) ?T { - const value = self.map.get(key) orelse return null; - return value.as(T) catch null; -} -``` - -Aí fica: - -```zig -const idade = ctx.get(i64, "idade") orelse 0; -``` +- Adicionar suporte a argumentos nos filtros (já quase pronto — parsear name:arg) +- Implementar tags básicas (if/for) usando a árvore do parser +- Autoescape completo (escape só em .string, e tratar .safe se quiser) +- Blocos e extends (usando a árvore para coletar blocos e renderizar base)