diff --git a/src/main/api.zig b/src/main/api.zig index 835d649..27b1546 100644 --- a/src/main/api.zig +++ b/src/main/api.zig @@ -63,6 +63,16 @@ pub const ApiServer = struct { return note; } + pub fn createUser(self: *ApiServer, info: CreateInfo(models.User)) !models.User { + const id = Uuid.randV4(self.prng.random()); + // TODO: check for dupes + + const user = reify(models.User, id, info); + try self.db.putUser(user); + + return user; + } + pub fn getNote(self: *ApiServer, id: Uuid, alloc: std.mem.Allocator) !?models.Note { return self.db.getNote(id, alloc); } diff --git a/src/main/db.zig b/src/main/db.zig index 4151631..df152cb 100644 --- a/src/main/db.zig +++ b/src/main/db.zig @@ -51,18 +51,15 @@ pub fn free(alloc: std.mem.Allocator, val: anytype) void { pub const Database = struct { internal_alloc: std.mem.Allocator, notes: std.AutoHashMap(Uuid, models.Note), + users: std.AutoHashMap(Uuid, models.User), pub fn init(alloc: std.mem.Allocator) !Database { var db = Database{ .internal_alloc = alloc, .notes = std.AutoHashMap(Uuid, models.Note).init(alloc), + .users = std.AutoHashMap(Uuid, models.User).init(alloc), }; - try db.putNote(models.Note{ - .id = Uuid{ .data = @bitCast([16]u8, @as(u128, 1)) }, - .content = "abcd", - }); - return db; } @@ -97,6 +94,29 @@ pub const Database = struct { } try self.notes.put(key, copy); } + + pub fn containsUser(self: *Database, id: Uuid) !bool { + return self.users.contains(id); + } + + // returns a copy of the note data from storage. memory is allocated with the provided + // allocator. can be freed using free() above + pub fn getUser(self: *Database, id: Uuid, alloc: std.mem.Allocator) !?models.User { + const note = self.users.get(id) orelse return null; + return try clone(alloc, note); + } + + pub fn putUser(self: *Database, note: models.User) !void { + const copy = try clone(self.internal_alloc, note); + errdefer free(self.internal_alloc, copy); + + const key = copy.id; + + if (self.users.fetchRemove(key)) |e| { + free(self.internal_alloc, e.value); + } + try self.users.put(key, copy); + } }; test "clone" { diff --git a/src/main/main.zig b/src/main/main.zig index c4d328e..072fb5a 100644 --- a/src/main/main.zig +++ b/src/main/main.zig @@ -14,8 +14,9 @@ const RouteArgs = http.RouteArgs; const router = Router{ .routes = &[_]Route{ Route.new(.GET, "/healthcheck", healthcheck), - Route.new(.GET, "/:id", getNote), - Route.new(.POST, "/", createNote), + Route.new(.GET, "/notes/:id", getNote), + Route.new(.POST, "/notes", createNote), + Route.new(.POST, "/users", createUser), }, }; @@ -70,6 +71,15 @@ fn createNote(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !voi try respondJson(ctx, .created, note, srv.alloc); } +fn createUser(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void { + const info = try parseRequestBody(api.CreateInfo(models.User), ctx, srv.alloc); + defer freeRequestBody(info, srv.alloc); + + const user = try srv.api.createUser(info); + + try respondJson(ctx, .created, user, srv.alloc); +} + fn getNote(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs) !void { const id_str = args.get("id") orelse return error.NotFound; const id = Uuid.parse(id_str) catch return respondJson(ctx, .bad_request, .{ .@"error" = "Invalid UUID" }, srv.alloc); diff --git a/src/main/models.zig b/src/main/models.zig index eac6bbe..589ca35 100644 --- a/src/main/models.zig +++ b/src/main/models.zig @@ -4,3 +4,8 @@ pub const Note = struct { id: Uuid, content: []const u8, }; + +pub const User = struct { + id: Uuid, + handle: []const u8, +};