diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2026-05-23 07:11:00 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2026-05-23 07:11:00 +0200 |
| commit | f109fb62b7e45d54b0c9f524a0707f3c2688b6cb (patch) | |
| tree | e539196b2b97fc3e8f11837c4638288b8494ff80 | |
| parent | 79ba17323c33c7e7e6b4b3ef526db85f1cf9c086 (diff) | |
add api sketch
| -rw-r--r-- | build.zig | 2 | ||||
| -rw-r--r-- | flake.nix | 2 | ||||
| -rw-r--r-- | src/api/root.zig | 2 | ||||
| -rw-r--r-- | src/api/sketch.zig | 29 | ||||
| -rw-r--r-- | src/frontend/Minifier.zig | 4 | ||||
| -rw-r--r-- | src/http/Server.zig | 20 | ||||
| -rw-r--r-- | src/http/Url.zig | 39 | ||||
| -rw-r--r-- | src/http/root.zig | 3 | ||||
| -rw-r--r-- | src/main.zig | 4 |
9 files changed, 101 insertions, 4 deletions
@@ -32,6 +32,8 @@ pub fn build(b: *std.Build) void { .target = target, }); + api_mod.addImport("http", http_mod); + const exe = b.addExecutable(.{ .name = "memora", .root_module = b.createModule(.{ @@ -21,12 +21,14 @@ buildInputs = [ pkgs.zig + pkgs.sqlite ]; }; devShells.x86_64-linux.default = pkgs.mkShell { packages = [ pkgs.zig + pkgs.sqlite ]; }; }; diff --git a/src/api/root.zig b/src/api/root.zig index 5128aa1..c28991c 100644 --- a/src/api/root.zig +++ b/src/api/root.zig @@ -3,6 +3,8 @@ const std = @import("std"); +pub const _ = @import("sketch.zig"); + test { _ = std.testing.refAllDecls(@This()); } diff --git a/src/api/sketch.zig b/src/api/sketch.zig new file mode 100644 index 0000000..409606f --- /dev/null +++ b/src/api/sketch.zig @@ -0,0 +1,29 @@ +const std = @import("std"); +const http = @import("http"); + +pub const Url = http.Url.Template( + "/api/images/{id}/metadata/{name}", + .{ + .guard = Auth(.admin), + } +); + +const Query = struct { + condition: []const u8, + start: usize, + end: usize, +} + +pub fn post(request: http.Request(Url)) !http.Response { + const query = try request.body.json(Query, request.arena); + + return .string(request.params.id); +} + +pub fn get(request: http.Request(Url)) !http.Response { + return .file("./some/path.txt"); +} + +test { + _ = std.testing.refAllDecls(@This()); +} diff --git a/src/frontend/Minifier.zig b/src/frontend/Minifier.zig index 541bbe1..65dd9fb 100644 --- a/src/frontend/Minifier.zig +++ b/src/frontend/Minifier.zig @@ -55,7 +55,6 @@ pub fn minify( var block: []const u8 = ""; while (content.len > 0) { - const had_comment: bool = cmt: { inline for (self.comments) |comment| { const start, const end = comment; @@ -69,8 +68,7 @@ pub fn minify( break :cmt false; }; - if (had_comment) { - } else if (std.mem.indexOfScalar(u8, self.quotes, content[0])) |_| { + if (had_comment) {} else if (std.mem.indexOfScalar(u8, self.quotes, content[0])) |_| { const quote = content[0]; push(&content, &block, 1); while (content.len > 0) { diff --git a/src/http/Server.zig b/src/http/Server.zig new file mode 100644 index 0000000..b6e2d90 --- /dev/null +++ b/src/http/Server.zig @@ -0,0 +1,20 @@ +const std = @import("std"); + +const Self = @This(); + +server: std.Io.net.Server, +io: std.Io.Threaded, + +pub fn init( + gpa: std.mem.Allocator, + address: std.Io.net.IpAddress, +) !Self { + var io: std.Io.Threaded = .init(gpa, .{}); + + return .{ + .io = io, + .server = try address.listen(io.io(), .{ .reuse_address = true }), + }; +} + +pub fn serve(_: *Self) !void {} diff --git a/src/http/Url.zig b/src/http/Url.zig new file mode 100644 index 0000000..4a0a2b0 --- /dev/null +++ b/src/http/Url.zig @@ -0,0 +1,39 @@ +const std = @import("std"); + +const Segment = union(enum) { + literal: []const u8, + parameter: []const u8, + + pub fn format(self: @This(), writer: *std.Io.Writer) !void { + try writer.print("{s}{{ {s} }}", .{ @tagName(self), switch (self) { + inline else => |s| s, + } }); + } +}; + +pub fn Template(comptime template: []const u8) []const Segment { + var segments: []const Segment = &.{}; + var t = template; + + if (template.len == 0 or template[0] != '/') { + @compileError("template needs to be absolute"); + } + + while (t.len > 0) { + const index = std.mem.indexOfScalar(u8, t, '/'); + const segment = t[0 .. index orelse t.len]; + t = t[(index orelse t.len - 1) + 1 ..]; + + if (segment.len > 0) { + const s: []const Segment = &.{seg: { + if (segment[0] == '{' and segment[segment.len - 1] == '}') { + break :seg .{ .parameter = segment[1 .. segment.len - 1] }; + } else { + break :seg .{ .literal = segment }; + } + }}; + segments = segments ++ s; + } + } + return segments; +} diff --git a/src/http/root.zig b/src/http/root.zig index 743e1c4..317dacd 100644 --- a/src/http/root.zig +++ b/src/http/root.zig @@ -2,6 +2,9 @@ const std = @import("std"); +pub const Server = @import("Server.zig"); +pub const Url = @import("Url.zig"); + test { _ = std.testing.refAllDecls(@This()); } diff --git a/src/main.zig b/src/main.zig index 1a66b63..df0c061 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4,9 +4,11 @@ //! but also the actual running of the server / webapp. const std = @import("std"); +const http = @import("http"); pub fn main(init: std.process.Init) !void { - _ = init; + var server: http.Server = try .init(init.gpa, try .parseLiteral("127.0.0.1:8080")); + try server.serve(); } test { |