From fc15d56e4516b345ac5d25375415500690eefe52 Mon Sep 17 00:00:00 2001 From: Dave Crissman Date: Mon, 2 Dec 2024 21:36:22 -0500 Subject: [PATCH] fix: refactor ColorConverter to support HSV values --- .../test/src/ColorConverterTest.cs | 6 +-- .../src/ColorConverter.cs | 43 ++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Chickensoft.Serialization.Godot.Tests/test/src/ColorConverterTest.cs b/Chickensoft.Serialization.Godot.Tests/test/src/ColorConverterTest.cs index 164a39b..18ad77e 100644 --- a/Chickensoft.Serialization.Godot.Tests/test/src/ColorConverterTest.cs +++ b/Chickensoft.Serialization.Godot.Tests/test/src/ColorConverterTest.cs @@ -23,17 +23,17 @@ public void Converts() { TypeInfoResolver = new SerializableTypeResolver(), }; - var obj = new Color(0xff0000ff); + var obj = new Color(1f, 0.5f, 0f, 1f); var json = JsonSerializer.Serialize(obj, options); json.ShouldBe( /*lang=json*/ """ { - "rgba": "FF0000FF" + "rgba": "rgba(1, 0.5, 0, 1)" } """ - ); + , StringCompareShould.IgnoreLineEndings); var deserialized = JsonSerializer.Deserialize(json, options); diff --git a/Chickensoft.Serialization.Godot/src/ColorConverter.cs b/Chickensoft.Serialization.Godot/src/ColorConverter.cs index 44352f3..72a887f 100644 --- a/Chickensoft.Serialization.Godot/src/ColorConverter.cs +++ b/Chickensoft.Serialization.Godot/src/ColorConverter.cs @@ -1,13 +1,22 @@ namespace Chickensoft.Serialization.Godot; using System; -using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; +using System.Text.RegularExpressions; using global::Godot; /// Color JSON converter. -public class ColorConverter : JsonConverter { +public partial class ColorConverter : JsonConverter { + [GeneratedRegex("\\s*rgba\\((.*)\\)\\s*", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex RgbaRegex(); + + [GeneratedRegex("\\s+", RegexOptions.IgnoreCase, "en-US")] + private static partial Regex WhitespaceRegex(); + + private static readonly Regex _rgbaRegex = RgbaRegex(); + private static readonly Regex _whitespaceRegex = WhitespaceRegex(); + /// public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Color); @@ -18,11 +27,14 @@ public override Color Read( Type typeToConvert, JsonSerializerOptions options ) { - var rgba = (uint)0x000000ff; + var r = 0f; + var g = 0f; + var b = 0f; + var a = 1f; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { - return new Color(rgba); + return new Color(r, g, b, a); } if (reader.TokenType != JsonTokenType.PropertyName) { @@ -34,7 +46,26 @@ JsonSerializerOptions options switch (propertyName) { case "rgba": - rgba = uint.Parse(reader.GetString() ?? string.Empty, NumberStyles.HexNumber); + var match = _rgbaRegex.Match(reader.GetString() ?? string.Empty); + if (match.Groups[1].Success) { + var values = _whitespaceRegex + .Replace(match.Groups[1].Value, "") + .Split(","); + + if (values.Length == 4) { + r = float.Parse(values[0]); + g = float.Parse(values[1]); + b = float.Parse(values[2]); + a = float.Parse(values[3]); + } + else { + throw new JsonException("Unable to parse property 'rgba' of Color"); + } + } + else { + throw new JsonException("Unable to parse property 'rgba' of Color"); + } + break; default: break; @@ -51,7 +82,7 @@ public override void Write( JsonSerializerOptions options ) { writer.WriteStartObject(); - writer.WriteString("rgba", value.ToRgba32().ToString("X")); + writer.WriteString("rgba", $"rgba({value.R}, {value.G}, {value.B}, {value.A})"); writer.WriteEndObject(); } }