wttr/zig/src/render/json.zig

73 lines
2.4 KiB
Zig

const std = @import("std");
const types = @import("../weather/types.zig");
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData) ![]const u8 {
var output = std.ArrayList(u8).init(allocator);
errdefer output.deinit();
try std.json.stringify(.{
.current_condition = .{
.temp_C = weather.current.temp_c,
.temp_F = weather.current.temp_f,
.weatherCode = weather.current.weather_code,
.weatherDesc = .{.{ .value = weather.current.condition }},
.humidity = weather.current.humidity,
.windspeedKmph = weather.current.wind_kph,
.winddirDegree = weather.current.wind_dir,
.pressure = weather.current.pressure_mb,
.precipMM = weather.current.precip_mm,
},
.weather = blk: {
var forecast_array = std.ArrayList(struct {
date: []const u8,
maxtempC: f32,
mintempC: f32,
weatherCode: u16,
weatherDesc: []const u8,
}).init(allocator);
defer forecast_array.deinit();
for (weather.forecast) |day| {
try forecast_array.append(.{
.date = day.date,
.maxtempC = day.max_temp_c,
.mintempC = day.min_temp_c,
.weatherCode = day.weather_code,
.weatherDesc = day.condition,
});
}
break :blk try forecast_array.toOwnedSlice();
},
}, .{}, output.writer());
return output.toOwnedSlice();
}
test "render json format" {
const allocator = std.testing.allocator;
const weather = types.WeatherData{
.location = "London",
.current = .{
.temp_c = 15.0,
.temp_f = 59.0,
.condition = "Partly cloudy",
.weather_code = 116,
.humidity = 72,
.wind_kph = 13.0,
.wind_dir = "SW",
.pressure_mb = 1013.0,
.precip_mm = 0.0,
},
.forecast = &[_]types.ForecastDay{},
.allocator = allocator,
};
const output = try render(allocator, weather);
defer allocator.free(output);
try std.testing.expect(output.len > 0);
try std.testing.expect(std.mem.indexOf(u8, output, "temp_C") != null);
try std.testing.expect(std.mem.indexOf(u8, output, "15") != null);
}