diff --git a/src/config/Config.zig b/src/config/Config.zig index a2f71c0c0..4a06e22ac 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -3797,17 +3797,22 @@ pub const Color = struct { pub fn fromHex(input: []const u8) !Color { // Trim the beginning '#' if it exists const trimmed = if (input.len != 0 and input[0] == '#') input[1..] else input; + if (trimmed.len != 6 and trimmed.len != 3) return error.InvalidValue; - // We expect exactly 6 for RRGGBB - if (trimmed.len != 6) return error.InvalidValue; + // Expand short hex values to full hex values + const rgb: []const u8 = if (trimmed.len == 3) &.{ + trimmed[0], trimmed[0], + trimmed[1], trimmed[1], + trimmed[2], trimmed[2], + } else trimmed; // Parse the colors two at a time. var result: Color = undefined; comptime var i: usize = 0; inline while (i < 6) : (i += 2) { const v: u8 = - ((try std.fmt.charToDigit(trimmed[i], 16)) * 16) + - try std.fmt.charToDigit(trimmed[i + 1], 16); + ((try std.fmt.charToDigit(rgb[i], 16)) * 16) + + try std.fmt.charToDigit(rgb[i + 1], 16); @field(result, switch (i) { 0 => "r", @@ -3827,6 +3832,8 @@ pub const Color = struct { try testing.expectEqual(Color{ .r = 10, .g = 11, .b = 12 }, try Color.fromHex("#0A0B0C")); try testing.expectEqual(Color{ .r = 10, .g = 11, .b = 12 }, try Color.fromHex("0A0B0C")); try testing.expectEqual(Color{ .r = 255, .g = 255, .b = 255 }, try Color.fromHex("FFFFFF")); + try testing.expectEqual(Color{ .r = 255, .g = 255, .b = 255 }, try Color.fromHex("FFF")); + try testing.expectEqual(Color{ .r = 51, .g = 68, .b = 85 }, try Color.fromHex("#345")); } test "parseCLI from name" {