centralize emoji logic

This commit is contained in:
Emil Lerch 2025-12-19 09:07:35 -08:00
parent ac6ddf829d
commit 4c95017e02
Signed by: lobo
GPG key ID: A7B62D657EF764F8
3 changed files with 24 additions and 33 deletions

View file

@ -1,17 +1,6 @@
const std = @import("std"); const std = @import("std");
const types = @import("../weather/types.zig"); const types = @import("../weather/types.zig");
const emoji = @import("emoji.zig");
const weather_icons = [_][]const u8{
"", // 0-99
"🌑", // 100-199
"", // 200-299
"☁️", // 300-399
};
fn getWeatherIcon(code: types.WeatherCode) []const u8 {
const idx = @min(@intFromEnum(code) / 100, weather_icons.len - 1);
return weather_icons[idx];
}
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 { pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 {
var output: std.ArrayList(u8) = .empty; var output: std.ArrayList(u8) = .empty;
@ -23,7 +12,7 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format:
if (format[i] == '%' and i + 1 < format.len) { if (format[i] == '%' and i + 1 < format.len) {
const code = format[i + 1]; const code = format[i + 1];
switch (code) { switch (code) {
'c' => try writer.print("{s}", .{getWeatherIcon(weather.current.weather_code)}), 'c' => try writer.print("{s}", .{emoji.getWeatherEmoji(weather.current.weather_code)}),
'C' => try writer.print("{s}", .{weather.current.condition}), 'C' => try writer.print("{s}", .{weather.current.condition}),
'h' => try writer.print("{d}%", .{weather.current.humidity}), 'h' => try writer.print("{d}%", .{weather.current.humidity}),
't' => { 't' => {

16
src/render/emoji.zig Normal file
View file

@ -0,0 +1,16 @@
const types = @import("../weather/types.zig");
pub fn getWeatherEmoji(code: types.WeatherCode) []const u8 {
return switch (@intFromEnum(code)) {
800 => "☀️", // Clear
801, 802 => "⛅️", // Few/scattered clouds
803, 804 => "☁️", // Broken/overcast clouds
701, 741 => "🌫", // Mist/fog
300...321 => "🌦", // Drizzle
500...531 => "🌧", // Rain
200...232 => "", // Thunderstorm
611...616 => "🌧", // Sleet
600...610, 617...622 => "🌨", // Snow
else => "", // Unknown
};
}

View file

@ -1,5 +1,6 @@
const std = @import("std"); const std = @import("std");
const types = @import("../weather/types.zig"); const types = @import("../weather/types.zig");
const emoji = @import("emoji.zig");
pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 { 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")) { if (std.mem.eql(u8, format, "1")) {
@ -7,7 +8,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
const unit = if (use_imperial) "°F" else "°C"; const unit = if (use_imperial) "°F" else "°C";
return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s}", .{ return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s}", .{
data.location, data.location,
getConditionEmoji(data.current.weather_code), emoji.getWeatherEmoji(data.current.weather_code),
temp, temp,
unit, unit,
}); });
@ -18,7 +19,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
const wind_unit = if (use_imperial) "mph" else "km/h"; const wind_unit = if (use_imperial) "mph" else "km/h";
return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s}", .{ return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s}", .{
data.location, data.location,
getConditionEmoji(data.current.weather_code), emoji.getWeatherEmoji(data.current.weather_code),
temp, temp,
unit, unit,
"🌬️", "🌬️",
@ -33,7 +34,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
const wind_unit = if (use_imperial) "mph" else "km/h"; const wind_unit = if (use_imperial) "mph" else "km/h";
return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s} {s}{d}%%", .{ return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s} {s}{d}%%", .{
data.location, data.location,
getConditionEmoji(data.current.weather_code), emoji.getWeatherEmoji(data.current.weather_code),
temp, temp,
unit, unit,
"🌬️", "🌬️",
@ -50,7 +51,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
const wind_unit = if (use_imperial) "mph" else "km/h"; const wind_unit = if (use_imperial) "mph" else "km/h";
return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s} {s}{d}%% {s}", .{ return std.fmt.allocPrint(allocator, "{s}: {s} {d:.0}{s} {s}{s}{d:.0}{s} {s}{d}%% {s}", .{
data.location, data.location,
getConditionEmoji(data.current.weather_code), emoji.getWeatherEmoji(data.current.weather_code),
temp, temp,
unit, unit,
"🌬️", "🌬️",
@ -75,7 +76,7 @@ fn renderCustom(allocator: std.mem.Allocator, data: types.WeatherData, format: [
if (format[i] == '%' and i + 1 < format.len) { if (format[i] == '%' and i + 1 < format.len) {
const code = format[i + 1]; const code = format[i + 1];
switch (code) { switch (code) {
'c' => try output.appendSlice(allocator, getConditionEmoji(data.current.weather_code)), 'c' => try output.appendSlice(allocator, emoji.getWeatherEmoji(data.current.weather_code)),
'C' => try output.appendSlice(allocator, data.current.condition), 'C' => try output.appendSlice(allocator, data.current.condition),
'h' => try output.writer(allocator).print("{d}", .{data.current.humidity}), 'h' => try output.writer(allocator).print("{d}", .{data.current.humidity}),
't' => { 't' => {
@ -116,21 +117,6 @@ fn renderCustom(allocator: std.mem.Allocator, data: types.WeatherData, format: [
return output.toOwnedSlice(allocator); return output.toOwnedSlice(allocator);
} }
fn getConditionEmoji(code: types.WeatherCode) []const u8 {
return switch (@intFromEnum(code)) {
800 => "☀️", // Clear
801, 802 => "⛅️", // Few/scattered clouds
803, 804 => "☁️", // Broken/overcast clouds
701, 741 => "🌁", // Mist/fog (alternatively, maybe 🌫 or 🌫 is better)
300...321 => "🌦", // Drizzle
500...531 => "🌧️", // Rain
200...232 => "⛈️", // Thunderstorm
611...616 => "❄️", // Sleet/freezing (check before snow)
600...610, 617...622 => "🌨️", // Snow
else => "🌡️",
};
}
test "format 1" { test "format 1" {
const data = types.WeatherData{ const data = types.WeatherData{
.location = "London", .location = "London",