Add type checking to simple_router's handle_func - #125
Conversation
| const hand_info = @typeInfo(@TypeOf(handler)); | ||
|
|
||
| // Need to check: | ||
| // 1) handler is function pointer |
There was a problem hiding this comment.
Forgive me if what I say don't make sense (my Zig knowledge is minimal at the moment) but wouldn't it be easier if we just change the handler: anytype to be just the signature we need? Like handler: fn(r: zap.Request) void, and there would be no need to do a manual inspection.
There was a problem hiding this comment.
That argument sounds compelling at first. But here's where the problem starts. The handler function also must take an instance (to a context) orelse all you could access from within the handler function would be global variables.
IMHO the comment above handle_func explains it:
/// Call this to add a route with a handler that is bound to an instance of a struct.
/// Example:
///
/// ```zig
/// const HandlerType = struct {
/// pub fn getA(self: *HandlerType, r: zap.Request) void {
/// _ = self;
/// r.sendBody("hello\n\n") catch return;
/// }
/// }
/// var handler_instance = HandlerType{};
///
/// my_router.handle_func("/getA", &handler_instance, HandlerType.getA);See, getA takes a self instance of type *HandlerType and only then the Request.
So there is no single static fn type for handler.
Related: In languages like Python, you can take a reference to an instance method—effectively a “function pointer.” For example, if your class defines a method like def get(self, request), you can instantiate the class with instantiated_object = MyClass() and then assign the method to a variable with handler = instantiated_object.get. This handler is bound to the instance, meaning you can call it with just the request (handler(just_a_request)) rather than needing to pass the instance explicitly (handler(instantiated_object, request)).
Zig doesn’t work like that, though. I recently wrote in detail about this difference [here](https://renerocks.ai/blog/zig-bound-functions/
There was a problem hiding this comment.
BTW, for handlers that don't need an instance, there is:
/// Call this to add a route with an unbound handler: a handler that is not member of a struct.
pub fn handle_func_unbound(self: *Router, path: []const u8, h: zap.HttpRequestFn) !void {Here, since no "dynamic typing" is needed, the type of the handler function h is fixed.
|
Thx, it's fine! And sorry it took so long! |
I took a quick stab at trying to fix #121.
This is the first time I've played with type introspection in Zig, so please let me know if there's a better way to do this.