create more zig-friendly request interface
This commit is contained in:
parent
31bece93fc
commit
76497fe22c
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
// C interfaces between main and libraries
|
||||||
pub const Header = extern struct {
|
pub const Header = extern struct {
|
||||||
name_ptr: [*]u8,
|
name_ptr: [*]u8,
|
||||||
name_len: usize,
|
name_len: usize,
|
||||||
|
@ -26,6 +27,13 @@ pub const Request = extern struct {
|
||||||
headers_len: usize,
|
headers_len: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If the library is Zig, we can use these helpers
|
||||||
|
pub const ZigRequest = struct {
|
||||||
|
method: [:0]u8,
|
||||||
|
content: []u8,
|
||||||
|
headers: []Header,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn toHeaders(alloc: std.mem.Allocator, headers: std.StringHashMap([]const u8)) ![*]Header {
|
pub fn toHeaders(alloc: std.mem.Allocator, headers: std.StringHashMap([]const u8)) ![*]Header {
|
||||||
var header_array = try std.ArrayList(Header).initCapacity(alloc, headers.count());
|
var header_array = try std.ArrayList(Header).initCapacity(alloc, headers.count());
|
||||||
var iterator = headers.iterator();
|
var iterator = headers.iterator();
|
||||||
|
@ -56,7 +64,7 @@ pub fn zigInit(parent_allocator: *anyopaque) callconv(.C) void {
|
||||||
allocator = @ptrCast(*std.mem.Allocator, @alignCast(@alignOf(*std.mem.Allocator), parent_allocator));
|
allocator = @ptrCast(*std.mem.Allocator, @alignCast(@alignOf(*std.mem.Allocator), parent_allocator));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ZigRequestHandler = *const fn (std.mem.Allocator, Request, ZigResponse) anyerror!void;
|
pub const ZigRequestHandler = *const fn (std.mem.Allocator, ZigRequest, ZigResponse) anyerror!void;
|
||||||
|
|
||||||
const log = std.log.scoped(.interface);
|
const log = std.log.scoped(.interface);
|
||||||
pub fn handleRequest(request: *Request, zigRequestHandler: ZigRequestHandler) ?*Response {
|
pub fn handleRequest(request: *Request, zigRequestHandler: ZigRequestHandler) ?*Response {
|
||||||
|
@ -69,10 +77,18 @@ pub fn handleRequest(request: *Request, zigRequestHandler: ZigRequestHandler) ?*
|
||||||
|
|
||||||
// setup headers
|
// setup headers
|
||||||
var headers = std.StringHashMap([]const u8).init(alloc);
|
var headers = std.StringHashMap([]const u8).init(alloc);
|
||||||
zigRequestHandler(alloc, request.*, .{
|
zigRequestHandler(
|
||||||
.body = &response,
|
alloc,
|
||||||
.headers = &headers,
|
.{
|
||||||
}) catch |e| {
|
.method = request.method[0..request.method_len :0],
|
||||||
|
.content = request.content[0..request.content_len],
|
||||||
|
.headers = request.headers[0..request.headers_len],
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.body = &response,
|
||||||
|
.headers = &headers,
|
||||||
|
},
|
||||||
|
) catch |e| {
|
||||||
log.err("Unexpected error processing request: {any}", .{e});
|
log.err("Unexpected error processing request: {any}", .{e});
|
||||||
if (@errorReturnTrace()) |trace| {
|
if (@errorReturnTrace()) |trace| {
|
||||||
std.debug.dumpStackTrace(trace.*);
|
std.debug.dumpStackTrace(trace.*);
|
||||||
|
|
|
@ -8,10 +8,20 @@ const log = std.log.scoped(.@"main-lib");
|
||||||
// request. Useful for deallocating memory
|
// request. Useful for deallocating memory
|
||||||
// export fn request_deinit() void {
|
// export fn request_deinit() void {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/// handle_request will be called on a single request, but due to the preservation
|
||||||
|
/// of restrictions imposed by the calling interface, it should generally be more
|
||||||
|
/// useful to call into the interface library to let it do the conversion work
|
||||||
|
/// on your behalf
|
||||||
export fn handle_request(request: *interface.Request) callconv(.C) ?*interface.Response {
|
export fn handle_request(request: *interface.Request) callconv(.C) ?*interface.Response {
|
||||||
return interface.handleRequest(request, handleRequest);
|
return interface.handleRequest(request, handleRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// zigInit is an optional export called at the beginning of a request. It will
|
||||||
|
// be passed an allocator (which...shh...is an arena allocator). Since the
|
||||||
|
// interface library provides a request handler that requires a built-in allocator,
|
||||||
|
// if you are using the interface library, you will need to also include this
|
||||||
|
// export
|
||||||
comptime {
|
comptime {
|
||||||
@export(
|
@export(
|
||||||
interface.zigInit,
|
interface.zigInit,
|
||||||
|
@ -25,12 +35,12 @@ comptime {
|
||||||
//
|
//
|
||||||
// handleRequest function here is the last line of boilerplate and the
|
// handleRequest function here is the last line of boilerplate and the
|
||||||
// entry to a request
|
// entry to a request
|
||||||
fn handleRequest(allocator: std.mem.Allocator, request: interface.Request, response: interface.ZigResponse) !void {
|
fn handleRequest(allocator: std.mem.Allocator, request: interface.ZigRequest, response: interface.ZigResponse) !void {
|
||||||
_ = allocator;
|
_ = allocator;
|
||||||
// setup
|
// setup
|
||||||
var response_writer = response.body.writer();
|
var response_writer = response.body.writer();
|
||||||
// real work
|
// real work
|
||||||
response_writer.print(" {d}", .{request.headers_len}) catch unreachable;
|
response_writer.print(" {d}", .{request.headers.len}) catch unreachable;
|
||||||
try response.headers.put("X-custom-foo", "bar");
|
try response.headers.put("X-custom-foo", "bar");
|
||||||
log.info("handlerequest header count {d}", .{response.headers.count()});
|
log.info("handlerequest header count {d}", .{response.headers.count()});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user