From 025cc8ce868357ec7a6a47177584eda3f144a64a Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Sat, 3 Jan 2026 15:49:38 -0800 Subject: [PATCH] remove fahrenheit from data structs --- src/render/ansi.zig | 26 ++------------------------ src/render/custom.zig | 12 ++---------- src/render/json.zig | 3 --- src/render/line.zig | 18 ++++++------------ src/render/v2.zig | 14 ++++---------- src/weather/MetNo.zig | 2 -- src/weather/types.zig | 19 +++++++++++++++++-- 7 files changed, 31 insertions(+), 63 deletions(-) diff --git a/src/render/ansi.zig b/src/render/ansi.zig index 7505adf..7be834a 100644 --- a/src/render/ansi.zig +++ b/src/render/ansi.zig @@ -37,8 +37,8 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, options: Re } fn renderCurrent(w: *std.Io.Writer, current: types.CurrentCondition, options: RenderOptions) !void { - const temp = if (options.use_imperial) current.temp_f else current.temp_c; - const feels_like = if (options.use_imperial) current.feels_like_f else current.feels_like_c; + const temp = if (options.use_imperial) current.tempFahrenheit() else current.temp_c; + const feels_like = if (options.use_imperial) current.feelsLikeFahrenheit() else current.feels_like_c; const temp_unit = if (options.use_imperial) "°F" else "°C"; const wind_unit = if (options.use_imperial) "mph" else "km/h"; const wind_speed = if (options.use_imperial) current.wind_kph * 0.621371 else current.wind_kph; @@ -323,8 +323,6 @@ test "render with imperial units" { .current = .{ .temp_c = 10.0, .feels_like_c = 10.0, - .feels_like_f = 10.0 * 1.8 + 32, - .temp_f = 50.0, .condition = "Clear", .weather_code = .clear, .humidity = 60, @@ -352,8 +350,6 @@ test "clear weather art" { .current = .{ .temp_c = 20.0, .feels_like_c = 20.0, - .feels_like_f = 20.0 * 1.8 + 32, - .temp_f = 68.0, .condition = "Clear", .weather_code = .clear, .humidity = 50, @@ -379,8 +375,6 @@ test "partly cloudy weather art" { .current = .{ .temp_c = 18.0, .feels_like_c = 18.0, - .feels_like_f = 18.0 * 1.8 + 32, - .temp_f = 64.0, .condition = "Partly cloudy", .weather_code = .clouds_few, .humidity = 55, @@ -406,8 +400,6 @@ test "cloudy weather art" { .current = .{ .temp_c = 15.0, .feels_like_c = 15.0, - .feels_like_f = 15.0 * 1.8 + 32, - .temp_f = 59.0, .condition = "Cloudy", .weather_code = .clouds_overcast, .humidity = 70, @@ -433,8 +425,6 @@ test "rain weather art" { .current = .{ .temp_c = 12.0, .feels_like_c = 12.0, - .feels_like_f = 12.0 * 1.8 + 32, - .temp_f = 54.0, .condition = "Rain", .weather_code = .rain_moderate, .humidity = 85, @@ -459,8 +449,6 @@ test "thunderstorm weather art" { .current = .{ .temp_c = 14.0, .feels_like_c = 14.0, - .feels_like_f = 14.0 * 1.8 + 32, - .temp_f = 57.0, .condition = "Thunderstorm", .weather_code = .thunderstorm, .humidity = 90, @@ -485,8 +473,6 @@ test "snow weather art" { .current = .{ .temp_c = -2.0, .feels_like_c = -2.0, - .feels_like_f = -2.0 * 1.8 + 32, - .temp_f = 28.0, .condition = "Snow", .weather_code = .snow, .humidity = 80, @@ -511,8 +497,6 @@ test "sleet weather art" { .current = .{ .temp_c = 0.0, .feels_like_c = 0.0, - .feels_like_f = 0.0 * 1.8 + 32, - .temp_f = 32.0, .condition = "Sleet", .weather_code = .sleet, .humidity = 75, @@ -537,8 +521,6 @@ test "fog weather art" { .current = .{ .temp_c = 8.0, .feels_like_c = 8.0, - .feels_like_f = 8.0 * 1.8 + 32, - .temp_f = 46.0, .condition = "Fog", .weather_code = .fog, .humidity = 95, @@ -563,8 +545,6 @@ test "unknown weather code art" { .current = .{ .temp_c = 16.0, .feels_like_c = 16.0, - .feels_like_f = 16.0 * 1.8 + 32, - .temp_f = 61.0, .condition = "Unknown", .weather_code = .unknown, .humidity = 60, @@ -592,8 +572,6 @@ test "temperature matches between ansi and custom format" { .current = .{ .temp_c = 13.1, .feels_like_c = 13.1, - .feels_like_f = 13.1 * 1.8 + 32, - .temp_f = 55.6, .condition = "Clear", .weather_code = .clear, .humidity = 60, diff --git a/src/render/custom.zig b/src/render/custom.zig index fde5756..e5445d0 100644 --- a/src/render/custom.zig +++ b/src/render/custom.zig @@ -16,7 +16,7 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: 'C' => try writer.print("{s}", .{weather.current.condition}), 'h' => try writer.print("{d}%", .{weather.current.humidity}), 't' => { - const temp = if (use_imperial) weather.current.temp_f else weather.current.temp_c; + const temp = if (use_imperial) weather.current.tempFahrenheit() else weather.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; const sign: u8 = if (temp >= 0) '+' else 0; if (sign != 0) { @@ -26,7 +26,7 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: } }, 'f' => { - const temp = if (use_imperial) weather.current.temp_f else weather.current.temp_c; + const temp = if (use_imperial) weather.current.tempFahrenheit() else weather.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; const sign: u8 = if (temp >= 0) '+' else 0; if (sign != 0) { @@ -83,8 +83,6 @@ test "render custom format with location and temp" { .current = .{ .temp_c = 7.0, .feels_like_c = 7.0, - .feels_like_f = 7.0 * 1.8 + 32, - .temp_f = 44.6, .condition = "Overcast", .weather_code = .clouds_overcast, .humidity = 76, @@ -112,8 +110,6 @@ test "render custom format with newline" { .current = .{ .temp_c = 10.0, .feels_like_c = 10.0, - .feels_like_f = 10.0 * 1.8 + 32, - .temp_f = 50.0, .condition = "Clear", .weather_code = .clear, .humidity = 65, @@ -140,8 +136,6 @@ test "render custom format with humidity and pressure" { .current = .{ .temp_c = 5.0, .feels_like_c = 5.0, - .feels_like_f = 5.0 * 1.8 + 32, - .temp_f = 41.0, .condition = "Cloudy", .weather_code = .clouds_overcast, .humidity = 85, @@ -169,8 +163,6 @@ test "render custom format with imperial units" { .current = .{ .temp_c = 10.0, .feels_like_c = 10.0, - .feels_like_f = 10.0 * 1.8 + 32, - .temp_f = 50.0, .condition = "Clear", .weather_code = .clear, .humidity = 60, diff --git a/src/render/json.zig b/src/render/json.zig index 7e10d1f..4c6b5c4 100644 --- a/src/render/json.zig +++ b/src/render/json.zig @@ -5,7 +5,6 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData) ![]const const data = .{ .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, @@ -28,8 +27,6 @@ test "render json format" { .current = .{ .temp_c = 15.0, .feels_like_c = 15.0, - .feels_like_f = 15.0 * 1.8 + 32, - .temp_f = 59.0, .condition = "Partly cloudy", .weather_code = .clouds_few, .humidity = 72, diff --git a/src/render/line.zig b/src/render/line.zig index 97caf3e..ec1b50f 100644 --- a/src/render/line.zig +++ b/src/render/line.zig @@ -4,7 +4,7 @@ const emoji = @import("emoji.zig"); pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 { if (std.mem.eql(u8, format, "1")) { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s}", .{ data.location, @@ -13,7 +13,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c unit, }); } else if (std.mem.eql(u8, format, "2")) { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; const wind = if (use_imperial) data.current.wind_kph * 0.621371 else data.current.wind_kph; const wind_unit = if (use_imperial) "mph" else "km/h"; @@ -28,7 +28,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c wind_unit, }); } else if (std.mem.eql(u8, format, "3")) { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; const wind = if (use_imperial) data.current.wind_kph * 0.621371 else data.current.wind_kph; const wind_unit = if (use_imperial) "mph" else "km/h"; @@ -45,7 +45,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c data.current.humidity, }); } else if (std.mem.eql(u8, format, "4")) { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; const unit = if (use_imperial) "°F" else "°C"; const wind = if (use_imperial) data.current.wind_kph * 0.621371 else data.current.wind_kph; const wind_unit = if (use_imperial) "mph" else "km/h"; @@ -80,11 +80,11 @@ fn renderCustom(allocator: std.mem.Allocator, data: types.WeatherData, format: [ 'C' => try output.appendSlice(allocator, data.current.condition), 'h' => try output.writer(allocator).print("{d}", .{data.current.humidity}), 't' => { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; try output.writer(allocator).print("{d:.0}", .{temp}); }, 'f' => { - const temp = if (use_imperial) data.current.temp_f else data.current.temp_c; + const temp = if (use_imperial) data.current.tempFahrenheit() else data.current.temp_c; try output.writer(allocator).print("{d:.0}", .{temp}); }, 'w' => { @@ -123,8 +123,6 @@ test "format 1" { .current = .{ .temp_c = 15.0, .feels_like_c = 15.0, - .feels_like_f = 15.0 * 1.8 + 32, - .temp_f = 59.0, .condition = "Clear", .weather_code = .clear, .humidity = 65, @@ -149,8 +147,6 @@ test "custom format" { .current = .{ .temp_c = 15.0, .feels_like_c = 15.0, - .feels_like_f = 15.0 * 1.8 + 32, - .temp_f = 59.0, .condition = "Clear", .weather_code = .clear, .humidity = 65, @@ -175,8 +171,6 @@ test "format 2 with imperial units" { .current = .{ .temp_c = 10.0, .feels_like_c = 10.0, - .feels_like_f = 10.0 * 1.8 + 32, - .temp_f = 50.0, .condition = "Cloudy", .weather_code = .clouds_overcast, .humidity = 70, diff --git a/src/render/v2.zig b/src/render/v2.zig index f0fd948..3594ac2 100644 --- a/src/render/v2.zig +++ b/src/render/v2.zig @@ -14,9 +14,9 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, use_impe try writer.print(" {s}\n", .{weather.current.condition}); try writer.writeAll(" 🌡️ "); if (use_imperial) { - try writer.print("{d:.1}°F\n", .{weather.current.temp_f}); + try writer.print("{d:.1}°F\n", .{weather.current.tempFahrenheit()}); } else { - try writer.print("{d:.1}°C ({d:.1}°F)\n", .{ weather.current.temp_c, weather.current.temp_f }); + try writer.print("{d:.1}°C ({d:.1}°F)\n", .{ weather.current.temp_c, weather.current.tempFahrenheit() }); } try writer.writeAll(" 💧 "); try writer.print("{d}%\n", .{weather.current.humidity}); @@ -49,15 +49,13 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, use_impe try writer.print(" {s}: {s}\n", .{ day.date, day.condition }); try writer.writeAll(" ↑ "); if (use_imperial) { - const max_f = day.max_temp_c * 9.0 / 5.0 + 32.0; - try writer.print("{d:.1}°F ", .{max_f}); + try writer.print("{d:.1}°F ", .{day.maxTempFahrenheit()}); } else { try writer.print("{d:.1}°C ", .{day.max_temp_c}); } try writer.writeAll("↓ "); if (use_imperial) { - const min_f = day.min_temp_c * 9.0 / 5.0 + 32.0; - try writer.print("{d:.1}°F\n", .{min_f}); + try writer.print("{d:.1}°F\n", .{day.minTempFahrenheit()}); } else { try writer.print("{d:.1}°C\n", .{day.min_temp_c}); } @@ -75,8 +73,6 @@ test "render v2 format" { .current = .{ .temp_c = 12.0, .feels_like_c = 12.0, - .feels_like_f = 12.0 * 1.8 + 32, - .temp_f = 53.6, .condition = "Overcast", .weather_code = .clouds_overcast, .humidity = 80, @@ -106,8 +102,6 @@ test "render v2 format with imperial units" { .current = .{ .temp_c = 10.0, .feels_like_c = 10.0, - .feels_like_f = 10.0 * 1.8 + 32, - .temp_f = 50.0, .condition = "Clear", .weather_code = .clear, .humidity = 65, diff --git a/src/weather/MetNo.zig b/src/weather/MetNo.zig index e6ff05a..611b665 100644 --- a/src/weather/MetNo.zig +++ b/src/weather/MetNo.zig @@ -187,9 +187,7 @@ fn parseMetNoResponse(allocator: std.mem.Allocator, coords: Coordinates, json: s .location = try std.fmt.allocPrint(allocator, "{d:.4},{d:.4}", .{ coords.latitude, coords.longitude }), .current = .{ .temp_c = temp_c, - .temp_f = temp_c * 9.0 / 5.0 + 32.0, .feels_like_c = feels_like_c, - .feels_like_f = feels_like_c * 9.0 / 5.0 + 32.0, .condition = try allocator.dupe(u8, symbolCodeToCondition(symbol_code)), .weather_code = symbolCodeToWeatherCode(symbol_code), .humidity = humidity, diff --git a/src/weather/types.zig b/src/weather/types.zig index 60ac855..9efb915 100644 --- a/src/weather/types.zig +++ b/src/weather/types.zig @@ -104,11 +104,12 @@ pub const WeatherData = struct { } }; +fn celsiusToFahrenheit(c: f32) f32 { + return c * 9.0 / 5.0 + 32.0; +} pub const CurrentCondition = struct { temp_c: f32, - temp_f: f32, feels_like_c: f32, - feels_like_f: f32, condition: []const u8, weather_code: WeatherCode, humidity: u8, @@ -116,6 +117,13 @@ pub const CurrentCondition = struct { wind_dir: []const u8, pressure_mb: f32, precip_mm: f32, + + pub fn tempFahrenheit(self: CurrentCondition) f32 { + return celsiusToFahrenheit(self.temp_c); + } + pub fn feelsLikeFahrenheit(self: CurrentCondition) f32 { + return celsiusToFahrenheit(self.feels_like_c); + } }; pub const ForecastDay = struct { @@ -125,6 +133,13 @@ pub const ForecastDay = struct { condition: []const u8, weather_code: WeatherCode, hourly: []HourlyForecast, + + pub fn maxTempFahrenheit(self: ForecastDay) f32 { + return celsiusToFahrenheit(self.max_temp_c); + } + pub fn minTempFahrenheit(self: ForecastDay) f32 { + return celsiusToFahrenheit(self.min_temp_c); + } }; pub const HourlyForecast = struct {