Skip to content

Commit 574ead6

Browse files
jsheelyFrankRay78nils-a
authored
Added hex color conversion (#1432)
* Added hex color conversion --------- Co-authored-by: Frank Ray <[email protected]> Co-authored-by: Nils Andresen <[email protected]>
1 parent a87277e commit 574ead6

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

src/Spectre.Console/Color.cs

+44
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,50 @@ public static Color FromInt32(int number)
213213
return ColorTable.GetColor(number);
214214
}
215215

216+
/// <summary>
217+
/// Creates a color from a hexadecimal string representation.
218+
/// </summary>
219+
/// <param name="hex">The hexadecimal string representation of the color.</param>
220+
/// <returns>The color created from the hexadecimal string.</returns>
221+
public static Color FromHex(string hex)
222+
{
223+
if (hex is null)
224+
{
225+
throw new ArgumentNullException(nameof(hex));
226+
}
227+
228+
if (hex.StartsWith("#"))
229+
{
230+
hex = hex.Substring(1);
231+
}
232+
233+
var r = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
234+
var g = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
235+
var b = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
236+
237+
return new Color(r, g, b);
238+
}
239+
240+
/// <summary>
241+
/// Tries to convert a hexadecimal color code to a <see cref="Color"/> object.
242+
/// </summary>
243+
/// <param name="hex">The hexadecimal color code.</param>
244+
/// <param name="color">When this method returns, contains the <see cref="Color"/> equivalent of the hexadecimal color code, if the conversion succeeded, or <see cref="Color.Default"/> if the conversion failed.</param>
245+
/// <returns><c>true</c> if the conversion succeeded; otherwise, <c>false</c>.</returns>
246+
public static bool TryFromHex(string hex, out Color color)
247+
{
248+
try
249+
{
250+
color = FromHex(hex);
251+
return true;
252+
}
253+
catch
254+
{
255+
color = Color.Default;
256+
return false;
257+
}
258+
}
259+
216260
/// <summary>
217261
/// Converts a <see cref="ConsoleColor"/> to a <see cref="Color"/>.
218262
/// </summary>

src/Tests/Spectre.Console.Tests/Unit/ColorTests.cs

+64
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,73 @@
1+
using System.Drawing;
2+
13
namespace Spectre.Console.Tests.Unit;
24

35
public sealed class ColorTests
46
{
57
public sealed class TheEqualsMethod
68
{
9+
[Theory]
10+
[InlineData("800080")]
11+
[InlineData("#800080")]
12+
public void Should_Consider_Color_And_Color_From_Hex_Equal(string color)
13+
{
14+
// Given
15+
var color1 = new Color(128, 0, 128);
16+
17+
// When
18+
var color2 = Color.FromHex(color);
19+
20+
// Then
21+
color2.ShouldBe(color1);
22+
}
23+
24+
[Theory]
25+
[InlineData("800080")]
26+
[InlineData("#800080")]
27+
public void Should_Consider_Color_And_Color_Try_From_Hex_Equal(string color)
28+
{
29+
// Given
30+
var color1 = new Color(128, 0, 128);
31+
32+
// When
33+
var result = Color.TryFromHex(color, out var color2);
34+
35+
// Then
36+
result.ShouldBeTrue();
37+
color2.ShouldBe(color1);
38+
}
39+
40+
[Theory]
41+
[InlineData(null)]
42+
[InlineData("")]
43+
[InlineData("#")]
44+
[InlineData("#80")]
45+
[InlineData("FOO")]
46+
public void Should_Not_Parse_Non_Color_From_Hex(string noncolor)
47+
{
48+
// Given, When
49+
var result = Record.Exception(() => Color.FromHex(noncolor));
50+
51+
// Then
52+
result.ShouldBeAssignableTo<Exception>();
53+
}
54+
55+
[Theory]
56+
[InlineData(null)]
57+
[InlineData("")]
58+
[InlineData("#")]
59+
[InlineData("#80")]
60+
[InlineData("FOO")]
61+
public void Should_Not_Parse_Non_Color_Try_From_Hex(string noncolor)
62+
{
63+
// Given, When
64+
var result = Color.TryFromHex(noncolor, out var color);
65+
66+
// Then
67+
result.ShouldBeFalse();
68+
color.ShouldBe(Color.Default);
69+
}
70+
771
[Fact]
872
public void Should_Consider_Color_And_Non_Color_Equal()
973
{

0 commit comments

Comments
 (0)