bring config to the top level/rename file
This commit is contained in:
parent
06720cc53c
commit
ea17e18c6f
4 changed files with 88 additions and 88 deletions
84
src/Config.zig
Normal file
84
src/Config.zig
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Config = @This();
|
||||||
|
|
||||||
|
listen_host: []const u8,
|
||||||
|
listen_port: u16,
|
||||||
|
cache_size: usize,
|
||||||
|
cache_dir: []const u8,
|
||||||
|
|
||||||
|
/// GeoLite2 is used for GeoIP (IP -> geographic location)
|
||||||
|
/// IP2Location is a fallback if IP is not found in this db
|
||||||
|
geolite_path: []const u8,
|
||||||
|
|
||||||
|
/// Geocache file stores location lookups
|
||||||
|
/// (e.g. "Portland -> 45.52345°N, -122.67621° W). When not found in cache,
|
||||||
|
/// a web service from Nominatum (https://nominatim.org/) is used
|
||||||
|
geocache_file: ?[]const u8,
|
||||||
|
|
||||||
|
/// If provided, when GeoLite2 is missing data, https://www.ip2location.com/
|
||||||
|
/// can be used. This will also be cached in the cached file
|
||||||
|
ip2location_api_key: ?[]const u8,
|
||||||
|
ip2location_cache_file: []const u8,
|
||||||
|
|
||||||
|
pub fn load(allocator: std.mem.Allocator) !Config {
|
||||||
|
var env = try std.process.getEnvMap(allocator);
|
||||||
|
defer env.deinit();
|
||||||
|
|
||||||
|
// Get XDG_CACHE_HOME or default to ~/.cache
|
||||||
|
const home = env.get("HOME") orelse "/tmp";
|
||||||
|
const xdg_cache = env.get("XDG_CACHE_HOME") orelse
|
||||||
|
try std.fs.path.join(allocator, &[_][]const u8{ home, ".cache" });
|
||||||
|
defer if (env.get("XDG_CACHE_HOME") == null) allocator.free(xdg_cache);
|
||||||
|
|
||||||
|
const default_cache_dir = try std.fs.path.join(allocator, &[_][]const u8{ xdg_cache, "wttr" });
|
||||||
|
defer allocator.free(default_cache_dir);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.listen_host = env.get("WTTR_LISTEN_HOST") orelse try allocator.dupe(u8, "0.0.0.0"),
|
||||||
|
.listen_port = if (env.get("WTTR_LISTEN_PORT")) |p|
|
||||||
|
try std.fmt.parseInt(u16, p, 10)
|
||||||
|
else
|
||||||
|
8002,
|
||||||
|
.cache_size = if (env.get("WTTR_CACHE_SIZE")) |s|
|
||||||
|
try std.fmt.parseInt(usize, s, 10)
|
||||||
|
else
|
||||||
|
10_000,
|
||||||
|
.cache_dir = try allocator.dupe(u8, env.get("WTTR_CACHE_DIR") orelse default_cache_dir),
|
||||||
|
.geolite_path = blk: {
|
||||||
|
if (env.get("WTTR_GEOLITE_PATH")) |v| {
|
||||||
|
break :blk try allocator.dupe(u8, v);
|
||||||
|
}
|
||||||
|
break :blk try std.fmt.allocPrint(allocator, "{s}/GeoLite2-City.mmdb", .{
|
||||||
|
env.get("WTTR_CACHE_DIR") orelse default_cache_dir,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.geocache_file = if (env.get("WTTR_GEOCACHE_FILE")) |v| try allocator.dupe(u8, v) else try std.fs.path.join(allocator, &[_][]const u8{ default_cache_dir, "geocache.json" }),
|
||||||
|
.ip2location_api_key = if (env.get("IP2LOCATION_API_KEY")) |v| try allocator.dupe(u8, v) else null,
|
||||||
|
.ip2location_cache_file = blk: {
|
||||||
|
if (env.get("IP2LOCATION_CACHE_FILE")) |v| {
|
||||||
|
break :blk try allocator.dupe(u8, v);
|
||||||
|
}
|
||||||
|
break :blk try std.fmt.allocPrint(allocator, "{s}/ip2location.cache", .{env.get("WTTR_CACHE_DIR") orelse default_cache_dir});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: Config, allocator: std.mem.Allocator) void {
|
||||||
|
allocator.free(self.listen_host);
|
||||||
|
allocator.free(self.cache_dir);
|
||||||
|
allocator.free(self.geolite_path);
|
||||||
|
if (self.geocache_file) |f| allocator.free(f);
|
||||||
|
if (self.ip2location_api_key) |k| allocator.free(k);
|
||||||
|
allocator.free(self.ip2location_cache_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "config loads defaults" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const cfg = try Config.load(allocator);
|
||||||
|
defer cfg.deinit(allocator);
|
||||||
|
|
||||||
|
try std.testing.expectEqualStrings("0.0.0.0", cfg.listen_host);
|
||||||
|
try std.testing.expectEqual(@as(u16, 8002), cfg.listen_port);
|
||||||
|
try std.testing.expectEqual(@as(usize, 10_000), cfg.cache_size);
|
||||||
|
}
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub const Config = struct {
|
|
||||||
listen_host: []const u8,
|
|
||||||
listen_port: u16,
|
|
||||||
cache_size: usize,
|
|
||||||
cache_dir: []const u8,
|
|
||||||
|
|
||||||
/// GeoLite2 is used for GeoIP (IP -> geographic location)
|
|
||||||
/// IP2Location is a fallback if IP is not found in this db
|
|
||||||
geolite_path: []const u8,
|
|
||||||
|
|
||||||
/// Geocache file stores location lookups
|
|
||||||
/// (e.g. "Portland -> 45.52345°N, -122.67621° W). When not found in cache,
|
|
||||||
/// a web service from Nominatum (https://nominatim.org/) is used
|
|
||||||
geocache_file: ?[]const u8,
|
|
||||||
|
|
||||||
/// If provided, when GeoLite2 is missing data, https://www.ip2location.com/
|
|
||||||
/// can be used. This will also be cached in the cached file
|
|
||||||
ip2location_api_key: ?[]const u8,
|
|
||||||
ip2location_cache_file: []const u8,
|
|
||||||
|
|
||||||
pub fn load(allocator: std.mem.Allocator) !Config {
|
|
||||||
var env = try std.process.getEnvMap(allocator);
|
|
||||||
defer env.deinit();
|
|
||||||
|
|
||||||
// Get XDG_CACHE_HOME or default to ~/.cache
|
|
||||||
const home = env.get("HOME") orelse "/tmp";
|
|
||||||
const xdg_cache = env.get("XDG_CACHE_HOME") orelse
|
|
||||||
try std.fs.path.join(allocator, &[_][]const u8{ home, ".cache" });
|
|
||||||
defer if (env.get("XDG_CACHE_HOME") == null) allocator.free(xdg_cache);
|
|
||||||
|
|
||||||
const default_cache_dir = try std.fs.path.join(allocator, &[_][]const u8{ xdg_cache, "wttr" });
|
|
||||||
defer allocator.free(default_cache_dir);
|
|
||||||
|
|
||||||
return Config{
|
|
||||||
.listen_host = env.get("WTTR_LISTEN_HOST") orelse try allocator.dupe(u8, "0.0.0.0"),
|
|
||||||
.listen_port = if (env.get("WTTR_LISTEN_PORT")) |p|
|
|
||||||
try std.fmt.parseInt(u16, p, 10)
|
|
||||||
else
|
|
||||||
8002,
|
|
||||||
.cache_size = if (env.get("WTTR_CACHE_SIZE")) |s|
|
|
||||||
try std.fmt.parseInt(usize, s, 10)
|
|
||||||
else
|
|
||||||
10_000,
|
|
||||||
.cache_dir = try allocator.dupe(u8, env.get("WTTR_CACHE_DIR") orelse default_cache_dir),
|
|
||||||
.geolite_path = blk: {
|
|
||||||
if (env.get("WTTR_GEOLITE_PATH")) |v| {
|
|
||||||
break :blk try allocator.dupe(u8, v);
|
|
||||||
}
|
|
||||||
break :blk try std.fmt.allocPrint(allocator, "{s}/GeoLite2-City.mmdb", .{
|
|
||||||
env.get("WTTR_CACHE_DIR") orelse default_cache_dir,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
.geocache_file = if (env.get("WTTR_GEOCACHE_FILE")) |v| try allocator.dupe(u8, v) else try std.fs.path.join(allocator, &[_][]const u8{ default_cache_dir, "geocache.json" }),
|
|
||||||
.ip2location_api_key = if (env.get("IP2LOCATION_API_KEY")) |v| try allocator.dupe(u8, v) else null,
|
|
||||||
.ip2location_cache_file = blk: {
|
|
||||||
if (env.get("IP2LOCATION_CACHE_FILE")) |v| {
|
|
||||||
break :blk try allocator.dupe(u8, v);
|
|
||||||
}
|
|
||||||
break :blk try std.fmt.allocPrint(allocator, "{s}/ip2location.cache", .{env.get("WTTR_CACHE_DIR") orelse default_cache_dir});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: Config, allocator: std.mem.Allocator) void {
|
|
||||||
allocator.free(self.listen_host);
|
|
||||||
allocator.free(self.cache_dir);
|
|
||||||
allocator.free(self.geolite_path);
|
|
||||||
if (self.geocache_file) |f| allocator.free(f);
|
|
||||||
if (self.ip2location_api_key) |k| allocator.free(k);
|
|
||||||
allocator.free(self.ip2location_cache_file);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test "config loads defaults" {
|
|
||||||
const allocator = std.testing.allocator;
|
|
||||||
const cfg = try Config.load(allocator);
|
|
||||||
defer cfg.deinit(allocator);
|
|
||||||
|
|
||||||
try std.testing.expectEqualStrings("0.0.0.0", cfg.listen_host);
|
|
||||||
try std.testing.expectEqual(@as(u16, 8002), cfg.listen_port);
|
|
||||||
try std.testing.expectEqual(@as(usize, 10_000), cfg.cache_size);
|
|
||||||
}
|
|
||||||
|
|
@ -139,7 +139,7 @@ test "GeoIP init with invalid path fails" {
|
||||||
|
|
||||||
test "isUSIP detects US IPs" {
|
test "isUSIP detects US IPs" {
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
const Config = @import("../config.zig").Config;
|
const Config = @import("../Config.zig");
|
||||||
const config = try Config.load(allocator);
|
const config = try Config.load(allocator);
|
||||||
defer config.deinit(allocator);
|
defer config.deinit(allocator);
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const config = @import("config.zig");
|
const Config = @import("Config.zig");
|
||||||
const Cache = @import("cache/Cache.zig");
|
const Cache = @import("cache/Cache.zig");
|
||||||
const MetNo = @import("weather/MetNo.zig");
|
const MetNo = @import("weather/MetNo.zig");
|
||||||
const Server = @import("http/Server.zig");
|
const Server = @import("http/Server.zig");
|
||||||
|
|
@ -15,7 +15,7 @@ pub fn main() !void {
|
||||||
defer _ = gpa.deinit();
|
defer _ = gpa.deinit();
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
const cfg = try config.Config.load(allocator);
|
const cfg = try Config.load(allocator);
|
||||||
defer cfg.deinit(allocator);
|
defer cfg.deinit(allocator);
|
||||||
|
|
||||||
std.log.info("wttr starting on {s}:{d}", .{ cfg.listen_host, cfg.listen_port });
|
std.log.info("wttr starting on {s}:{d}", .{ cfg.listen_host, cfg.listen_port });
|
||||||
|
|
@ -81,7 +81,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
test {
|
test {
|
||||||
std.testing.refAllDecls(@This());
|
std.testing.refAllDecls(@This());
|
||||||
_ = @import("config.zig");
|
_ = @import("Config.zig");
|
||||||
_ = @import("cache/Lru.zig");
|
_ = @import("cache/Lru.zig");
|
||||||
_ = @import("weather/Mock.zig");
|
_ = @import("weather/Mock.zig");
|
||||||
_ = @import("http/RateLimiter.zig");
|
_ = @import("http/RateLimiter.zig");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue