Fixed TryParseW3CColorName

This commit is contained in:
Tig
2024-09-23 13:58:02 -06:00
parent c5cda74549
commit 7fcb5007ec
2 changed files with 44 additions and 31 deletions

View File

@@ -1,6 +1,7 @@
#nullable enable
using System.Collections;
using System.Globalization;
using System.Resources;
using Terminal.Gui.Resources;
namespace Terminal.Gui;
@@ -10,6 +11,8 @@ namespace Terminal.Gui;
/// </summary>
public static class ColorStrings
{
// PERFORMANCE: See https://stackoverflow.com/a/15521524/297526 for why GlobalResources.GetString is fast.
/// <summary>
/// Gets the W3C standard string for <paramref name="color"/>.
/// </summary>
@@ -17,7 +20,6 @@ public static class ColorStrings
/// <returns><see langword="null"/> if there is no standard color name for the specified color.</returns>
public static string? GetW3CColorName (Color color)
{
// Fetch the color name from the resource file
return GlobalResources.GetString ($"#{color.R:X2}{color.G:X2}{color.B:X2}", CultureInfo.CurrentUICulture);
}
@@ -27,18 +29,18 @@ public static class ColorStrings
/// <returns></returns>
public static IEnumerable<string> GetW3CColorNames ()
{
foreach (DictionaryEntry entry in GlobalResources.GetResourceSet (
CultureInfo.CurrentUICulture,
true,
true,
e =>
{
string keyName = e.Key.ToString () ?? string.Empty;
return e.Value is string && keyName.StartsWith ('#');
})!)
ResourceSet? resourceSet = GlobalResources.GetResourceSet (CultureInfo.CurrentUICulture, true, true);
if (resourceSet == null)
{
yield return (entry.Value as string)!;
yield break;
}
foreach (DictionaryEntry entry in resourceSet)
{
if (entry is { Value: string colorName, Key: string key } && key.StartsWith ('#'))
{
yield return colorName;
}
}
}
@@ -50,30 +52,31 @@ public static class ColorStrings
/// <returns><see langword="true"/> if <paramref name="name"/> was parsed successfully.</returns>
public static bool TryParseW3CColorName (string name, out Color color)
{
// Iterate through all resource entries to find the matching color name
foreach (DictionaryEntry entry in GlobalResources.GetResourceSet (CultureInfo.CurrentUICulture, true, true)!)
{
if (entry.Value is string colorName && colorName.Equals (name, StringComparison.OrdinalIgnoreCase))
{
// Parse the key to extract the color components
string key = entry.Key.ToString () ?? string.Empty;
if (key.StartsWith ("#") && key.Length == 7)
{
if (int.TryParse (key.Substring (1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int r)
&& int.TryParse (key.Substring (3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int g)
&& int.TryParse (key.Substring (5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int b))
{
color = new (r, g, b);
return true;
}
}
return TryParseColorKey (entry.Key.ToString (), out color);
}
}
color = default (Color);
return TryParseColorKey (name, out color);
return false;
bool TryParseColorKey (string? key, out Color color)
{
if (key != null && key.StartsWith ('#') && key.Length == 7)
{
if (int.TryParse (key.AsSpan (1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int r) &&
int.TryParse (key.AsSpan (3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int g) &&
int.TryParse (key.AsSpan (5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int b))
{
color = new Color (r, g, b);
return true;
}
}
color = default (Color);
return false;
}
}
}

View File

@@ -9,8 +9,10 @@ namespace Terminal.Gui.ResourcesTests;
public class ResourceManagerTests
{
private const string DODGER_BLUE_COLOR_KEY = "#1E90FF";
private const string DODGER_BLUE_COLOR_KEY = "DodgerBlue";
private const string DODGER_BLUE_COLOR_NAME = "DodgerBlue";
private const string NO_NAMED_COLOR_KEY = "#1E80FF";
private const string NO_NAMED_COLOR_NAME = "#1E80FF";
private const string EXISTENT_CULTURE = "pt-PT";
private const string NO_EXISTENT_CULTURE = "de-DE";
private const string NO_EXISTENT_KEY = "blabla";
@@ -62,7 +64,7 @@ public class ResourceManagerTests
RestoreCurrentCultures ();
}
[Fact (Skip = "Tig broke this test and doesn't understand why.")]
[Fact]
public void GetResourceSet_FallBack_To_Default_For_Not_Translated_Existent_Culture_File ()
{
CultureInfo.CurrentCulture = new (EXISTENT_CULTURE);
@@ -82,6 +84,14 @@ public class ResourceManagerTests
Assert.True (ColorStrings.TryParseW3CColorName (DODGER_BLUE_COLOR_NAME, out Color color));
Assert.Equal (DODGER_BLUE_COLOR_KEY, color.ToString ());
// W3CColors.GetColorNames also calls ColorStrings.GetW3CColorNames for no-named colors
colorNames = new W3CColors ().GetColorNames ().ToArray ();
Assert.DoesNotContain (NO_NAMED_COLOR_NAME, colorNames);
// ColorStrings.TryParseW3CColorName method uses GetResourceSet method to retrieve a color value for no-named colors
Assert.True (ColorStrings.TryParseW3CColorName (NO_NAMED_COLOR_NAME, out color));
Assert.Equal (NO_NAMED_COLOR_KEY, color.ToString ());
RestoreCurrentCultures ();
}