Skip to content

Commit

Permalink
API cleanup #2 --------------
Browse files Browse the repository at this point in the history
- Middleware: no more MixContexts
    - zig structs are fine
- more documentation (comments -> autodoc).
- websocket docs
  • Loading branch information
renerocksai committed Jan 9, 2024
1 parent 8892cae commit 207a761
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 234 deletions.
33 changes: 8 additions & 25 deletions doc/zig-ception.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,12 @@ Here is how it is used in user-code:

```zig
// create a combined context struct
const Context = zap.Middleware.MixContexts(.{
.{ .name = "?user", .type = UserMiddleWare.User },
.{ .name = "?session", .type = SessionMiddleWare.Session },
});
const Context = struct {
user: ?UserMiddleWare.User = null,
session: ?SessionMiddleWare.Session = null,
};
```

The result of this function call is a struct that has a `user` field of type
`?UserMiddleWare.User`, which is the `User` struct inside of its containing
struct - and a `session` field of type `?SessionMiddleWare.Session`.

So `MixContexts` accepts a **tuple** of structs that each contain a
`name` field and a `type` field. As a hack, we support the `?` in the name to
indicate we want the resulting struct field to be an optional.

A **tuple** means that we can "mix" as many structs as we like. Not just two
like in the example above.

`MixContexts` inspects the passed-in `type` fields and **composes a new struct
type at comptime**! Have a look at its [source code](../src/middleware.zig).
You'll be blown away if this kind of metaprogramming stuff isn't what you do
everyday. I was totally blown away by trying it out and seeing it that it
_actually_ worked.

Why do we create combined structs? Because all our Middleware handler functions
need to receive a per-request context. But each wants their own data: the User
middleware might want to access a User struct, the Session middleware might want
Expand Down Expand Up @@ -62,10 +45,10 @@ Have a look at an excerpt of the example:

```zig
// create a combined context struct
const Context = zap.Middleware.MixContexts(.{
.{ .name = "?user", .type = UserMiddleWare.User },
.{ .name = "?session", .type = SessionMiddleWare.Session },
});
const Context = struct {
user: ?UserMiddleWare.User = null,
session: ?SessionMiddleWare.Session = null,
};
// we create a Handler type based on our Context
const Handler = zap.Middleware.Handler(Context);
Expand Down
11 changes: 6 additions & 5 deletions examples/middleware_with_endpoint/middleware_with_endpoint.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ const SharedAllocator = struct {
};

// create a combined context struct
const Context = zap.Middleware.MixContexts(.{
.{ .name = "?user", .type = UserMiddleWare.User },
.{ .name = "?session", .type = SessionMiddleWare.Session },
});
// NOTE: context struct members need to be optionals which default to null!!!
const Context = struct {
user: ?UserMiddleWare.User = null,
session: ?SessionMiddleWare.Session = null,
};

// we create a Handler type based on our Context
const Handler = zap.Middleware.Handler(Context);
Expand Down Expand Up @@ -143,7 +144,7 @@ const HtmlEndpoint = struct {
pub fn init() Self {
return .{
.ep = zap.Endpoint.init(.{
.path = "/doesn'tmatter",
.path = "/doesn't+matter",
.get = get,
}),
};
Expand Down
1 change: 1 addition & 0 deletions examples/websockets/websockets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ fn on_close_websocket(context: ?*Context, uuid: isize) void {
std.log.info("websocket closed: {s}", .{message});
}
}

fn handle_websocket_message(
context: ?*Context,
handle: WebSockets.WsHandle,
Expand Down
49 changes: 23 additions & 26 deletions src/endpoint.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,32 @@ pub const EndpointSettings = struct {
/// The main thread usually continues at the instructions after the call to zap.start().
///
/// ```zig
/// // file: stopendpoint.zig
/// const StopEndpoint = struct {
/// ep: zap.Endpoint = undefined,
///
/// pub const Self = @This();
/// pub fn init(
/// path: []const u8,
/// ) StopEndpoint {
/// return .{
/// .ep = zap.Endpoint.init(.{
/// .path = path,
/// .get = get,
/// }),
/// };
/// }
///
/// ep: zap.Endpoint = undefined,
/// // access the internal Endpoint
/// pub fn endpoint(self: *StopEndpoint) *zap.Endpoint {
/// return &self.ep;
/// }
///
/// pub fn init(
/// path: []const u8,
/// ) Self {
/// return .{
/// .ep = zap.Endpoint.init(.{
/// .path = path,
/// .get = get,
/// }),
/// };
/// }
///
/// // access the internal Endpoint
/// pub fn endpoint(self: *Self) *zap.Endpoint {
/// return &self.ep;
/// }
///
/// fn get(e: *zap.Endpoint, r: zap.Request) void {
/// const self: *Self = @fieldParentPtr(Self, "ep", e);
/// _ = self;
/// _ = e;
/// _ = r;
/// zap.stop();
/// }
/// fn get(e: *zap.Endpoint, r: zap.Request) void {
/// const self: *StopEndpoint = @fieldParentPtr(StopEndpoint, "ep", e);
/// _ = self;
/// _ = r;
/// zap.stop();
/// }
/// };
/// ```
pub const Endpoint = struct {
settings: EndpointSettings,
Expand Down
Loading

0 comments on commit 207a761

Please sign in to comment.