Hey
this is my first Post and also my first attempts at metaprogramming.
For my Project im working on, i needed some icons and found them in the form of SVGs.
Because i want this project to be small and minimal, and because i need the icons the whole time the Program is running, i want to embed these.
… so far so easy …
But DVUI (the UI lib im using) only talks TVG not SVG.
There is a function provided by DVUI dvui.svgToTvg(...) which works fine, but it wants to alloc those, that way my program would have the SVGs embedded and the TVGs on the heap, also … i would create the TVGs every time the Program is setting up.
I don’t want this.
I could just convert all of my assets by hand,… but i also dont like this. I want my assets to be just a folder of SVGs!
So… i managed to get the following working and would like to know if there is anything bad/dirty with it and most importantly: Is there an easier way?
(comptime blocks dont support Io in my findings, right?)
Also, are my generated TVGs really embedded this way?
My meta file:
const std = @import("std");
const dvui = @import("dvui");
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const args = try init.minimal.args.toSlice(arena);
const cwd = std.Io.Dir.cwd();
const assets = try cwd.openDir(init.io, "src/assets", .{ .iterate = true });
defer assets.close(init.io);
var output: std.ArrayList(u8) = try .initCapacity(arena, 100 * 1024);
try output.print(
arena,
"pub const Tvgs = struct {s}\n",
.{"{"},
);
var names: std.ArrayList([]const u8) = .empty;
var asset_iter = try assets.walk(arena);
while (try asset_iter.next(init.io)) |svg| {
const svg_data = try assets.readFileAlloc(init.io, svg.path, arena, .unlimited);
const tvg = try dvui.svgToTvg(arena, svg_data);
var name_buf: [1024]u8 = undefined;
_ = std.mem.replace(u8, svg.basename, "-", "_", &name_buf);
const name = try arena.alloc(u8, name_buf[0 .. svg.basename.len - 4].len);
std.mem.copyForwards(u8, name, name_buf[0 .. svg.basename.len - 4]);
try output.print(
arena,
"const {s}_const: [{d}]u8 = .{s} ",
.{ name, tvg.len, "{" },
);
try names.append(arena, name);
for (tvg) |b| {
try output.print(
arena,
"{d}, ",
.{b},
);
}
try output.print(
arena,
"{s};\n",
.{"}"},
);
}
for (names.items) |name| {
try output.print(
arena,
"{s}: []const u8 = &Tvgs.{s}_const,\n",
.{ name, name },
);
}
try output.print(
arena,
"{s};\n",
.{"}"},
);
var output_file = try cwd.createFile(init.io, args[1], .{});
defer output_file.close(init.io);
try output_file.writeStreamingAll(init.io, output.items);
return std.process.cleanExit(init.io);
}
it gets embedded like this example here.