Use new controller layout
This commit is contained in:
parent
228b9490ef
commit
add17c0a0a
10 changed files with 110 additions and 205 deletions
|
@ -13,14 +13,12 @@ const services = struct {
|
||||||
const notes = @import("./services/notes.zig");
|
const notes = @import("./services/notes.zig");
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RegistrationRequest = struct {
|
pub const RegistrationOptions = struct {
|
||||||
username: []const u8,
|
invite_code: ?[]const u8 = null,
|
||||||
password: []const u8,
|
|
||||||
invite_code: []const u8,
|
|
||||||
email: ?[]const u8 = null,
|
email: ?[]const u8 = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const InviteRequest = struct {
|
pub const InviteOptions = struct {
|
||||||
pub const Kind = services.invites.Kind;
|
pub const Kind = services.invites.Kind;
|
||||||
|
|
||||||
name: ?[]const u8 = null,
|
name: ?[]const u8 = null,
|
||||||
|
@ -227,7 +225,7 @@ fn ApiConn(comptime DbConn: type) type {
|
||||||
return community;
|
return community;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createInvite(self: *Self, options: InviteRequest) !services.invites.Invite {
|
pub fn createInvite(self: *Self, options: InviteOptions) !services.invites.Invite {
|
||||||
// Only logged in users can make invites
|
// Only logged in users can make invites
|
||||||
const user_id = self.user_id orelse return error.TokenRequired;
|
const user_id = self.user_id orelse return error.TokenRequired;
|
||||||
|
|
||||||
|
@ -251,26 +249,33 @@ fn ApiConn(comptime DbConn: type) type {
|
||||||
return try services.invites.get(self.db, invite_id, self.arena.allocator());
|
return try services.invites.get(self.db, invite_id, self.arena.allocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(self: *Self, request: RegistrationRequest) !UserResponse {
|
pub fn register(self: *Self, username: []const u8, password: []const u8, opt: RegistrationOptions) !UserResponse {
|
||||||
std.log.debug("registering user {s} with code {s}", .{ request.username, request.invite_code });
|
std.log.debug("registering user {s} with code {?s}", .{ username, opt.invite_code });
|
||||||
const invite = try services.invites.getByCode(self.db, request.invite_code, self.community.id, self.arena.allocator());
|
const maybe_invite = if (opt.invite_code) |code|
|
||||||
|
try services.invites.getByCode(self.db, code, self.community.id, self.arena.allocator())
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
if (!Uuid.eql(invite.community_id, self.community.id)) return error.NotFound;
|
if (maybe_invite) |invite| {
|
||||||
|
if (!Uuid.eql(invite.community_id, self.community.id)) return error.WrongCommunity;
|
||||||
if (invite.max_uses != null and invite.times_used >= invite.max_uses.?) return error.InviteExpired;
|
if (invite.max_uses != null and invite.times_used >= invite.max_uses.?) return error.InviteExpired;
|
||||||
if (invite.expires_at != null and DateTime.now().isAfter(invite.expires_at.?)) return error.InviteExpired;
|
if (invite.expires_at != null and DateTime.now().isAfter(invite.expires_at.?)) return error.InviteExpired;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invite_kind = if (maybe_invite) |inv| inv.kind else .user;
|
||||||
|
|
||||||
if (self.community.kind == .admin) @panic("Unimplmented");
|
if (self.community.kind == .admin) @panic("Unimplmented");
|
||||||
|
|
||||||
const user_id = try services.auth.register(
|
const user_id = try services.auth.register(
|
||||||
self.db,
|
self.db,
|
||||||
request.username,
|
username,
|
||||||
request.password,
|
password,
|
||||||
self.community.id,
|
self.community.id,
|
||||||
.{ .invite_id = invite.id, .email = request.email },
|
.{ .invite_id = if (maybe_invite) |inv| inv.id else null, .email = opt.email },
|
||||||
self.arena.allocator(),
|
self.arena.allocator(),
|
||||||
);
|
);
|
||||||
|
|
||||||
switch (invite.kind) {
|
switch (invite_kind) {
|
||||||
.user => {},
|
.user => {},
|
||||||
.system => @panic("System user invites unimplemented"),
|
.system => @panic("System user invites unimplemented"),
|
||||||
.community_owner => {
|
.community_owner => {
|
||||||
|
|
|
@ -13,40 +13,26 @@ pub const invites = @import("./controllers/invites.zig");
|
||||||
pub const users = @import("./controllers/users.zig");
|
pub const users = @import("./controllers/users.zig");
|
||||||
pub const notes = @import("./controllers/notes.zig");
|
pub const notes = @import("./controllers/notes.zig");
|
||||||
|
|
||||||
pub fn routeRequest(api_source: anytype, request: http.Request, response: http.Response, alloc: std.mem.Allocator) void {
|
pub fn routeRequest(api_source: anytype, ctx: http.server.Context, alloc: std.mem.Allocator) void {
|
||||||
// TODO: hashmaps?
|
// TODO: hashmaps?
|
||||||
inline for (routes) |route| {
|
inline for (routes) |route| {
|
||||||
if (Context(route).matchAndHandle(api_source, request, response, alloc)) return;
|
if (Context(route).matchAndHandle(api_source, ctx, alloc)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo 404
|
var response = Response{ .headers = http.Headers.init(alloc), .ctx = ctx };
|
||||||
|
defer response.headers.deinit();
|
||||||
|
|
||||||
|
response.status(.not_found) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const routes = .{ sample_api, invites.create };
|
const routes = .{
|
||||||
|
auth.login,
|
||||||
pub const sample_api = struct {
|
auth.verify_login,
|
||||||
const Self = @This();
|
communities.create,
|
||||||
|
invites.create,
|
||||||
pub const method = .POST;
|
users.create,
|
||||||
pub const path = "/notes/:id/reacts";
|
notes.create,
|
||||||
pub const content_type = "application/json";
|
//notes.get,
|
||||||
|
|
||||||
pub const Args = struct {
|
|
||||||
id: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Body = struct {
|
|
||||||
content: util.Uuid,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Query = struct {
|
|
||||||
arg: []const u8 = "",
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn handler(ctx: Context(Self), response: *Response, _: api.ApiSource.Conn) !void {
|
|
||||||
std.log.debug("{}", .{ctx.body.content});
|
|
||||||
try response.writeJson(.created, ctx.query);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn Context(comptime Route: type) type {
|
pub fn Context(comptime Route: type) type {
|
||||||
|
@ -74,7 +60,7 @@ pub fn Context(comptime Route: type) type {
|
||||||
query: Query,
|
query: Query,
|
||||||
|
|
||||||
fn parseArgs(path: []const u8) ?Args {
|
fn parseArgs(path: []const u8) ?Args {
|
||||||
var args: Route.Args = undefined;
|
var args: Args = undefined;
|
||||||
var path_iter = util.PathIter.from(path);
|
var path_iter = util.PathIter.from(path);
|
||||||
comptime var route_iter = util.PathIter.from(Route.path);
|
comptime var route_iter = util.PathIter.from(Route.path);
|
||||||
inline while (comptime route_iter.next()) |route_segment| {
|
inline while (comptime route_iter.next()) |route_segment| {
|
||||||
|
@ -93,7 +79,7 @@ pub fn Context(comptime Route: type) type {
|
||||||
const req = ctx.request;
|
const req = ctx.request;
|
||||||
if (req.method != Route.method) return false;
|
if (req.method != Route.method) return false;
|
||||||
var path = std.mem.sliceTo(std.mem.sliceTo(req.path, '#'), '?');
|
var path = std.mem.sliceTo(std.mem.sliceTo(req.path, '#'), '?');
|
||||||
var args: Route.Args = parseArgs(path) orelse return false;
|
var args: Args = parseArgs(path) orelse return false;
|
||||||
|
|
||||||
var response = Response{ .headers = http.Headers.init(alloc), .ctx = ctx };
|
var response = Response{ .headers = http.Headers.init(alloc), .ctx = ctx };
|
||||||
defer response.headers.deinit();
|
defer response.headers.deinit();
|
||||||
|
@ -116,7 +102,7 @@ pub fn Context(comptime Route: type) type {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn errorHandler(response: *Response, status: http.Status) void {
|
fn errorHandler(response: *Response, status: http.Status) void {
|
||||||
response.writeStatus(status) catch unreachable;
|
response.status(status) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepareAndHandle(self: *Self, api_source: anytype, req: http.Request, response: *Response) void {
|
fn prepareAndHandle(self: *Self, api_source: anytype, req: http.Request, response: *Response) void {
|
||||||
|
@ -128,7 +114,7 @@ pub fn Context(comptime Route: type) type {
|
||||||
var api_conn = self.getApiConn(api_source) catch return errorHandler(response, .internal_server_error); // TODO
|
var api_conn = self.getApiConn(api_source) catch return errorHandler(response, .internal_server_error); // TODO
|
||||||
defer api_conn.close();
|
defer api_conn.close();
|
||||||
|
|
||||||
self.handle(response, api_conn);
|
self.handle(response, &api_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseBody(self: *Self, req: http.Request) !void {
|
fn parseBody(self: *Self, req: http.Request) !void {
|
||||||
|
@ -179,16 +165,16 @@ pub const Response = struct {
|
||||||
headers: http.Headers,
|
headers: http.Headers,
|
||||||
ctx: http.server.Context,
|
ctx: http.server.Context,
|
||||||
|
|
||||||
pub fn writeStatus(self: *Self, status: http.Status) !void {
|
pub fn status(self: *Self, status_code: http.Status) !void {
|
||||||
var stream = try self.ctx.openResponse(&self.headers, status);
|
var stream = try self.ctx.openResponse(&self.headers, status_code);
|
||||||
defer stream.close();
|
defer stream.close();
|
||||||
try stream.finish();
|
try stream.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn writeJson(self: *Self, status: http.Status, response_body: anytype) !void {
|
pub fn json(self: *Self, status_code: http.Status, response_body: anytype) !void {
|
||||||
try self.headers.put("Content-Type", "application/json");
|
try self.headers.put("Content-Type", "application/json");
|
||||||
|
|
||||||
var stream = try self.ctx.openResponse(&self.headers, status);
|
var stream = try self.ctx.openResponse(&self.headers, status_code);
|
||||||
defer stream.close();
|
defer stream.close();
|
||||||
|
|
||||||
const writer = stream.writer();
|
const writer = stream.writer();
|
||||||
|
@ -196,6 +182,13 @@ pub const Response = struct {
|
||||||
|
|
||||||
try stream.finish();
|
try stream.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn err(self: *Self, status_code: http.Status, message: []const u8, details: anytype) !void {
|
||||||
|
return self.json(status_code, .{
|
||||||
|
.message = message,
|
||||||
|
.details = details,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const json_options = if (builtin.mode == .Debug)
|
const json_options = if (builtin.mode == .Debug)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
const root = @import("root");
|
|
||||||
const http = @import("http");
|
|
||||||
const Uuid = @import("util").Uuid;
|
|
||||||
|
|
||||||
const utils = @import("../controllers.zig").utils;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub fn get(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 utils.respondError(ctx, .bad_request, "Invalid UUID");
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
const user = (try api.getActor(id)) orelse return utils.respondError(ctx, .not_found, "Note not found");
|
|
||||||
|
|
||||||
try utils.respondJson(ctx, .ok, user);
|
|
||||||
}
|
|
|
@ -1,42 +1,28 @@
|
||||||
const std = @import("std");
|
const api = @import("api");
|
||||||
const root = @import("root");
|
|
||||||
const builtin = @import("builtin");
|
|
||||||
const http = @import("http");
|
|
||||||
const Uuid = @import("util").Uuid;
|
|
||||||
|
|
||||||
const utils = @import("../controllers.zig").utils;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub const login = struct {
|
pub const login = struct {
|
||||||
pub const path = "/auth/login";
|
|
||||||
pub const method = .POST;
|
pub const method = .POST;
|
||||||
pub fn handler(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
pub const path = "/auth/login";
|
||||||
const credentials = try utils.parseRequestBody(struct { username: []const u8, password: []const u8 }, ctx);
|
|
||||||
defer utils.freeRequestBody(credentials, ctx.alloc);
|
|
||||||
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
pub const Body = struct {
|
||||||
defer api.close();
|
username: []const u8,
|
||||||
|
password: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
const token = try api.login(credentials.username, credentials.password);
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const token = try srv.login(req.body.username, req.body.password);
|
||||||
|
|
||||||
try utils.respondJson(ctx, .ok, token);
|
try res.json(.ok, token);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const verify_login = struct {
|
pub const verify_login = struct {
|
||||||
pub const path = "/auth/login";
|
|
||||||
pub const method = .GET;
|
pub const method = .GET;
|
||||||
|
pub const path = "/auth/login";
|
||||||
|
|
||||||
pub fn handler(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
pub fn handler(_: anytype, res: anytype, srv: anytype) !void {
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
const info = try srv.verifyAuthorization();
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
// The self-hosted compiler doesn't like inferring this error set.
|
try res.json(.ok, info);
|
||||||
// do this for now
|
|
||||||
const info = try api.verifyAuthorization();
|
|
||||||
|
|
||||||
try utils.respondJson(ctx, .ok, info);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,33 +1,16 @@
|
||||||
const root = @import("root");
|
const api = @import("api");
|
||||||
const http = @import("http");
|
|
||||||
|
|
||||||
const utils = @import("../controllers.zig").utils;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub const create = struct {
|
pub const create = struct {
|
||||||
pub const method = .POST;
|
pub const method = .POST;
|
||||||
pub const path = "/communities";
|
pub const path = "/communities";
|
||||||
pub fn handler(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
|
||||||
const opt = try utils.parseRequestBody(struct { origin: []const u8 }, ctx);
|
|
||||||
defer utils.freeRequestBody(opt, ctx.alloc);
|
|
||||||
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
pub const Body = struct {
|
||||||
defer api.close();
|
origin: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
const invite = try api.createCommunity(opt.origin);
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const invite = try srv.createCommunity(req.body.origin);
|
||||||
|
|
||||||
try utils.respondJson(ctx, .created, invite);
|
try res.json(.created, invite);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn get(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs) !void {
|
|
||||||
const host = args.get("host") orelse return error.NotFound;
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
const invite = (try api.getCommunity(host)) orelse return utils.respondError(ctx, .not_found, "Community not found");
|
|
||||||
|
|
||||||
try utils.respondJson(ctx, .ok, invite);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
const api = @import("api");
|
const api = @import("api");
|
||||||
|
|
||||||
pub const create = struct {
|
pub const create = struct {
|
||||||
pub const path = "/invites";
|
|
||||||
pub const method = .POST;
|
pub const method = .POST;
|
||||||
pub const Body = api.InviteRequest;
|
pub const path = "/invites";
|
||||||
|
|
||||||
pub fn handler(req: anytype, res: anytype, srv: api.ApiSource.Conn) !void {
|
pub const Body = api.InviteOptions;
|
||||||
|
|
||||||
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
// No need to free because it will be freed when the api conn
|
// No need to free because it will be freed when the api conn
|
||||||
// is closed
|
// is closed
|
||||||
const invite = srv.createInvite(req.body);
|
const invite = try srv.createInvite(req.body);
|
||||||
|
|
||||||
try res.writeJson(.created, invite);
|
try res.json(.created, invite);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,40 +1,32 @@
|
||||||
const root = @import("root");
|
const api = @import("api");
|
||||||
const http = @import("http");
|
const util = @import("util");
|
||||||
const Uuid = @import("util").Uuid;
|
|
||||||
|
|
||||||
const utils = @import("../controllers.zig").utils;
|
|
||||||
const NoteCreateInfo = @import("api").NoteCreateInfo;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub const create = struct {
|
pub const create = struct {
|
||||||
pub const method = .POST;
|
pub const method = .POST;
|
||||||
pub const path = "/notes";
|
pub const path = "/notes";
|
||||||
pub fn handler(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
|
||||||
const info = try utils.parseRequestBody(struct { content: []const u8 }, ctx);
|
|
||||||
defer utils.freeRequestBody(info, ctx.alloc);
|
|
||||||
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
pub const Body = struct {
|
||||||
defer api.close();
|
content: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
const note = try api.createNote(info.content);
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const note = try srv.createNote(req.body.content);
|
||||||
|
|
||||||
try utils.respondJson(ctx, .created, note);
|
try res.json(.created, note);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const get = struct {
|
pub const get = struct {
|
||||||
pub const method = .GET;
|
pub const method = .GET;
|
||||||
pub const path = "/notes/:id";
|
pub const path = "/notes/:id";
|
||||||
pub fn handler(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 utils.respondError(ctx, .bad_request, "Invalid UUID");
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
const note = try api.getNote(id);
|
pub const Args = struct {
|
||||||
|
id: util.Uuid,
|
||||||
|
};
|
||||||
|
|
||||||
try utils.respondJson(ctx, .ok, note);
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const note = try srv.getNote(req.args.id);
|
||||||
|
|
||||||
|
try res.json(.ok, note);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
const root = @import("root");
|
|
||||||
const http = @import("http");
|
|
||||||
const Uuid = @import("util").Uuid;
|
|
||||||
|
|
||||||
const utils = @import("../../controllers.zig").utils;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub fn create(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs) !void {
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
const note_id = args.get("id") orelse return error.NotFound;
|
|
||||||
const id = Uuid.parse(note_id) catch return utils.respondError(ctx, .bad_request, "Invalid UUID");
|
|
||||||
|
|
||||||
try api.react(id);
|
|
||||||
try utils.respondJson(ctx, .created, .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs) !void {
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
|
||||||
defer api.close();
|
|
||||||
|
|
||||||
const note_id = args.get("id") orelse return error.NotFound;
|
|
||||||
const id = Uuid.parse(note_id) catch return utils.respondError(ctx, .bad_request, "Invalid UUID");
|
|
||||||
|
|
||||||
const reacts = try api.listReacts(id);
|
|
||||||
try utils.respondJson(ctx, .ok, .{ .items = reacts });
|
|
||||||
}
|
|
|
@ -1,29 +1,26 @@
|
||||||
const std = @import("std");
|
const api = @import("api");
|
||||||
const root = @import("root");
|
|
||||||
const http = @import("http");
|
|
||||||
const Uuid = @import("util").Uuid;
|
|
||||||
|
|
||||||
const RegistrationRequest = @import("api").RegistrationRequest;
|
|
||||||
const utils = @import("../controllers.zig").utils;
|
|
||||||
|
|
||||||
const RequestServer = root.RequestServer;
|
|
||||||
const RouteArgs = http.RouteArgs;
|
|
||||||
|
|
||||||
pub const create = struct {
|
pub const create = struct {
|
||||||
pub const method = .POST;
|
pub const method = .POST;
|
||||||
pub const path = "/users";
|
pub const path = "/users";
|
||||||
pub fn handler(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
|
||||||
const info = try utils.parseRequestBody(RegistrationRequest, ctx);
|
|
||||||
defer utils.freeRequestBody(info, ctx.alloc);
|
|
||||||
|
|
||||||
var api = try utils.getApiConn(srv, ctx);
|
pub const Body = struct {
|
||||||
defer api.close();
|
username: []const u8,
|
||||||
|
password: []const u8,
|
||||||
|
invite_code: ?[]const u8 = null,
|
||||||
|
email: ?[]const u8 = null,
|
||||||
|
};
|
||||||
|
|
||||||
const user = api.register(info) catch |err| switch (err) {
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
error.UsernameTaken => return utils.respondError(ctx, .bad_request, "Username Unavailable"),
|
const options = .{
|
||||||
|
.invite_code = req.body.invite_code,
|
||||||
|
.email = req.body.email,
|
||||||
|
};
|
||||||
|
const user = srv.register(req.body.username, req.body.password, options) catch |err| switch (err) {
|
||||||
|
error.UsernameTaken => return res.err(.unprocessable_entity, "Username Unavailable", {}),
|
||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
|
|
||||||
try utils.respondJson(ctx, .created, user);
|
try res.json(.created, user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,16 +26,13 @@ pub const RequestServer = struct {
|
||||||
defer srv.shutdown();
|
defer srv.shutdown();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const buf = try self.alloc.alloc(u8, 1 << 28); // 4mb
|
var arena = std.heap.ArenaAllocator.init(self.alloc);
|
||||||
defer self.alloc.free(buf);
|
defer arena.deinit();
|
||||||
var fba = std.heap.FixedBufferAllocator.init(buf);
|
|
||||||
const alloc = fba.allocator();
|
|
||||||
|
|
||||||
var ctx = try srv.accept(alloc);
|
var ctx = try srv.accept(arena.allocator());
|
||||||
defer ctx.close();
|
defer ctx.close();
|
||||||
|
|
||||||
_ = c.Context(c.sample_api).matchAndHandle(self.api, ctx, self.alloc);
|
c.routeRequest(self.api, ctx, arena.allocator());
|
||||||
if (true) continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue