115 lines
4.3 KiB
Zig
115 lines
4.3 KiB
Zig
const std = @import("std");
|
|
|
|
pub const QueryParams = struct {
|
|
format: ?[]const u8 = null,
|
|
lang: ?[]const u8 = null,
|
|
location: ?[]const u8 = null,
|
|
units: ?Units = null,
|
|
transparency: ?u8 = null,
|
|
|
|
pub const Units = enum {
|
|
metric,
|
|
uscs,
|
|
};
|
|
|
|
pub fn parse(allocator: std.mem.Allocator, query_string: []const u8) !QueryParams {
|
|
var params = QueryParams{};
|
|
var iter = std.mem.splitScalar(u8, query_string, '&');
|
|
|
|
while (iter.next()) |pair| {
|
|
if (pair.len == 0) continue;
|
|
|
|
var kv = std.mem.splitScalar(u8, pair, '=');
|
|
const key = kv.next() orelse continue;
|
|
const value = kv.next();
|
|
|
|
if (std.mem.eql(u8, key, "format")) {
|
|
params.format = if (value) |v| try allocator.dupe(u8, v) else null;
|
|
} else if (std.mem.eql(u8, key, "lang")) {
|
|
params.lang = if (value) |v| try allocator.dupe(u8, v) else null;
|
|
} else if (std.mem.eql(u8, key, "location")) {
|
|
params.location = if (value) |v| try allocator.dupe(u8, v) else null;
|
|
} else if (std.mem.eql(u8, key, "u")) {
|
|
params.units = .uscs;
|
|
} else if (std.mem.eql(u8, key, "m")) {
|
|
params.units = .metric;
|
|
} else if (std.mem.eql(u8, key, "use_imperial")) {
|
|
params.units = .uscs;
|
|
} else if (std.mem.eql(u8, key, "use_metric")) {
|
|
params.units = .metric;
|
|
} else if (std.mem.eql(u8, key, "transparency")) {
|
|
if (value) |v| {
|
|
params.transparency = try std.fmt.parseInt(u8, v, 10);
|
|
}
|
|
} else if (std.mem.eql(u8, key, "t")) {
|
|
params.transparency = 150;
|
|
}
|
|
}
|
|
|
|
return params;
|
|
}
|
|
};
|
|
|
|
test "parse empty query" {
|
|
const allocator = std.testing.allocator;
|
|
const params = try QueryParams.parse(allocator, "");
|
|
try std.testing.expect(params.format == null);
|
|
try std.testing.expect(params.lang == null);
|
|
try std.testing.expect(params.units == null);
|
|
}
|
|
|
|
test "parse format parameter" {
|
|
const allocator = std.testing.allocator;
|
|
const params = try QueryParams.parse(allocator, "format=j1");
|
|
defer if (params.format) |f| allocator.free(f);
|
|
try std.testing.expect(params.format != null);
|
|
try std.testing.expectEqualStrings("j1", params.format.?);
|
|
}
|
|
|
|
test "parse units with question mark" {
|
|
const allocator = std.testing.allocator;
|
|
|
|
// Test with just "u" (no question mark in query string)
|
|
const params1 = try QueryParams.parse(allocator, "u");
|
|
try std.testing.expectEqual(QueryParams.Units.uscs, params1.units.?);
|
|
|
|
// Test with "u=" (empty value)
|
|
const params2 = try QueryParams.parse(allocator, "u=");
|
|
try std.testing.expectEqual(QueryParams.Units.uscs, params2.units.?);
|
|
|
|
// Test combined with other params
|
|
const params3 = try QueryParams.parse(allocator, "format=3&u");
|
|
defer if (params3.format) |f| allocator.free(f);
|
|
try std.testing.expectEqual(QueryParams.Units.uscs, params3.units.?);
|
|
}
|
|
|
|
test "parse units parameters" {
|
|
const allocator = std.testing.allocator;
|
|
const params_m = try QueryParams.parse(allocator, "m");
|
|
try std.testing.expectEqual(QueryParams.Units.metric, params_m.units.?);
|
|
|
|
const params_u = try QueryParams.parse(allocator, "u");
|
|
try std.testing.expectEqual(QueryParams.Units.uscs, params_u.units.?);
|
|
|
|
const params_u_query = try QueryParams.parse(allocator, "u=");
|
|
try std.testing.expectEqual(QueryParams.Units.uscs, params_u_query.units.?);
|
|
}
|
|
|
|
test "parse multiple parameters" {
|
|
const allocator = std.testing.allocator;
|
|
const params = try QueryParams.parse(allocator, "format=3&lang=de&m");
|
|
defer if (params.format) |f| allocator.free(f);
|
|
defer if (params.lang) |l| allocator.free(l);
|
|
try std.testing.expectEqualStrings("3", params.format.?);
|
|
try std.testing.expectEqualStrings("de", params.lang.?);
|
|
try std.testing.expectEqual(QueryParams.Units.metric, params.units.?);
|
|
}
|
|
|
|
test "parse transparency" {
|
|
const allocator = std.testing.allocator;
|
|
const params_t = try QueryParams.parse(allocator, "t");
|
|
try std.testing.expectEqual(@as(u8, 150), params_t.transparency.?);
|
|
|
|
const params_custom = try QueryParams.parse(allocator, "transparency=200");
|
|
try std.testing.expectEqual(@as(u8, 200), params_custom.transparency.?);
|
|
}
|