zig-webui
zig-webui copied to clipboard
feat: try to add embed folder
Try this Zig version of vfs.py, I did not test it yet.
- Run
python vfs.py "myFolder" "vfs.zig" - Import
vfs.ziginmain.zigof the serve_a_folder example - Set
vfsas file the handlerMyWindow.setFileHandler(vfs);
vfs.py:
import os
import sys
def generate_vfs_zig(directory, output_file):
files = []
index_files = {}
for root, _, filenames in os.walk(directory):
for filename in filenames:
filepath = os.path.join(root, filename)
relative_path = os.path.relpath(filepath, directory)
# Ensure path starts with a slash
relative_path = '/' + relative_path.replace('\\', '/')
files.append((relative_path, filepath))
# Check for index files
if filename.startswith("index."):
dir_path = os.path.dirname(relative_path)
if dir_path not in index_files:
index_files[dir_path] = relative_path
with open(output_file, 'w') as zig_file:
zig_file.write('const std = @import("std");\n')
zig_file.write('const webui = @import("webui");\n\n')
zig_file.write('pub const VirtualFile = struct {\n')
zig_file.write(' path: []const u8,\n')
zig_file.write(' data: []const u8,\n')
zig_file.write(' length: usize,\n')
zig_file.write('};\n\n')
zig_file.write('pub const virtual_files = []const VirtualFile{\n')
for relative_path, filepath in files:
with open(filepath, 'rb') as f:
data = f.read()
zig_file.write(' VirtualFile{\n')
zig_file.write(f' .path = "{relative_path}",\n')
zig_file.write(' .data = &[_]u8{')
zig_file.write(','.join(f'0x{byte:02x}' for byte in data))
zig_file.write('},\n')
zig_file.write(f' .length = {len(data)},\n')
zig_file.write(' },\n')
zig_file.write('};\n\n')
zig_file.write('pub const virtual_files_count = @sizeOf(virtual_files) / @sizeOf(virtual_files[0]);\n\n')
zig_file.write('pub const index_files = []const struct {\n')
zig_file.write(' dir_path: []const u8,\n')
zig_file.write(' index_path: []const u8,\n')
zig_file.write('}{\n')
for dir_path, index_path in index_files.items():
zig_file.write(f' .{{ "{dir_path}/", "{index_path}" }},\n')
zig_file.write('};\n\n')
zig_file.write('pub fn virtualFileSystem(path: []const u8) ?[]const u8 {\n')
zig_file.write(' for (virtual_files) |file| {\n')
zig_file.write(' if (std.mem.eql(u8, file.path, path)) {\n')
zig_file.write(' return file.data;\n')
zig_file.write(' }\n')
zig_file.write(' }\n')
zig_file.write(' return null;\n')
zig_file.write('}\n\n')
zig_file.write('pub fn vfs(path: []const u8) ?[]const u8 {\n')
zig_file.write(' const file_data = virtualFileSystem(path);\n\n')
zig_file.write(' if (file_data) |data| {\n')
zig_file.write(' const content_type = webui.getMimeType(path);\n')
zig_file.write(' const header = std.fmt.bufPrint(\n')
zig_file.write(' "HTTP/1.1 200 OK\\r\\nContent-Type: {s}\\r\\nContent-Length: {d}\\r\\nCache-Control: no-cache\\r\\n\\r\\n",\n')
zig_file.write(' .{content_type, data.len}\n')
zig_file.write(' );\n')
zig_file.write(' return header ++ data;\n')
zig_file.write(' } else {\n')
zig_file.write(' // Check for index file redirection\n')
zig_file.write(' var redirect_path = std.mem.concat(u8, path, "/");\n')
zig_file.write(' for (index_files) |entry| {\n')
zig_file.write(' if (std.mem.eql(u8, entry.dir_path, redirect_path)) {\n')
zig_file.write(' const header = std.fmt.bufPrint(\n')
zig_file.write(' "HTTP/1.1 302 Found\\r\\nLocation: {s}\\r\\nCache-Control: no-cache\\r\\n\\r\\n",\n')
zig_file.write(' .{entry.index_path}\n')
zig_file.write(' );\n')
zig_file.write(' return header;\n')
zig_file.write(' }\n')
zig_file.write(' }\n')
zig_file.write(' return null;\n')
zig_file.write(' }\n')
zig_file.write('}\n')
if __name__ == '__main__':
if len(sys.argv) != 3:
print(f'Usage: {sys.argv[0]} <directory> <output_zig>')
sys.exit(1)
directory = sys.argv[1]
output_zig = sys.argv[2]
generate_vfs_zig(directory, output_zig)
print(f'Generated {output_zig} from {directory}')
A better solution can be achieved through zig theory, but there may not be time recently
And I think this is not a priority to solve, because zig itself supports embedded files, but does not support embedded folders.