about summary refs log tree commit diff
path: root/src/Content.zig
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2026-09-18 04:00:18 +0200
committerRobert Günzler <r@gnzler.io>2026-09-22 22:37:51 +0200
commit5bc242742e1225c7c3b87a31c2c2a3998ac18685 (patch)
treebaae923037b49ba31bb0a15ece2eec4bea13ab25 /src/Content.zig
parentc677e8873e0eae790a1b8b07844a10efa9f63a1e (diff)
downloadsite-5bc242742e1225c7c3b87a31c2c2a3998ac18685.tar.gz
v2
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to 'src/Content.zig')
-rw-r--r--src/Content.zig210
1 files changed, 0 insertions, 210 deletions
diff --git a/src/Content.zig b/src/Content.zig
deleted file mode 100644
index 120d8b5..0000000
--- a/src/Content.zig
+++ /dev/null
@@ -1,210 +0,0 @@
-const std = @import("std");
-const os = @import("os.zig");
-
-const Content = @This();
-const log = std.log.scoped(.Content);
-
-pub const Digest = [64]u8;
-
-io: std.Io,
-arena: *std.heap.ArenaAllocator,
-root: std.Io.Dir,
-
-pub fn init(io: std.Io, allocator: std.mem.Allocator, root_dir: std.Io.Dir) !Content {
-    const arena = try allocator.create(std.heap.ArenaAllocator);
-    errdefer allocator.destroy(arena);
-    arena.* = std.heap.ArenaAllocator.init(allocator);
-
-    return .{
-        .io = io,
-        .arena = arena,
-        .root = root_dir,
-    };
-}
-
-pub fn deinit(self: *Content) void {
-    self.root.close(self.io);
-    const allocator = self.arena.child_allocator;
-    self.arena.deinit();
-    allocator.destroy(self.arena);
-}
-
-pub fn digest(self: *Content, dir: std.Io.Dir, sub_path: []const u8) !Digest {
-    // generate sha256 digest
-    // TODO: use zig-based hashing?
-    const command = blk: {
-        var buf: [std.os.linux.PATH_MAX + 10]u8 = undefined;
-        @memcpy(buf[0..10], "sha256sum ");
-        @memcpy(buf[10 .. 10 + sub_path.len], sub_path);
-        break :blk buf[0 .. 10 + sub_path.len];
-    };
-    var buf: [std.os.linux.PATH_MAX + 64]u8 = undefined;
-    var w = std.Io.Writer.fixed(&buf);
-    try os.captureStdout(self.io, command, .{ .cwd = .{ .dir = dir } }, &w);
-
-    // take only the digest
-    return buf[0..64].*;
-}
-
-pub fn get(self: *Content, dgst: Digest) !?Digest {
-    const found = blk: {
-        self.root.access(self.io, &dgst, .{}) catch |err| switch (err) {
-            error.FileNotFound => break :blk false,
-            else => return err,
-        };
-        break :blk true;
-    };
-    if (found) {
-        return dgst;
-    } else {
-        return null;
-    }
-}
-
-pub fn add(self: *Content, dir: std.Io.Dir, sub_path: []const u8) !Digest {
-    const dgst = try self.digest(dir, sub_path);
-
-    return (try self.get(dgst)) orelse {
-        // create digest directory
-        try self.root.createDirPath(self.io, &dgst);
-
-        log.debug("Added {s}", .{dgst});
-        return dgst;
-    };
-}
-
-pub fn del(self: *Content, dgst: Digest) !void {
-    try self.root.deleteTree(self.io, &dgst);
-}
-
-const Enumerator = struct {
-    content: *Content,
-    walker: std.Io.Dir.SelectiveWalker,
-
-    pub fn deinit(self: *Enumerator) void {
-        self.walker.deinit();
-    }
-
-    pub fn next(self: *Enumerator) !?Digest {
-        if (try self.walker.next(self.content.io)) |e| {
-            switch (e.kind) {
-                // TODO: we should probably check that this is actually a digest
-                .directory => return e.basename[0..64].*,
-                else => return null,
-            }
-        } else {
-            return null;
-        }
-    }
-};
-
-pub fn enumerate(self: *Content, allocator: std.mem.Allocator) !Enumerator {
-    return .{
-        .walker = try self.root.walkSelectively(allocator),
-        .content = self,
-    };
-}
-
-pub fn propSet(self: *Content, dgst: Digest, key: []const u8, val: ?[]const u8) !void {
-    const digest_dir = try self.root.openDir(self.io, &dgst, .{});
-    defer digest_dir.close(self.io);
-
-    if (val == null) {
-        return try digest_dir.deleteFile(self.io, key);
-    }
-
-    return try digest_dir.writeFile(self.io, .{
-        .sub_path = key,
-        .data = val.?,
-    });
-}
-
-pub fn propGet(self: *Content, dgst: Digest, key: []const u8, allocator: std.mem.Allocator) !?[]const u8 {
-    const digest_dir = try self.root.openDir(self.io, &dgst, .{});
-    defer digest_dir.close(self.io);
-
-    if (digest_dir.readFileAlloc(self.io, key, allocator, .unlimited)) |val| {
-        return val;
-    } else |err| switch (err) {
-        error.FileNotFound => return null,
-        else => return err,
-    }
-}
-
-// fn checkLink(self: *Content, allocator: std.mem.Allocator, dgst: Digest) ![]const u8 {
-//     const link_target = try self.propGet(dgst, "link", allocator);
-//     // check target exists
-//     try std.Io.Dir.cwd().access(self.io, link_target, .{ .read = true });
-//     return link_target;
-// }
-
-test "e2e" {
-    std.testing.log_level = .debug;
-
-    const DEMO_DIR: []const u8 = "/home/robert/tmp/rbc-demo/";
-    const CONTENT_DIR: []const u8 = DEMO_DIR ++ ".content";
-
-    try std.Io.Dir.cwd().deleteTree(std.testing.io, CONTENT_DIR);
-
-    const demo_dir = try std.Io.Dir.cwd().openDir(std.testing.io, DEMO_DIR, .{ .iterate = true });
-    const content_dir = try std.Io.Dir.cwd().createDirPathOpen(std.testing.io, CONTENT_DIR, .{ .open_options = .{ .iterate = true } });
-
-    var cnt = try Content.init(std.testing.io, std.testing.allocator, content_dir);
-    defer cnt.deinit();
-
-    {
-        var walker = try demo_dir.walkSelectively(std.testing.allocator);
-        defer walker.deinit();
-
-        while (try walker.next(std.testing.io)) |e| {
-            switch (e.kind) {
-                .file => {
-                    log.info("+ {s}", .{e.path});
-                    const dgst = try cnt.add(demo_dir, e.path);
-                    try content_dir.access(std.testing.io, &dgst, .{});
-                    const rel = try std.fs.path.relativePosix(std.testing.allocator, DEMO_DIR, CONTENT_DIR, e.path);
-                    defer std.testing.allocator.free(rel);
-                    try cnt.propSet(dgst, "link", rel);
-                },
-                else => {},
-            }
-        }
-    }
-
-    var etor = try cnt.enumerate(std.testing.allocator);
-    defer etor.deinit();
-
-    {
-        const dgst = try etor.next();
-        try std.testing.expect(dgst != null);
-
-        try cnt.propSet(dgst.?, "foo", "bar");
-        const val1 = try cnt.propGet(dgst.?, "foo", std.testing.allocator);
-        try std.testing.expect(val1 != null);
-        defer std.testing.allocator.free(val1);
-        try std.testing.expect(std.mem.eql(u8, "bar", val1.?));
-
-        try cnt.propSet(dgst.?, "foo", null);
-        const val2 = try cnt.propGet(dgst.?, "foo", std.testing.allocator);
-        try std.testing.expect(val2 == null);
-    }
-
-    {
-        const dgst = try etor.next();
-        try std.testing.expect(dgst != null);
-
-        try cnt.del(dgst.?);
-        const err = content_dir.access(std.testing.io, &dgst.?, .{});
-        try std.testing.expectError(error.FileNotFound, err);
-    }
-
-    while (try etor.next()) |dgst| {
-        log.info("? {s}", .{dgst});
-        try content_dir.access(std.testing.io, &dgst, .{});
-        const link = try cnt.propGet(dgst, "link", std.testing.allocator);
-        try std.testing.expect(link != null);
-        defer std.testing.allocator.free(link.?);
-        try content_dir.access(std.testing.io, link.?, .{});
-        log.info("l {s}", .{link.?});
-    }
-}