Skip to content

Commit

Permalink
Router Additions
Browse files Browse the repository at this point in the history
Router Additions
  • Loading branch information
mookums authored Nov 17, 2024
2 parents 09b12c5 + 791bb42 commit 9d5a1d9
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 175 deletions.
12 changes: 11 additions & 1 deletion examples/basic/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn main() !void {
const num: i8 = 12;

try router.serve_route("/", Route.init().get(&num, struct {
pub fn handler_fn(ctx: *Context, id: *const i8) !void {
fn handler_fn(ctx: *Context, id: *const i8) !void {
const body_fmt =
\\ <!DOCTYPE html>
\\ <html>
Expand All @@ -59,6 +59,16 @@ pub fn main() !void {
}
}.handler_fn));

router.serve_not_found(Route.init().get({}, struct {
fn handler_fn(ctx: *Context, _: void) !void {
try ctx.respond(.{
.status = .@"Not Found",
.mime = http.Mime.HTML,
.body = "Not Found Handler!",
});
}
}.handler_fn));

// This provides the entry function into the Tardy runtime. This will run
// exactly once inside of each runtime (each thread gets a single runtime).
try t.entry(
Expand Down
4 changes: 3 additions & 1 deletion examples/fs/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ pub fn main() !void {
&router,
struct {
fn entry(rt: *Runtime, r: *const Router) !void {
var server = Server.init(.{ .allocator = rt.allocator });
var server = Server.init(.{
.allocator = rt.allocator,
});
try server.bind(host, port);
try server.serve(r, rt);
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/job.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const TaskFn = @import("tardy").TaskFn;

pub const AfterType = union(enum) {
recv,
sse: struct {
other: struct {
func: *const anyopaque,
ctx: *anyopaque,
},
Expand Down
105 changes: 77 additions & 28 deletions src/http/context.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,60 +38,109 @@ pub fn Context(comptime Server: type) type {
triggered: bool = false,

pub fn to_sse(self: *Self, then: TaskFn(bool, *SSE)) !void {
assert(!self.triggered);
self.triggered = true;

self.response.set(.{
.status = .OK,
.body = "",
.mime = Mime{
.extension = ".sse",
.description = "Server-Sent Events",
.content_type = "text/event-stream",
},
});

const headers = try self.provision.response.headers_into_buffer(
self.provision.buffer,
null,
);

const sse = try self.allocator.create(SSE);
sse.* = .{
.context = self,
.runtime = self.runtime,
.allocator = self.allocator,
};

const pslice = Pseudoslice.init(headers, "", self.provision.buffer);
try self.respond_headers_only(
.{
.status = .OK,
.body = "",
.mime = Mime{
.extension = ".sse",
.description = "Server-Sent Events",
.content_type = "text/event-stream",
},
},
null,
sse,
then,
);
}

pub fn close(self: *Self) !void {
self.provision.job = .close;
try self.runtime.net.close(
self.provision,
Server.close_task,
self.provision.socket,
);
}

pub fn send_then(
self: *Self,
data: []const u8,
ctx: anytype,
then: TaskFn(bool, @TypeOf(ctx)),
) !void {
const pslice = Pseudoslice.init(data, "", self.provision.buffer);

const first_chunk = try Server.prepare_send(
self.runtime,
self.provision,
.{ .sse = .{
.func = then,
.ctx = sse,
} },
.{
.other = .{
.func = then,
.ctx = ctx,
},
},
pslice,
);

try self.runtime.net.send(
self.provision,
Server.send_then_sse_task,
Server.send_then_other_task,
self.provision.socket,
first_chunk,
);
}

pub fn close(self: *Self) !void {
self.provision.job = .close;
try self.runtime.net.close(
pub fn send_then_recv(self: *Self, data: []const u8) !void {
const pslice = Pseudoslice.init(data, "", self.provision.buffer);

const first_chunk = try Server.prepare_send(
self.runtime,
self.provision,
Server.close_task,
.recv,
pslice,
);

try self.runtime.net.send(
self.provision,
Server.send_then_recv_task,
self.provision.socket,
first_chunk,
);
}

// This will respond with the headers only.
// You will be in charge of sending the body.
pub fn respond_headers_only(
self: *Self,
options: ResponseSetOptions,
content_length: ?usize,
ctx: anytype,
then: TaskFn(bool, @TypeOf(ctx)),
) !void {
assert(!self.triggered);
self.triggered = true;

// the body should not be set.
assert(options.body == null);
self.response.set(options);

const headers = try self.provision.response.headers_into_buffer(
self.provision.buffer,
content_length,
);

try self.send_then(headers, ctx, then);
}

/// This is your standard response.
pub fn respond(self: *Self, options: ResponseSetOptions) !void {
assert(!self.triggered);
self.triggered = true;
Expand Down
2 changes: 1 addition & 1 deletion src/http/response.zig
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub const Response = struct {
}
}

pub fn headers_into_buffer(self: *Response, buffer: []u8, content_length: ?u32) ![]u8 {
pub fn headers_into_buffer(self: *Response, buffer: []u8, content_length: ?usize) ![]u8 {
var index: usize = 0;

// Status Line
Expand Down
2 changes: 1 addition & 1 deletion src/http/route.zig
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn Route(comptime Server: type) type {
// You can either give a void (if you don't want to pass data through) or a pointer.
comptime assert(@typeInfo(@TypeOf(data)) == .Pointer or @typeInfo(@TypeOf(data)) == .Void);
const inner_data = switch (comptime @typeInfo(@TypeOf(data))) {
.Void => @intFromPtr(&data),
.Void => 1, // Needs to not be 0.
.Pointer => @intFromPtr(data),
else => unreachable,
};
Expand Down
Loading

0 comments on commit 9d5a1d9

Please sign in to comment.