srctree

Gregory Mullen parent 4b8f4d7c c5c0970b
add endpoint poc

build.zig added: 90, removed: 8, total 82
@@ -36,6 +36,7 @@ pub fn build(b: *std.Build) !void {
"basic",
"cookies",
"template",
"endpoint",
};
for (examples) |example| {
const path = try std.fmt.allocPrint(b.allocator, "examples/{s}.zig", .{example});
 
filename was Deleted added: 90, removed: 8, total 82
@@ -0,0 +1,23 @@
const Endpoints = Endpoint.Endpoints(.{
@import("endpoint/example.zig"),
});
 
pub fn main() !void {
var endpoints = Endpoints.init();
endpoints.serve(
std.heap.page_allocator,
.{ .http = .{ .port = 8084 } },
) catch |err| {
std.log.err("Unable to serve endpoints! err: [{}]", .{err});
@panic("endpoint error");
};
}
 
fn index(verse: *Verse) Verse.Router.Error!void {
try verse.quickStart();
try verse.sendRawSlice("hello world");
}
 
const std = @import("std");
const Verse = @import("verse");
const Endpoint = Verse.Endpoint;
 
filename was Deleted added: 90, removed: 8, total 82
@@ -0,0 +1,9 @@
/// .root is a special cased name to resolve at "/"
pub const verse_name = .root;
 
pub fn index(vrs: *Verse) !void {
try vrs.quickStart();
try vrs.sendRawSlice("hello world");
}
 
const Verse = @import("verse");
 
src/endpoint.zig added: 90, removed: 8, total 82
@@ -6,10 +6,58 @@ pub const Target = struct {
name: []const u8,
};
 
pub fn Endpoints(endpoints: anytype) !Endpoint {
if (@typeInfo(endpoints).Struct.is_tuple == false) return error.InvalidEndpointTypes;
pub fn Endpoints(endpoints: anytype) type {
if (@typeInfo(@TypeOf(endpoints)).Struct.is_tuple == false) return error.InvalidEndpointTypes;
inline for (endpoints) |ep| {
validateEndpoint(ep);
}
return struct {
pub const Self = @This();
pub const Endpoints = endpoints;
 
return error.NotImplemented;
pub const routes = buildRoutes(endpoints[0]);
 
pub fn init() Self {
return .{};
}
 
pub fn serve(_: *Self, a: Allocator, options: Verse.Server.Options) !void {
var server = try Verse.Server.init(a, options, .{ .routefn = route });
try server.serve();
}
 
pub fn route(v: *Verse) !Verse.Router.BuildFn {
return Verse.Router.router(v, &routes);
}
};
}
 
fn validateEndpoint(EP: anytype) void {
if (!@hasDecl(EP, "verse_name")) @compileError("Verse: provided endpoint is missing name decl.\n" ++
"Expected `pub const verse_name = .endpoint_name;` from: " ++ @typeName(EP));
}
 
fn routeCount(EP: type) usize {
var count: usize = 0;
for (@typeInfo(EP).Struct.decls) |decl| {
if (std.mem.eql(u8, "index", decl.name)) count += 1;
}
return count;
}
 
fn buildRoutes(EP: anytype) [routeCount(EP)]Verse.Router.Match {
var match: [routeCount(EP)]Verse.Router.Match = undefined;
var idx: usize = 0;
for (@typeInfo(EP).Struct.decls) |decl| {
if (std.mem.eql(u8, "index", decl.name)) {
match[idx] = Verse.Router.ANY("", EP.index);
idx += 1;
}
}
 
return match;
}
 
const std = @import("std");
const Allocator = std.mem.Allocator;
const Verse = @import("verse.zig");
 
src/verse.zig added: 90, removed: 8, total 82
@@ -5,6 +5,7 @@ pub const RequestData = @import("request_data.zig");
pub const Template = @import("template.zig");
pub const Router = @import("router.zig");
pub const UriIter = Router.UriIter;
pub const Endpoint = @import("endpoint.zig");
 
pub const Headers = @import("headers.zig");
pub const Auth = @import("auth.zig");