49 lines
1.6 KiB
Zig
49 lines
1.6 KiB
Zig
//! Shared JSON parsing helpers used by all API providers.
|
|
//! Centralises the common patterns: extracting floats, strings,
|
|
//! unsigned ints, and mapping HTTP errors.
|
|
|
|
const std = @import("std");
|
|
|
|
/// Extract a required float from a JSON value (string, float, or integer).
|
|
/// Returns 0 for null, missing, or unparseable values.
|
|
pub fn parseJsonFloat(val: ?std.json.Value) f64 {
|
|
const v = val orelse return 0;
|
|
return switch (v) {
|
|
.float => |f| f,
|
|
.integer => |i| @floatFromInt(i),
|
|
.string => |s| std.fmt.parseFloat(f64, s) catch 0,
|
|
else => 0,
|
|
};
|
|
}
|
|
|
|
/// Extract an optional float. Returns null for missing/null JSON values.
|
|
pub fn optFloat(val: ?std.json.Value) ?f64 {
|
|
const v = val orelse return null;
|
|
return switch (v) {
|
|
.float => |f| f,
|
|
.integer => |i| @floatFromInt(i),
|
|
.null => null,
|
|
else => null,
|
|
};
|
|
}
|
|
|
|
/// Extract an optional unsigned integer. Returns null for missing/null/negative values.
|
|
/// Float values are accepted only if they are whole numbers (e.g. 1234.0).
|
|
pub fn optUint(val: ?std.json.Value) ?u64 {
|
|
const v = val orelse return null;
|
|
return switch (v) {
|
|
.integer => |i| if (i >= 0) @intCast(i) else null,
|
|
.float => |f| if (f >= 0 and f == @floor(f)) @intFromFloat(f) else null,
|
|
.null => null,
|
|
else => null,
|
|
};
|
|
}
|
|
|
|
/// Extract an optional string. Returns null for missing or non-string values.
|
|
pub fn jsonStr(val: ?std.json.Value) ?[]const u8 {
|
|
const v = val orelse return null;
|
|
return switch (v) {
|
|
.string => |s| s,
|
|
else => null,
|
|
};
|
|
}
|