Skip to content

Commit a94296e

Browse files
committed
Migrate StringEnum<TEnum> to a readonly struct
1 parent 593146a commit a94296e

File tree

1 file changed

+38
-36
lines changed

1 file changed

+38
-36
lines changed

src/Octokit.Webhooks/Extensions/StringEnum.cs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
namespace Octokit.Webhooks.Extensions;
22

33
using System;
4+
using System.Diagnostics.CodeAnalysis;
45
using System.Globalization;
56
using System.Linq;
67
using System.Runtime.Serialization;
78
using JetBrains.Annotations;
89

910
[PublicAPI]
10-
public sealed class StringEnum<TEnum> : IEquatable<StringEnum<TEnum>>
11+
public readonly struct StringEnum<TEnum> : IEquatable<StringEnum<TEnum>>
1112
where TEnum : struct
1213
{
13-
private TEnum? parsedValue;
14+
private readonly TEnum? parsedValue;
15+
private readonly bool isValidEnum;
1416

1517
public StringEnum(string stringValue)
1618
{
1719
this.StringValue = stringValue;
18-
this.parsedValue = null;
20+
if (TryParseEnum(stringValue, out var enumValue))
21+
{
22+
this.parsedValue = enumValue;
23+
this.isValidEnum = true;
24+
}
25+
else
26+
{
27+
this.parsedValue = null;
28+
this.isValidEnum = false;
29+
}
1930
}
2031

2132
public StringEnum(TEnum parsedValue)
@@ -27,19 +38,20 @@ public StringEnum(TEnum parsedValue)
2738

2839
this.StringValue = ToEnumString(parsedValue);
2940
this.parsedValue = parsedValue;
41+
this.isValidEnum = true;
3042
}
3143

3244
public string StringValue { get; }
3345

34-
public TEnum Value => this.parsedValue ??= this.ParseValue();
46+
public TEnum Value => this.parsedValue ?? throw GetArgumentException(this.StringValue);
3547

3648
public static implicit operator StringEnum<TEnum>(string value) => new(value);
3749

3850
public static implicit operator StringEnum<TEnum>(TEnum parsedValue) => new(parsedValue);
3951

4052
public static bool operator ==(StringEnum<TEnum>? left, StringEnum<TEnum>? right)
4153
{
42-
if (ReferenceEquals(left, right))
54+
if (left is null && right is null)
4355
{
4456
return true;
4557
}
@@ -49,41 +61,27 @@ public StringEnum(TEnum parsedValue)
4961
return false;
5062
}
5163

52-
return left.Equals(right);
64+
return left.Value.Equals(right.Value);
5365
}
5466

5567
public static bool operator !=(StringEnum<TEnum>? left, StringEnum<TEnum>? right) => !(left == right);
5668

57-
public bool TryParse(out TEnum value)
69+
public bool TryParse([NotNullWhen(true)] out TEnum value)
5870
{
59-
if (this.parsedValue is not null)
71+
if (this.isValidEnum && this.parsedValue is not null)
6072
{
6173
value = this.parsedValue.Value;
6274
return true;
6375
}
6476

65-
try
66-
{
67-
value = ToEnum(this.StringValue);
68-
this.parsedValue = value;
69-
return true;
70-
}
71-
catch (ArgumentException)
72-
{
73-
value = default;
74-
return false;
75-
}
77+
value = default;
78+
return false;
7679
}
7780

78-
public override bool Equals(object? obj) => this.Equals(obj as StringEnum<TEnum>);
81+
public override bool Equals(object? obj) => obj is StringEnum<TEnum> other && this.Equals(other);
7982

80-
public bool Equals(StringEnum<TEnum>? other)
83+
public bool Equals(StringEnum<TEnum> other)
8184
{
82-
if (other is null)
83-
{
84-
return false;
85-
}
86-
8785
var canParseThis = this.TryParse(out var thisValue);
8886
var canParseOther = other.TryParse(out var otherValue);
8987

@@ -116,6 +114,20 @@ public override int GetHashCode()
116114

117115
public override string ToString() => this.StringValue;
118116

117+
private static bool TryParseEnum(string str, out TEnum value)
118+
{
119+
try
120+
{
121+
value = ToEnum(str);
122+
return true;
123+
}
124+
catch (ArgumentException)
125+
{
126+
value = default;
127+
return false;
128+
}
129+
}
130+
119131
private static ArgumentException GetArgumentException(string? value) => new(string.Format(
120132
CultureInfo.InvariantCulture,
121133
"Value '{0}' is not a valid '{1}' enum value.",
@@ -149,14 +161,4 @@ private static TEnum ToEnum(string str)
149161

150162
throw new ArgumentException(str);
151163
}
152-
153-
private TEnum ParseValue()
154-
{
155-
if (this.TryParse(out var value))
156-
{
157-
return value;
158-
}
159-
160-
throw GetArgumentException(this.StringValue);
161-
}
162164
}

0 commit comments

Comments
 (0)