╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────╮ │1 const std = @import("std"); │ │2 +const ui = @import("./ui.zig");│ │3 │ │4 const Asset = struct { │ │5 path: []const u8, │ ╰──────────────────────────────────╯ ╭───────────────────────────────────────╮ │16 │ │17 pub fn run( │ │18 io: std.Io, │ │19 + allocator: std.mem.Allocator, │ │20 net_server: *std.Io.net.Server,│ │21 tasks: *std.Io.Group, │ │22 err: *std.Io.Writer, │ ╰───────────────────────────────────────╯ ╭───────────────────────────────────────────╮ │23 ) void { │ │24 const Listener = struct { │ │25 io: std.Io, │ │26 + allocator: std.mem.Allocator, │ │27 net_server: *std.Io.net.Server,│ │28 tasks: *std.Io.Group, │ │29 err: *std.Io.Writer, │ ╰───────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────╮ │38 │ │39 const Connection = struct { │ │40 io: std.Io, │ │41 + allocator: std.mem.Allocator,│ │42 stream: std.Io.net.Stream, │ │43 err: *std.Io.Writer, │ │44 │ ╰─────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │45 fn run(conn: @This()) void { │ │46 defer conn.stream.close(conn.io); │ │43 - handleConnection(conn.io, conn.stream, conn.err) catch |request_err| { │ │47 + handleConnection(conn.io, conn.allocator, conn.stream, conn.err) catch |request_err| {│ │48 logError(conn.err, "web ui request failed: {s}\n", .{@errorName(request_err)}); │ │49 }; │ │50 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │52 │ │53 ctx.tasks.async(ctx.io, Connection.run, .{Connection{│ │54 .io = ctx.io, │ │55 + .allocator = ctx.allocator, │ │56 .stream = stream, │ │57 .err = ctx.err, │ │58 }}); │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────╮ │62 │ │63 tasks.async(io, Listener.run, .{Listener{│ │64 .io = io, │ │65 + .allocator = allocator, │ │66 .net_server = net_server, │ │67 .tasks = tasks, │ │68 .err = err, │ ╰─────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │69 }}); │ │70 +} │ │71 + │ │72 +fn renderIndexHtml(allocator: std.mem.Allocator) ![]const u8 { │ │73 + const template = (findAsset("/index.html") orelse return error.MissingIndexAsset).body; │ │74 + │ │75 + var root = try ui.initRoot(allocator); │ │76 + defer root.deinit(); │ │77 + │ │78 + const content = try ui.generateHtml(allocator, &root); │ │79 + defer allocator.free(content); │ │80 + │ │81 + const needle = "{{{ HAXY_CONTENT }}}"; │ │82 + const index = std.mem.indexOf(u8, template, needle) orelse return error.MissingTemplateToken;│ │83 + │ │84 + var out: std.ArrayList(u8) = .empty; │ │85 + errdefer out.deinit(allocator); │ │86 + try out.appendSlice(allocator, template[0..index]); │ │87 + try out.appendSlice(allocator, content); │ │88 + try out.appendSlice(allocator, template[index + needle.len ..]); │ │89 + return try out.toOwnedSlice(allocator); │ │90 } │ │91 │ │92 fn handleConnection( │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────╮ │93 io: std.Io, │ │94 + allocator: std.mem.Allocator,│ │95 stream: std.Io.net.Stream, │ │96 err: *std.Io.Writer, │ │97 ) !void { │ ╰─────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │108 else => |e| return e, │ │109 }; │ │110 │ │ 84 - handleRequest(&http_server, &request) catch |request_err| { │ │111 + handleRequest(&http_server, &request, allocator) catch |request_err| { │ │112 try err.print("web ui request failed: {s}\n", .{@errorName(request_err)});│ │113 try err.flush(); │ │114 if (http_server.reader.state == .received_head) { │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