more renaming
This commit is contained in:
parent
4ec74d8967
commit
80266514e0
4 changed files with 153 additions and 152 deletions
151
src/http/QueryParams.zig
Normal file
151
src/http/QueryParams.zig
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
//!Units:
|
||||
//!
|
||||
//! m # metric (SI) (used by default everywhere except US)
|
||||
//! u # USCS (used by default in US)
|
||||
//! M # show wind speed in m/s
|
||||
//!
|
||||
//!View options:
|
||||
//!
|
||||
//! 0 # only current weather
|
||||
//! 1 # current weather + today's forecast
|
||||
//! 2 # current weather + today's + tomorrow's forecast
|
||||
//! A # ignore User-Agent and force ANSI output format (terminal)
|
||||
//! d # restrict output to standard console font glyphs
|
||||
//! F # do not show the "Follow" line
|
||||
//! n # narrow version (only day and night)
|
||||
//! q # quiet version (no "Weather report" text)
|
||||
//! Q # superquiet version (no "Weather report", no city name)
|
||||
//! T # switch terminal sequences off (no colors)
|
||||
|
||||
const std = @import("std");
|
||||
const RenderOptions = @import("../render/Formatted.zig").RenderOptions;
|
||||
|
||||
const QueryParams = @This();
|
||||
|
||||
format: ?[]const u8 = null,
|
||||
lang: ?[]const u8 = null,
|
||||
location: ?[]const u8 = null,
|
||||
transparency: ?u8 = null,
|
||||
/// A: Ignore user agent and force ansi mode
|
||||
ansi: bool = false,
|
||||
/// T: Avoid terminal sequences and just output plain text
|
||||
text_only: bool = false,
|
||||
/// This is necessary because it it imporant to know if the user explicitly
|
||||
/// requested imperial/metric
|
||||
use_imperial: ?bool = null,
|
||||
render_options: RenderOptions,
|
||||
|
||||
pub fn parse(allocator: std.mem.Allocator, query_string: []const u8) !QueryParams {
|
||||
// SAFETY: function adds render_options at end of function before return
|
||||
var params = QueryParams{ .render_options = undefined };
|
||||
var iter = std.mem.splitScalar(u8, query_string, '&');
|
||||
var render_options = RenderOptions{};
|
||||
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 (key.len == 1) {
|
||||
switch (key[0]) {
|
||||
'0' => render_options.days = 0,
|
||||
'1' => render_options.days = 1,
|
||||
'2' => render_options.days = 2,
|
||||
'u' => params.use_imperial = true,
|
||||
'm' => params.use_imperial = false,
|
||||
'n' => render_options.narrow = true,
|
||||
'q' => render_options.quiet = true,
|
||||
'Q' => render_options.super_quiet = true,
|
||||
'A' => params.ansi = true,
|
||||
'T' => params.text_only = true,
|
||||
't' => params.transparency = 150,
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
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, "use_imperial")) {
|
||||
params.use_imperial = true;
|
||||
} else if (std.mem.eql(u8, key, "use_metric")) {
|
||||
params.use_imperial = false;
|
||||
} else if (std.mem.eql(u8, key, "transparency")) {
|
||||
if (value) |v| {
|
||||
params.transparency = try std.fmt.parseInt(u8, v, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.use_imperial) |u| render_options.use_imperial = u;
|
||||
params.render_options = render_options;
|
||||
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.use_imperial == 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.expect(params1.use_imperial.?);
|
||||
|
||||
// Test with "u=" (empty value)
|
||||
const params2 = try QueryParams.parse(allocator, "u=");
|
||||
try std.testing.expect(params2.use_imperial.?);
|
||||
|
||||
// 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.expect(params3.use_imperial.?);
|
||||
}
|
||||
|
||||
test "parse units parameters" {
|
||||
const allocator = std.testing.allocator;
|
||||
const params_m = try QueryParams.parse(allocator, "m");
|
||||
try std.testing.expect(!params_m.use_imperial.?);
|
||||
|
||||
const params_u = try QueryParams.parse(allocator, "u");
|
||||
try std.testing.expect(params_u.use_imperial.?);
|
||||
|
||||
const params_u_query = try QueryParams.parse(allocator, "u=");
|
||||
try std.testing.expect(params_u_query.use_imperial.?);
|
||||
}
|
||||
|
||||
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.expect(!params.use_imperial.?);
|
||||
}
|
||||
|
||||
test "parse transparency" {
|
||||
const allocator = std.testing.allocator;
|
||||
const params_t = try QueryParams.parse(allocator, "t");
|
||||
try std.testing.expect(params_t.transparency != null);
|
||||
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.?);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
|||
const httpz = @import("httpz");
|
||||
const WeatherProvider = @import("../weather/Provider.zig");
|
||||
const Resolver = @import("../location/resolver.zig").Resolver;
|
||||
const QueryParams = @import("query.zig").QueryParams;
|
||||
const QueryParams = @import("QueryParams.zig");
|
||||
const Formatted = @import("../render/Formatted.zig");
|
||||
const Line = @import("../render/Line.zig");
|
||||
const Json = @import("../render/Json.zig");
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
const std = @import("std");
|
||||
const RenderOptions = @import("../render/Formatted.zig").RenderOptions;
|
||||
|
||||
///Units:
|
||||
///
|
||||
/// m # metric (SI) (used by default everywhere except US)
|
||||
/// u # USCS (used by default in US)
|
||||
/// M # show wind speed in m/s
|
||||
///
|
||||
///View options:
|
||||
///
|
||||
/// 0 # only current weather
|
||||
/// 1 # current weather + today's forecast
|
||||
/// 2 # current weather + today's + tomorrow's forecast
|
||||
/// A # ignore User-Agent and force ANSI output format (terminal)
|
||||
/// d # restrict output to standard console font glyphs
|
||||
/// F # do not show the "Follow" line
|
||||
/// n # narrow version (only day and night)
|
||||
/// q # quiet version (no "Weather report" text)
|
||||
/// Q # superquiet version (no "Weather report", no city name)
|
||||
/// T # switch terminal sequences off (no colors)
|
||||
pub const QueryParams = struct {
|
||||
format: ?[]const u8 = null,
|
||||
lang: ?[]const u8 = null,
|
||||
location: ?[]const u8 = null,
|
||||
transparency: ?u8 = null,
|
||||
/// A: Ignore user agent and force ansi mode
|
||||
ansi: bool = false,
|
||||
/// T: Avoid terminal sequences and just output plain text
|
||||
text_only: bool = false,
|
||||
/// This is necessary because it it imporant to know if the user explicitly
|
||||
/// requested imperial/metric
|
||||
use_imperial: ?bool = null,
|
||||
render_options: RenderOptions,
|
||||
|
||||
pub fn parse(allocator: std.mem.Allocator, query_string: []const u8) !QueryParams {
|
||||
// SAFETY: function adds render_options at end of function before return
|
||||
var params = QueryParams{ .render_options = undefined };
|
||||
var iter = std.mem.splitScalar(u8, query_string, '&');
|
||||
var render_options = RenderOptions{};
|
||||
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 (key.len == 1) {
|
||||
switch (key[0]) {
|
||||
'0' => render_options.days = 0,
|
||||
'1' => render_options.days = 1,
|
||||
'2' => render_options.days = 2,
|
||||
'u' => params.use_imperial = true,
|
||||
'm' => params.use_imperial = false,
|
||||
'n' => render_options.narrow = true,
|
||||
'q' => render_options.quiet = true,
|
||||
'Q' => render_options.super_quiet = true,
|
||||
'A' => params.ansi = true,
|
||||
'T' => params.text_only = true,
|
||||
't' => params.transparency = 150,
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
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, "use_imperial")) {
|
||||
params.use_imperial = true;
|
||||
} else if (std.mem.eql(u8, key, "use_metric")) {
|
||||
params.use_imperial = false;
|
||||
} else if (std.mem.eql(u8, key, "transparency")) {
|
||||
if (value) |v| {
|
||||
params.transparency = try std.fmt.parseInt(u8, v, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.use_imperial) |u| render_options.use_imperial = u;
|
||||
params.render_options = render_options;
|
||||
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.use_imperial == 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.expect(params1.use_imperial.?);
|
||||
|
||||
// Test with "u=" (empty value)
|
||||
const params2 = try QueryParams.parse(allocator, "u=");
|
||||
try std.testing.expect(params2.use_imperial.?);
|
||||
|
||||
// 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.expect(params3.use_imperial.?);
|
||||
}
|
||||
|
||||
test "parse units parameters" {
|
||||
const allocator = std.testing.allocator;
|
||||
const params_m = try QueryParams.parse(allocator, "m");
|
||||
try std.testing.expect(!params_m.use_imperial.?);
|
||||
|
||||
const params_u = try QueryParams.parse(allocator, "u");
|
||||
try std.testing.expect(params_u.use_imperial.?);
|
||||
|
||||
const params_u_query = try QueryParams.parse(allocator, "u=");
|
||||
try std.testing.expect(params_u_query.use_imperial.?);
|
||||
}
|
||||
|
||||
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.expect(!params.use_imperial.?);
|
||||
}
|
||||
|
||||
test "parse transparency" {
|
||||
const allocator = std.testing.allocator;
|
||||
const params_t = try QueryParams.parse(allocator, "t");
|
||||
try std.testing.expect(params_t.transparency != null);
|
||||
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.?);
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ test {
|
|||
_ = @import("cache/Lru.zig");
|
||||
_ = @import("weather/Mock.zig");
|
||||
_ = @import("http/RateLimiter.zig");
|
||||
_ = @import("http/query.zig");
|
||||
_ = @import("http/QueryParams.zig");
|
||||
_ = @import("http/help.zig");
|
||||
_ = @import("render/Formatted.zig");
|
||||
_ = @import("render/Line.zig");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue