FlexiLib/src/main-lib.zig

71 lines
2.8 KiB
Zig

const std = @import("std");
const interface = @import("interface.zig");
const testing = std.testing;
const log = std.log.scoped(.@"main-lib");
// request_deinit is an optional export and will be called a the end of the
// request. Useful for deallocating memory
// 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 {
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 {
@export(
interface.zigInit,
.{ .name = "zigInit", .linkage = .Strong },
);
}
// ************************************************************************
// Boilerplate ^^, Custom code vv
// ************************************************************************
//
// handleRequest function here is the last line of boilerplate and the
// entry to a request
fn handleRequest(allocator: std.mem.Allocator, request: interface.ZigRequest, response: interface.ZigResponse) !void {
_ = allocator;
// setup
var response_writer = response.body.writer();
// real work
response_writer.print(" {d}", .{request.headers.len}) catch unreachable;
try response.headers.put("X-custom-foo", "bar");
log.info("handlerequest header count {d}", .{response.headers.count()});
}
test "handle_request" {
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
var aa = arena.allocator();
interface.zigInit(&aa);
var headers: []interface.Header = @constCast(&[_]interface.Header{.{
.name_ptr = @ptrCast([*:0]u8, @constCast("GET".ptr)),
.name_len = 3,
.value_ptr = @ptrCast([*:0]u8, @constCast("GET".ptr)),
.value_len = 3,
}});
var req = interface.Request{
.method = @ptrCast([*:0]u8, @constCast("GET".ptr)),
.method_len = 3,
.content = @ptrCast([*:0]u8, @constCast("GET".ptr)),
.content_len = 3,
.headers = headers.ptr,
.headers_len = 1,
};
const response = handle_request(&req).?;
try testing.expectEqualStrings(" 1", response.ptr[0..response.len]);
try testing.expectEqualStrings("X-custom-foo", response.headers[0].name_ptr[0..response.headers[0].name_len]);
try testing.expectEqualStrings("bar", response.headers[0].value_ptr[0..response.headers[0].value_len]);
}