Skip to content

Commit 8ed499b

Browse files
committed
update struct
1 parent 74dd9eb commit 8ed499b

20 files changed

+258
-304
lines changed

build.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn build(b: *std.Build) void {
2222
.target = target,
2323
.optimize = optimize,
2424
});
25-
unit_tests.root_module.addImport("zinc", module);
25+
// unit_tests.root_module.addImport("zinc", module);
2626
unit_tests.root_module.addImport("url", url.module("url"));
2727

2828
const run_unit_tests = b.addRunArtifact(unit_tests);

src/test/context_test.zig

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const std = @import("std");
2+
const URL = @import("url");
3+
const RespondOptions = std.http.Server.Request.RespondOptions;
4+
const Header = std.http.Header;
5+
6+
const zinc = @import("../zinc.zig");
7+
const Request = zinc.Request;
8+
const Response = zinc.Response;
9+
const Config = zinc.Config;
10+
const Headers = zinc.Headers;
11+
const Param = zinc.Param;
12+
const HandlerFn = zinc.HandlerFn;
13+
const Context = zinc.Context;
14+
15+
test "context query" {
16+
var req = Request.init(.{
17+
.target = "/query?id=1234&message=hello&message=world&ids[a]=1234&ids[b]=hello&ids[b]=world",
18+
});
19+
20+
var ctx = Context.init(.{ .request = &req }).?;
21+
22+
var qm = ctx.getQueryMap() orelse {
23+
return try std.testing.expect(false);
24+
};
25+
26+
try std.testing.expectEqualStrings(qm.get("id").?.items[0], "1234");
27+
try std.testing.expectEqualStrings(qm.get("message").?.items[0], "hello");
28+
try std.testing.expectEqualStrings(qm.get("message").?.items[1], "world");
29+
30+
const idv = ctx.queryValues("id") catch return try std.testing.expect(false);
31+
try std.testing.expectEqualStrings(idv.items[0], "1234");
32+
33+
const messages = ctx.queryArray("message") catch return try std.testing.expect(false);
34+
try std.testing.expectEqualStrings(messages[0], "hello");
35+
try std.testing.expectEqualStrings(messages[1], "world");
36+
37+
const ids: std.StringHashMap(std.ArrayList([]const u8)) = ctx.queryMap("ids") orelse return try std.testing.expect(false);
38+
try std.testing.expectEqualStrings(ids.get("a").?.items[0], "1234");
39+
try std.testing.expectEqualStrings(ids.get("b").?.items[0], "hello");
40+
try std.testing.expectEqualStrings(ids.get("b").?.items[1], "world");
41+
}
42+
43+
test "context query map" {
44+
var req = Request.init(.{
45+
.target = "/query?ids[a]=1234&ids[b]=hello&ids[b]=world",
46+
});
47+
48+
var ctx = Context.init(.{ .request = &req }).?;
49+
50+
var ids: std.StringHashMap(std.ArrayList([]const u8)) = ctx.queryMap("ids") orelse return try std.testing.expect(false);
51+
try std.testing.expectEqualStrings(ids.get("a").?.items[0], "1234");
52+
try std.testing.expectEqualStrings(ids.get("b").?.items[0], "hello");
53+
try std.testing.expectEqualStrings(ids.get("b").?.items[1], "world");
54+
}

src/test/middleware_test.zig

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// test "Middleware" {
2+
// var text: []const u8 = undefined;
3+
4+
// var router = zinc.Router.init(.{});
5+
6+
// const mid1 = struct {
7+
// var signature: []const u8 = undefined;
8+
// inline fn testMiddle1(c: *Context) anyerror!void {
9+
// text += "A";
10+
// try c.next();
11+
// text += "B";
12+
// }
13+
// };
14+
// router.use(mid1.testMiddle1);
15+
// // router.get("/", mid3.testMiddle3);
16+
// std.testing.expectEqualStrings("ACDB", signature);
17+
// }

