const std = @import("std"); const Allocator = std.mem.Allocator; const HTML = @import("html/Element.zig"); const Element = @import("Element.zig"); const Self = @This(); src: []const u8, alt: ?[]const u8 = null, pub fn init(alloc: Allocator, src: []const u8) !*Self { const v = try alloc.create(Self); v.* = .{ .src = src, }; return v; } pub fn element(self: *Self) Element { return .{ .ptr = self, .vtable = .{ .deinit = destroy, .html = html } }; } pub fn deinit(self: *Self, alloc: Allocator) void { destroy(self, alloc); } fn destroy(context: *anyopaque, alloc: Allocator) void { const self: *Self = @ptrCast(@alignCast(context)); alloc.destroy(self); } fn html(context: *anyopaque, alloc: Allocator) HTML.Error!HTML { const self: *Self = @ptrCast(@alignCast(context)); var img = try HTML.init(alloc, .void, "img"); errdefer img.deinit(); try img.setAttribute("src", self.src); if (self.alt) |it| try img.setAttribute("alt", it); return img; } test "html" { const alloc = std.testing.allocator; const expect = std.testing.expect; const eql = std.mem.eql; var img = try init(alloc, "foo"); defer img.deinit(alloc); const h = try img.element().renderHTML(alloc); defer alloc.free(h); try expect(eql(u8, h, "")); img.alt = "bar"; const h2 = try img.element().renderHTML(alloc); defer alloc.free(h2); try expect(eql(u8, h2, "\"bar\"")); }