Zig query string encoder and pair splitter
Zig
const std = @import("std");
fn encodeQuery(a: std.mem.Allocator, pairs: []const [2][]const u8) ![]u8 {
var out = std.ArrayList(u8).init(a);
const w = out.writer();
for (pairs, 0..) |p, i| {
if (i > 0) try w.writeByte('&');
try w.writeAll(p[0]); try w.writeByte('=');
for (p[1]) |c| if (std.ascii.isAlphanumeric(c) or c == '-') try w.writeByte(c) else try w.print("%{X:0>2}", .{c});
}
return out.toOwnedSlice();
}
fn parseQuery(a: std.mem.Allocator, q: []const u8) !std.StringHashMap([]const u8) {
var map = std.StringHashMap([]const u8).init(a);
var it = std.mem.splitScalar(u8, q, '&');
while (it.next()) |part| {
const eq = std.mem.indexOfScalar(u8, part, '=') orelse continue;
try map.put(try a.dupe(u8, part[0..eq]), try a.dupe(u8, part[eq + 1 ..]));
}
return map;
}