Remove dead code
This commit is contained in:
parent
16c574bdd6
commit
f7bcafe1b1
6 changed files with 64 additions and 249 deletions
|
@ -103,9 +103,9 @@ pub fn build(b: *std.build.Builder) !void {
|
||||||
unittest_http_cmd.dependOn(&unittest_http.step);
|
unittest_http_cmd.dependOn(&unittest_http.step);
|
||||||
unittest_http.addPackage(pkgs.util);
|
unittest_http.addPackage(pkgs.util);
|
||||||
|
|
||||||
//const unittest_util_cmd = b.step("unit:util", "Run tests for util package");
|
const unittest_util_cmd = b.step("unit:util", "Run tests for util package");
|
||||||
//const unittest_util = b.addTest("src/util/Uuid.zig");
|
const unittest_util = b.addTest("src/util/test.zig");
|
||||||
//unittest_util_cmd.dependOn(&unittest_util.step);
|
unittest_util_cmd.dependOn(&unittest_util.step);
|
||||||
|
|
||||||
//const util_tests = b.addTest("src/util/lib.zig");
|
//const util_tests = b.addTest("src/util/lib.zig");
|
||||||
//const sql_tests = b.addTest("src/sql/lib.zig");
|
//const sql_tests = b.addTest("src/sql/lib.zig");
|
||||||
|
@ -115,7 +115,7 @@ pub fn build(b: *std.build.Builder) !void {
|
||||||
//const unit_tests = b.step("unit-tests", "Run tests");
|
//const unit_tests = b.step("unit-tests", "Run tests");
|
||||||
const unittest_all = b.step("unit", "Run unit tests");
|
const unittest_all = b.step("unit", "Run unit tests");
|
||||||
unittest_all.dependOn(unittest_http_cmd);
|
unittest_all.dependOn(unittest_http_cmd);
|
||||||
//unittest_all.dependOn(unittest_util_cmd);
|
unittest_all.dependOn(unittest_util_cmd);
|
||||||
|
|
||||||
const api_integration = b.addTest("./tests/api_integration/lib.zig");
|
const api_integration = b.addTest("./tests/api_integration/lib.zig");
|
||||||
api_integration.addPackage(pkgs.opts);
|
api_integration.addPackage(pkgs.opts);
|
||||||
|
|
|
@ -349,10 +349,62 @@ pub fn router(routes: anytype) Router(@TypeOf(routes)) {
|
||||||
return Router(@TypeOf(routes)){ .routes = routes };
|
return Router(@TypeOf(routes)){ .routes = routes };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const PathIter = struct {
|
||||||
|
is_first: bool,
|
||||||
|
iter: std.mem.SplitIterator(u8),
|
||||||
|
|
||||||
|
pub fn from(path: []const u8) PathIter {
|
||||||
|
return .{ .is_first = true, .iter = std.mem.split(u8, path, "/") };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(self: *PathIter) ?[]const u8 {
|
||||||
|
defer self.is_first = false;
|
||||||
|
while (self.iter.next()) |it| if (it.len != 0) {
|
||||||
|
return it;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (self.is_first) return self.iter.rest();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first(self: *PathIter) []const u8 {
|
||||||
|
std.debug.assert(self.is_first);
|
||||||
|
return self.next().?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rest(self: *PathIter) []const u8 {
|
||||||
|
return self.iter.rest();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "PathIter" {
|
||||||
|
const testCase = struct {
|
||||||
|
fn case(path: []const u8, segments: []const []const u8) !void {
|
||||||
|
var iter = PathIter.from(path);
|
||||||
|
for (segments) |s| {
|
||||||
|
try std.testing.expectEqualStrings(s, iter.next() orelse return error.TestExpectedEqual);
|
||||||
|
}
|
||||||
|
try std.testing.expect(iter.next() == null);
|
||||||
|
}
|
||||||
|
}.case;
|
||||||
|
|
||||||
|
try testCase("", &.{""});
|
||||||
|
try testCase("*", &.{"*"});
|
||||||
|
try testCase("/", &.{""});
|
||||||
|
try testCase("/ab/cd", &.{ "ab", "cd" });
|
||||||
|
try testCase("/ab/cd/", &.{ "ab", "cd" });
|
||||||
|
try testCase("/ab/cd//", &.{ "ab", "cd" });
|
||||||
|
try testCase("ab", &.{"ab"});
|
||||||
|
try testCase("/ab", &.{"ab"});
|
||||||
|
try testCase("ab/", &.{"ab"});
|
||||||
|
try testCase("ab//ab//", &.{ "ab", "ab" });
|
||||||
|
}
|
||||||
|
|
||||||
// helper function for doing route analysis
|
// helper function for doing route analysis
|
||||||
fn pathMatches(route: []const u8, path: []const u8) bool {
|
fn pathMatches(route: []const u8, path: []const u8) bool {
|
||||||
var path_iter = util.PathIter.from(path);
|
var path_iter = PathIter.from(path);
|
||||||
var route_iter = util.PathIter.from(route);
|
var route_iter = PathIter.from(route);
|
||||||
while (route_iter.next()) |route_segment| {
|
while (route_iter.next()) |route_segment| {
|
||||||
const path_segment = path_iter.next() orelse return false;
|
const path_segment = path_iter.next() orelse return false;
|
||||||
if (route_segment.len > 0 and route_segment[0] == ':') {
|
if (route_segment.len > 0 and route_segment[0] == ':') {
|
||||||
|
@ -444,8 +496,8 @@ test "route" {
|
||||||
pub fn Mount(comptime route: []const u8) type {
|
pub fn Mount(comptime route: []const u8) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub fn handle(_: @This(), req: anytype, res: anytype, ctx: anytype, next: anytype) !void {
|
pub fn handle(_: @This(), req: anytype, res: anytype, ctx: anytype, next: anytype) !void {
|
||||||
var path_iter = util.PathIter.from(ctx.path);
|
var path_iter = PathIter.from(ctx.path);
|
||||||
comptime var route_iter = util.PathIter.from(route);
|
comptime var route_iter = PathIter.from(route);
|
||||||
var path_unused: []const u8 = ctx.path;
|
var path_unused: []const u8 = ctx.path;
|
||||||
|
|
||||||
inline while (comptime route_iter.next()) |route_segment| {
|
inline while (comptime route_iter.next()) |route_segment| {
|
||||||
|
@ -491,8 +543,8 @@ test "mount" {
|
||||||
|
|
||||||
fn parseArgsFromPath(comptime route: []const u8, comptime Args: type, path: []const u8) !Args {
|
fn parseArgsFromPath(comptime route: []const u8, comptime Args: type, path: []const u8) !Args {
|
||||||
var args: Args = undefined;
|
var args: Args = undefined;
|
||||||
var path_iter = util.PathIter.from(path);
|
var path_iter = PathIter.from(path);
|
||||||
comptime var route_iter = util.PathIter.from(route);
|
comptime var route_iter = PathIter.from(route);
|
||||||
inline while (comptime route_iter.next()) |route_segment| {
|
inline while (comptime route_iter.next()) |route_segment| {
|
||||||
const path_segment = path_iter.next() orelse return error.RouteMismatch;
|
const path_segment = path_iter.next() orelse return error.RouteMismatch;
|
||||||
if (route_segment.len > 0 and route_segment[0] == ':') {
|
if (route_segment.len > 0 and route_segment[0] == ':') {
|
||||||
|
|
|
@ -19,8 +19,9 @@ fn execScript(db: anytype, script: []const u8, alloc: std.mem.Allocator) !void {
|
||||||
const tx = try db.beginOrSavepoint();
|
const tx = try db.beginOrSavepoint();
|
||||||
errdefer tx.rollback();
|
errdefer tx.rollback();
|
||||||
|
|
||||||
var iter = util.SqlStmtIter.from(script);
|
var iter = std.mem.split(u8, script, ";");
|
||||||
while (iter.next()) |stmt| {
|
while (iter.next()) |stmt| {
|
||||||
|
if (stmt.len == 0) continue;
|
||||||
try execStmt(tx, stmt, alloc);
|
try execStmt(tx, stmt, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
161
src/util/Url.zig
161
src/util/Url.zig
|
@ -1,161 +0,0 @@
|
||||||
const Url = @This();
|
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
scheme: []const u8,
|
|
||||||
hostport: []const u8,
|
|
||||||
path: []const u8,
|
|
||||||
query: []const u8,
|
|
||||||
fragment: []const u8,
|
|
||||||
|
|
||||||
pub fn parse(url: []const u8) !Url {
|
|
||||||
const scheme_end = for (url) |ch, i| {
|
|
||||||
if (ch == ':') break i;
|
|
||||||
} else return error.InvalidUrl;
|
|
||||||
|
|
||||||
if (url.len < scheme_end + 3 or url[scheme_end + 1] != '/' or url[scheme_end + 1] != '/') return error.InvalidUrl;
|
|
||||||
|
|
||||||
const hostport_start = scheme_end + 3;
|
|
||||||
const hostport_end = for (url[hostport_start..]) |ch, i| {
|
|
||||||
if (ch == '/' or ch == '?' or ch == '#') break i + hostport_start;
|
|
||||||
} else url.len;
|
|
||||||
|
|
||||||
const path_end = for (url[hostport_end..]) |ch, i| {
|
|
||||||
if (ch == '?' or ch == '#') break i + hostport_end;
|
|
||||||
} else url.len;
|
|
||||||
|
|
||||||
const query_end = if (!(url.len > path_end and url[path_end] == '?'))
|
|
||||||
path_end
|
|
||||||
else for (url[path_end..]) |ch, i| {
|
|
||||||
if (ch == '#') break i + path_end;
|
|
||||||
} else url.len;
|
|
||||||
|
|
||||||
const query = url[path_end..query_end];
|
|
||||||
const fragment = url[query_end..];
|
|
||||||
|
|
||||||
return Url{
|
|
||||||
.scheme = url[0..scheme_end],
|
|
||||||
.hostport = url[hostport_start..hostport_end],
|
|
||||||
.path = url[hostport_end..path_end],
|
|
||||||
.query = if (query.len > 0) query[1..] else query,
|
|
||||||
.fragment = if (fragment.len > 0) fragment[1..] else fragment,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getQuery(self: Url, param: []const u8) ?[]const u8 {
|
|
||||||
var key_start: usize = 0;
|
|
||||||
std.log.debug("query: {s}", .{self.query});
|
|
||||||
while (key_start < self.query.len) {
|
|
||||||
const key_end = for (self.query[key_start..]) |ch, i| {
|
|
||||||
if (ch == '=') break key_start + i;
|
|
||||||
} else return null;
|
|
||||||
|
|
||||||
const val_start = key_end + 1;
|
|
||||||
const val_end = for (self.query[val_start..]) |ch, i| {
|
|
||||||
if (ch == '&') break val_start + i;
|
|
||||||
} else self.query.len;
|
|
||||||
|
|
||||||
const key = self.query[key_start..key_end];
|
|
||||||
if (std.mem.eql(u8, key, param)) return self.query[val_start..val_end];
|
|
||||||
|
|
||||||
key_start = val_end + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn strDecode(buf: []u8, str: []const u8) ![]u8 {
|
|
||||||
var str_i: usize = 0;
|
|
||||||
var buf_i: usize = 0;
|
|
||||||
while (str_i < str.len) : ({
|
|
||||||
str_i += 1;
|
|
||||||
buf_i += 1;
|
|
||||||
}) {
|
|
||||||
if (buf_i >= buf.len) return error.NoSpaceLeft;
|
|
||||||
const ch = str[str_i];
|
|
||||||
if (ch == '%') {
|
|
||||||
if (str.len < str_i + 2) return error.BadEscape;
|
|
||||||
|
|
||||||
const hi = try std.fmt.charToDigit(str[str_i + 1], 16);
|
|
||||||
const lo = try std.fmt.charToDIgit(str[str_i + 2], 16);
|
|
||||||
str_i += 2;
|
|
||||||
|
|
||||||
buf[buf_i] = (hi << 4) | lo;
|
|
||||||
} else {
|
|
||||||
buf[buf_i] = str[str_i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf[0..buf_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expectEqualUrl(expected: Url, actual: Url) !void {
|
|
||||||
const t = @import("std").testing;
|
|
||||||
try t.expectEqualStrings(expected.scheme, actual.scheme);
|
|
||||||
try t.expectEqualStrings(expected.hostport, actual.hostport);
|
|
||||||
try t.expectEqualStrings(expected.path, actual.path);
|
|
||||||
try t.expectEqualStrings(expected.query, actual.query);
|
|
||||||
try t.expectEqualStrings(expected.fragment, actual.fragment);
|
|
||||||
}
|
|
||||||
test "Url" {
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "https",
|
|
||||||
.hostport = "example.com",
|
|
||||||
.path = "",
|
|
||||||
.query = "",
|
|
||||||
.fragment = "",
|
|
||||||
}, try Url.parse("https://example.com"));
|
|
||||||
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "https",
|
|
||||||
.hostport = "example.com:1234",
|
|
||||||
.path = "",
|
|
||||||
.query = "",
|
|
||||||
.fragment = "",
|
|
||||||
}, try Url.parse("https://example.com:1234"));
|
|
||||||
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "http",
|
|
||||||
.hostport = "example.com",
|
|
||||||
.path = "/home",
|
|
||||||
.query = "",
|
|
||||||
.fragment = "",
|
|
||||||
}, try Url.parse("http://example.com/home"));
|
|
||||||
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "https",
|
|
||||||
.hostport = "example.com",
|
|
||||||
.path = "",
|
|
||||||
.query = "query=abc",
|
|
||||||
.fragment = "",
|
|
||||||
}, try Url.parse("https://example.com?query=abc"));
|
|
||||||
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "https",
|
|
||||||
.hostport = "example.com",
|
|
||||||
.path = "",
|
|
||||||
.query = "query=abc",
|
|
||||||
.fragment = "",
|
|
||||||
}, try Url.parse("https://example.com?query=abc"));
|
|
||||||
|
|
||||||
try expectEqualUrl(.{
|
|
||||||
.scheme = "https",
|
|
||||||
.hostport = "example.com",
|
|
||||||
.path = "/path/to/resource",
|
|
||||||
.query = "query=abc",
|
|
||||||
.fragment = "123",
|
|
||||||
}, try Url.parse("https://example.com/path/to/resource?query=abc#123"));
|
|
||||||
|
|
||||||
const t = @import("std").testing;
|
|
||||||
try t.expectError(error.InvalidUrl, Url.parse("https:example.com"));
|
|
||||||
try t.expectError(error.InvalidUrl, Url.parse("example.com"));
|
|
||||||
}
|
|
||||||
|
|
||||||
test "Url.getQuery" {
|
|
||||||
const url = try Url.parse("https://example.com?a=xyz&b=jkl");
|
|
||||||
const t = @import("std").testing;
|
|
||||||
|
|
||||||
try t.expectEqualStrings("xyz", url.getQuery("a").?);
|
|
||||||
try t.expectEqualStrings("jkl", url.getQuery("b").?);
|
|
||||||
try t.expect(url.getQuery("c") == null);
|
|
||||||
try t.expect(url.getQuery("xyz") == null);
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn Separator(comptime separator: u8) type {
|
|
||||||
return struct {
|
|
||||||
const Self = @This();
|
|
||||||
str: []const u8,
|
|
||||||
pub fn from(str: []const u8) Self {
|
|
||||||
return .{ .str = std.mem.trim(u8, str, &.{separator}) };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(self: *Self) ?[]const u8 {
|
|
||||||
if (self.str.len == 0) return null;
|
|
||||||
|
|
||||||
const part = std.mem.sliceTo(self.str, separator);
|
|
||||||
self.str = std.mem.trimLeft(u8, self.str[part.len..], &.{separator});
|
|
||||||
|
|
||||||
return part;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const PathIter = struct {
|
|
||||||
is_first: bool,
|
|
||||||
iter: std.mem.SplitIterator(u8),
|
|
||||||
|
|
||||||
pub fn from(path: []const u8) PathIter {
|
|
||||||
return .{ .is_first = true, .iter = std.mem.split(u8, path, "/") };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(self: *PathIter) ?[]const u8 {
|
|
||||||
defer self.is_first = false;
|
|
||||||
while (self.iter.next()) |it| if (it.len != 0) {
|
|
||||||
return it;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (self.is_first) return self.iter.rest();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn first(self: *PathIter) []const u8 {
|
|
||||||
std.debug.assert(self.is_first);
|
|
||||||
return self.next().?;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rest(self: *PathIter) []const u8 {
|
|
||||||
return self.iter.rest();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test "PathIter /ab/cd/" {
|
|
||||||
const path = "/ab/cd/";
|
|
||||||
var it = PathIter.from(path);
|
|
||||||
try std.testing.expectEqualStrings("ab", it.next().?);
|
|
||||||
try std.testing.expectEqualStrings("cd", it.next().?);
|
|
||||||
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
test "PathIter ''" {
|
|
||||||
const path = "";
|
|
||||||
var it = PathIter.from(path);
|
|
||||||
try std.testing.expectEqualStrings("", it.next().?);
|
|
||||||
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
test "PathIter ab/c//defg/" {
|
|
||||||
const path = "ab/c//defg/";
|
|
||||||
var it = PathIter.from(path);
|
|
||||||
try std.testing.expectEqualStrings("ab", it.next().?);
|
|
||||||
try std.testing.expectEqualStrings("c", it.next().?);
|
|
||||||
try std.testing.expectEqualStrings("defg", it.next().?);
|
|
||||||
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
|
|
||||||
}
|
|
|
@ -1,11 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const iters = @import("./iters.zig");
|
|
||||||
|
|
||||||
pub const Uuid = @import("./Uuid.zig");
|
pub const Uuid = @import("./Uuid.zig");
|
||||||
pub const DateTime = @import("./DateTime.zig");
|
pub const DateTime = @import("./DateTime.zig");
|
||||||
pub const Url = @import("./Url.zig");
|
|
||||||
pub const PathIter = iters.PathIter;
|
|
||||||
pub const SqlStmtIter = iters.Separator(';');
|
|
||||||
pub const serialize = @import("./serialize.zig");
|
pub const serialize = @import("./serialize.zig");
|
||||||
pub const Deserializer = serialize.Deserializer;
|
pub const Deserializer = serialize.Deserializer;
|
||||||
pub const DeserializerContext = serialize.DeserializerContext;
|
pub const DeserializerContext = serialize.DeserializerContext;
|
||||||
|
|
Loading…
Reference in a new issue