Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: refactor ColorConverter to support HSV values #32

Merged
merged 1 commit into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<Color>(json, options);

Expand Down
43 changes: 37 additions & 6 deletions Chickensoft.Serialization.Godot/src/ColorConverter.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>Color JSON converter.</summary>
public class ColorConverter : JsonConverter<Color> {
public partial class ColorConverter : JsonConverter<Color> {
[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();

/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) =>
typeToConvert == typeof(Color);
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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();
}
}
Loading