mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 15:14:08 +00:00
139 lines
4.3 KiB
Zig
139 lines
4.3 KiB
Zig
const std = @import("std");
|
|
const zap = @import("zap");
|
|
const Users = @import("users.zig");
|
|
const User = Users.User;
|
|
|
|
// an Endpoint
|
|
|
|
pub const UserWeb = @This();
|
|
|
|
alloc: std.mem.Allocator = undefined,
|
|
_users: Users = undefined,
|
|
|
|
path: []const u8,
|
|
error_strategy: zap.Endpoint.ErrorStrategy = .log_to_response,
|
|
|
|
pub fn init(
|
|
a: std.mem.Allocator,
|
|
user_path: []const u8,
|
|
) UserWeb {
|
|
return .{
|
|
.alloc = a,
|
|
._users = Users.init(a),
|
|
.path = user_path,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *UserWeb) void {
|
|
self._users.deinit();
|
|
}
|
|
|
|
pub fn users(self: *UserWeb) *Users {
|
|
return &self._users;
|
|
}
|
|
|
|
fn userIdFromPath(self: *UserWeb, path: []const u8) ?usize {
|
|
if (path.len >= self.path.len + 2) {
|
|
if (path[self.path.len] != '/') {
|
|
return null;
|
|
}
|
|
const idstr = path[self.path.len + 1 ..];
|
|
return std.fmt.parseUnsigned(usize, idstr, 10) catch null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// not implemented
|
|
// pub fn put(_: *UserWeb, _: zap.Request) !void {}
|
|
|
|
pub fn get(self: *UserWeb, r: zap.Request) !void {
|
|
if (r.path) |path| {
|
|
// /users
|
|
if (path.len == self.path.len) {
|
|
return self.listUsers(r);
|
|
}
|
|
var jsonbuf: [256]u8 = undefined;
|
|
if (self.userIdFromPath(path)) |id| {
|
|
if (self._users.get(id)) |user| {
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, user, .{});
|
|
try r.sendJson(json);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn listUsers(self: *UserWeb, r: zap.Request) !void {
|
|
if (self._users.toJSON()) |json| {
|
|
defer self.alloc.free(json);
|
|
try r.sendJson(json);
|
|
} else |err| {
|
|
return err;
|
|
}
|
|
}
|
|
|
|
pub fn post(self: *UserWeb, r: zap.Request) !void {
|
|
if (r.body) |body| {
|
|
const maybe_user: ?std.json.Parsed(User) = std.json.parseFromSlice(User, self.alloc, body, .{}) catch null;
|
|
if (maybe_user) |u| {
|
|
defer u.deinit();
|
|
if (self._users.addByName(u.value.first_name, u.value.last_name)) |id| {
|
|
var jsonbuf: [128]u8 = undefined;
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
|
|
try r.sendJson(json);
|
|
} else |err| {
|
|
std.debug.print("ADDING error: {}\n", .{err});
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn patch(self: *UserWeb, r: zap.Request) !void {
|
|
if (r.path) |path| {
|
|
if (self.userIdFromPath(path)) |id| {
|
|
if (self._users.get(id)) |_| {
|
|
if (r.body) |body| {
|
|
const maybe_user: ?std.json.Parsed(User) = std.json.parseFromSlice(User, self.alloc, body, .{}) catch null;
|
|
if (maybe_user) |u| {
|
|
defer u.deinit();
|
|
var jsonbuf: [128]u8 = undefined;
|
|
if (self._users.update(id, u.value.first_name, u.value.last_name)) {
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
|
|
try r.sendJson(json);
|
|
} else {
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{});
|
|
try r.sendJson(json);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn delete(self: *UserWeb, r: zap.Request) !void {
|
|
if (r.path) |path| {
|
|
if (self.userIdFromPath(path)) |id| {
|
|
var jsonbuf: [128]u8 = undefined;
|
|
if (self._users.delete(id)) {
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "OK", .id = id }, .{});
|
|
try r.sendJson(json);
|
|
} else {
|
|
const json = try zap.util.stringifyBuf(&jsonbuf, .{ .status = "ERROR", .id = id }, .{});
|
|
try r.sendJson(json);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn options(_: *UserWeb, r: zap.Request) !void {
|
|
try r.setHeader("Access-Control-Allow-Origin", "*");
|
|
try r.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD");
|
|
r.setStatus(zap.http.StatusCode.no_content);
|
|
r.markAsFinished(true);
|
|
}
|
|
|
|
pub fn head(_: *UserWeb, r: zap.Request) !void {
|
|
r.setStatus(zap.http.StatusCode.no_content);
|
|
r.markAsFinished(true);
|
|
}
|