src/test/route_test.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ test "route matching error" {
3232
var route = tc.route;
3333
const route_expected = route.match(tc.reqMethod, tc.reqPath) catch |err| {
3434
try testing.expect(err == (tc.expected catch |e| e));
35-
// std.debug.print(" \r\n route test1 case {d} passed, path: {s} ", .{ i, tc.reqPath });
35+
std.debug.print(" \r\n route test1 case {d} passed, path: {s} ", .{ i, tc.reqPath });
3636
continue;
3737
};
3838

3939
try testing.expectEqual(route_expected.*, (try tc.expected));
40-
// std.debug.print(" \r\n route test2 case {d} passed, path: {s} ", .{ i, tc.reqPath });
40+
std.debug.print(" \r\n route test2 case {d} passed, path: {s} ", .{ i, tc.reqPath });
4141
}
4242
}

src/test/router_test.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ test "router" {
3131
};
3232

3333
for (testCases, 0..) |tc, i| {
34-
// std.debug.print(" \r\n test case {d}, path: {s} ", .{ i, tc.reqPath });
34+
std.debug.print(" \r\n test case {d}, path: {s} ", .{ i, tc.reqPath });
3535
const route_expected = router.matchRoute(tc.reqMethod, tc.reqPath) catch |err| {
3636
try testing.expect(err == (tc.expected catch |e| e));
3737
// std.debug.print(" \r\n test1 case {d} passed, path: {s} ", .{ i, tc.reqPath });

src/zinc.zig

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
pub const Engine = @import("zinc/engine.zig");
21
pub const Context = @import("zinc/context.zig");
2+
pub const Config = @import("zinc/config.zig");
3+
pub const Catchers = @import("zinc/catchers.zig");
4+
pub const Engine = @import("zinc/engine.zig");
5+
pub const Param = @import("zinc/param.zig");
36
pub const Request = @import("zinc/request.zig");
47
pub const Response = @import("zinc/response.zig");
58
pub const Route = @import("zinc/route.zig");
69
pub const Router = @import("zinc/router.zig");
710
pub const Headers = @import("zinc/headers.zig");
8-
pub const Config = @import("zinc/config.zig");
911
pub const Handler = @import("zinc/handler.zig");
10-
pub const HandlerFn = @import("zinc/handler.zig");
12+
pub const HandlerFn = @import("zinc/handler.zig").HandlerFn;
1113
pub const Middleware = @import("zinc/middleware.zig");
14+
pub const RouterGroup = @import("zinc/routergroup.zig");
1215

1316
pub fn init(comptime conf: Config.Engine) !Engine {
1417
return Engine.init(conf);

src/zinc/catchers.zig

+3-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ const net = std.net;
55
const proto = http.protocol;
66
const Server = http.Server;
77
const Allocator = std.mem.Allocator;
8-
const Handler = @import("handler.zig");
8+
9+
const zinc = @import("../zinc.zig");
10+
const Handler = zinc.Handler;
911
const HandlerFn = Handler.HandlerFn;
1012

1113
pub const Self = @This();
@@ -18,10 +20,6 @@ pub fn init(allocator: Allocator) Self {
1820
};
1921
}
2022

21-
// pub fn getCatchers(self: *Self) *std.AutoHashMap(http.Status, HandlerFn) {
22-
// return &self.catchers;
23-
// }
24-
2523
pub fn get(self: *Self, status: http.Status) ?HandlerFn {
2624
return self.catchers.get(status);
2725
}
@@ -49,10 +47,3 @@ pub fn methodNotAllowed(self: *Self) ?HandlerFn {
4947
pub fn internalServerError(self: *Self) ?HandlerFn {
5048
return self.get(http.Status.internal_server_error);
5149
}
52-
53-
// pub fn handle(self: *Self, status: http.Status, ctx: Handler.Context) void {
54-
// const handler = self.catchers.get(status);
55-
// if (handler != null) {
56-
// handler(ctx);
57-
// }
58-
// }

src/zinc/config.zig

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const StringHashMap = std.StringHashMap;
88
const ArrayList = std.ArrayList;
99
const Method = http.Method;
1010

11-
const Handler = @import("handler.zig");
11+
const zinc = @import("../zinc.zig");
12+
const Handler = zinc.Handler;
1213

1314
pub const Config = @This();
1415

src/zinc/context.zig

+28-59
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@ const URL = @import("url");
33
const RespondOptions = std.http.Server.Request.RespondOptions;
44
const Header = std.http.Header;
55

6-
const Request = @import("request.zig");
7-
const Response = @import("response.zig");
8-
const Config = @import("config.zig");
9-
const Headers = @import("headers.zig");
10-
const Param = @import("param.zig");
11-
12-
const HandlerFn = @import("handler.zig").HandlerFn;
6+
const zinc = @import("../zinc.zig");
7+
const Request = zinc.Request;
8+
const Response = zinc.Response;
9+
const Config = zinc.Config;
10+
const Headers = zinc.Headers;
11+
const Param = zinc.Param;
12+
const HandlerFn = zinc.HandlerFn;
13+
// const Context = zinc.Context;
14+
15+
// const Request = @import("request.zig");
16+
// const Response = @import("response.zig");
17+
// const Config = @import("config.zig");
18+
// const Headers = @import("headers.zig");
19+
// const Param = @import("param.zig");
20+
21+
// const HandlerFn = @import("handler.zig").HandlerFn;
1322

1423
pub const Context = @This();
1524
const Self = @This();
@@ -30,10 +39,8 @@ query_map: ?std.StringHashMap(std.ArrayList([]const u8)) = null,
3039
// Slice of optional function pointers
3140
handlers: std.ArrayList(*const fn (*Self) anyerror!void) = std.ArrayList(*const fn (*Self) anyerror!void).init(std.heap.page_allocator),
3241
index: u8 = 0, // Adjust the type based on your specific needs
33-
// index: usize = 0, // Adjust the type based on your specific needs
3442

35-
// body_buffer_len: usize = 0,
36-
// query: ?std.Uri.Component = null,
43+
// writer: std.io.AnyWriter = std.net.Stream.writer(),
3744

3845
pub fn deinit(self: *Self) void {
3946
self.headers.deinit();
@@ -56,6 +63,9 @@ pub fn init(self: Self) ?Context {
5663
.params = self.params,
5764
.query = self.query,
5865
.query_map = self.query_map,
66+
.handlers = self.handlers,
67+
.index = self.index,
68+
// .writer = try self.request.server_request.server.connection.stream.writer(),
5969
};
6070
}
6171

@@ -172,15 +182,15 @@ pub inline fn next(self: *Context) anyerror!void {
172182
self.index += 1;
173183

174184
if (self.index >= self.handlers.items.len) return;
175-
176-
try self.handlers.items[self.index](self);
185+
const handler = self.handlers.items[self.index];
186+
try handler(self);
177187

178188
self.index += 1;
179189
}
180190

181191
pub fn redirect(self: *Self, http_status: std.http.Status, url: []const u8) anyerror!void {
182192
try self.headers.add("Location", url);
183-
try self.request.server_request.respond("", .{ .status = http_status, .reason = http_status.phrase(), .extra_headers = self.headers.items(), .keep_alive = false });
193+
try self.request.req.respond("", .{ .status = http_status, .reason = http_status.phrase(), .extra_headers = self.headers.items(), .keep_alive = false });
184194
}
185195

186196
pub const queryError = error{
@@ -247,47 +257,6 @@ pub fn queryMap(self: *Self, map_key: []const u8) ?std.StringHashMap(std.ArrayLi
247257
return inner_map;
248258
}
249259

250-
test "context query" {
251-
var req = Request.init(.{
252-
.target = "/query?id=1234&message=hello&message=world&ids[a]=1234&ids[b]=hello&ids[b]=world",
253-
});
254-
255-
var ctx = Context.init(.{ .request = &req }).?;
256-
257-
var qm = ctx.getQueryMap() orelse {
258-
return try std.testing.expect(false);
259-
};
260-
261-
try std.testing.expectEqualStrings(qm.get("id").?.items[0], "1234");
262-
try std.testing.expectEqualStrings(qm.get("message").?.items[0], "hello");
263-
try std.testing.expectEqualStrings(qm.get("message").?.items[1], "world");
264-
265-
const idv = ctx.queryValues("id") catch return try std.testing.expect(false);
266-
try std.testing.expectEqualStrings(idv.items[0], "1234");
267-
268-
const messages = ctx.queryArray("message") catch return try std.testing.expect(false);
269-
try std.testing.expectEqualStrings(messages[0], "hello");
270-
try std.testing.expectEqualStrings(messages[1], "world");
271-
272-
const ids: std.StringHashMap(std.ArrayList([]const u8)) = ctx.queryMap("ids") orelse return try std.testing.expect(false);
273-
try std.testing.expectEqualStrings(ids.get("a").?.items[0], "1234");
274-
try std.testing.expectEqualStrings(ids.get("b").?.items[0], "hello");
275-
try std.testing.expectEqualStrings(ids.get("b").?.items[1], "world");
276-
}
277-
278-
test "context query map" {
279-
var req = Request.init(.{
280-
.target = "/query?ids[a]=1234&ids[b]=hello&ids[b]=world",
281-
});
282-
283-
var ctx = Context.init(.{ .request = &req }).?;
284-
285-
var ids: std.StringHashMap(std.ArrayList([]const u8)) = ctx.queryMap("ids") orelse return try std.testing.expect(false);
286-
try std.testing.expectEqualStrings(ids.get("a").?.items[0], "1234");
287-
try std.testing.expectEqualStrings(ids.get("b").?.items[0], "hello");
288-
try std.testing.expectEqualStrings(ids.get("b").?.items[1], "world");
289-
}
290-
291260
/// Get the query values as a map.
292261
/// e.g /post?name=foo&name=bar => getQueryMap() => {"name": ["foo", "bar"]}
293262
pub fn getQueryMap(self: *Self) ?std.StringHashMap(std.ArrayList([]const u8)) {
@@ -310,7 +279,7 @@ pub fn queryArray(self: *Self, name: []const u8) anyerror![][]const u8 {
310279
}
311280

312281
pub fn getPostFormMap(self: *Self) ?std.StringHashMap([]const u8) {
313-
const req = self.request.server_request;
282+
const req = self.request.req;
314283

315284
const content_type = req.head.content_type orelse return null;
316285
_ = std.mem.indexOf(u8, content_type, "application/x-www-form-urlencoded") orelse return null;
@@ -342,13 +311,10 @@ pub fn postFormMap(self: *Self, map_key: []const u8) ?std.StringHashMap([]const
342311
var inner_map: std.StringHashMap([]const u8) = std.StringHashMap([]const u8).init(self.allocator);
343312

344313
while (qit.next()) |kv| {
345-
// const decoded_key = self.allocator.alloc(u8, key.len) catch continue;
346314
const trimmed_key = std.mem.trim(u8, std.Uri.percentDecodeInPlace(@constCast(kv.key_ptr.*)), "");
347315
var splited_key = std.mem.splitSequence(u8, trimmed_key, "[");
348316
if (splited_key.index == null) continue;
349317
const key_name = splited_key.first();
350-
// std.debug.print("key_name: {s}\n", .{key_name});
351-
352318
if (!std.mem.eql(u8, key_name, map_key)) continue;
353319

354320
const key_rest = splited_key.next();
@@ -365,10 +331,13 @@ pub fn postFormMap(self: *Self, map_key: []const u8) ?std.StringHashMap([]const
365331
}
366332

367333
pub fn handle(self: *Self) anyerror!void {
334+
if (self.handlers.items.len == 0) try self.handlers.items[self.index](self);
335+
368336
for (self.handlers.items) |handler| {
369-
if (self.index >= self.handlers.items.len) {
337+
if (self.index > self.handlers.items.len) {
370338
continue;
371339
}
340+
372341
try handler(self);
373342
}
374343
}

0 commit comments

Comments
 (0)