1
1
namespace Octokit . Webhooks . Extensions ;
2
2
3
3
using System ;
4
+ using System . Diagnostics . CodeAnalysis ;
4
5
using System . Globalization ;
5
6
using System . Linq ;
6
7
using System . Runtime . Serialization ;
7
8
using JetBrains . Annotations ;
8
9
9
10
[ PublicAPI ]
10
- public sealed class StringEnum < TEnum > : IEquatable < StringEnum < TEnum > >
11
+ public readonly struct StringEnum < TEnum > : IEquatable < StringEnum < TEnum > >
11
12
where TEnum : struct
12
13
{
13
- private TEnum ? parsedValue ;
14
+ private readonly TEnum ? parsedValue ;
15
+ private readonly bool isValidEnum ;
14
16
15
17
public StringEnum ( string stringValue )
16
18
{
17
19
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
+ }
19
30
}
20
31
21
32
public StringEnum ( TEnum parsedValue )
@@ -27,19 +38,20 @@ public StringEnum(TEnum parsedValue)
27
38
28
39
this . StringValue = ToEnumString ( parsedValue ) ;
29
40
this . parsedValue = parsedValue ;
41
+ this . isValidEnum = true ;
30
42
}
31
43
32
44
public string StringValue { get ; }
33
45
34
- public TEnum Value => this . parsedValue ??= this . ParseValue ( ) ;
46
+ public TEnum Value => this . parsedValue ?? throw GetArgumentException ( this . StringValue ) ;
35
47
36
48
public static implicit operator StringEnum < TEnum > ( string value ) => new ( value ) ;
37
49
38
50
public static implicit operator StringEnum < TEnum > ( TEnum parsedValue ) => new ( parsedValue ) ;
39
51
40
52
public static bool operator == ( StringEnum < TEnum > ? left , StringEnum < TEnum > ? right )
41
53
{
42
- if ( ReferenceEquals ( left , right ) )
54
+ if ( left is null && right is null )
43
55
{
44
56
return true ;
45
57
}
@@ -49,41 +61,27 @@ public StringEnum(TEnum parsedValue)
49
61
return false ;
50
62
}
51
63
52
- return left . Equals ( right ) ;
64
+ return left . Value . Equals ( right . Value ) ;
53
65
}
54
66
55
67
public static bool operator != ( StringEnum < TEnum > ? left , StringEnum < TEnum > ? right ) => ! ( left == right ) ;
56
68
57
- public bool TryParse ( out TEnum value )
69
+ public bool TryParse ( [ NotNullWhen ( true ) ] out TEnum value )
58
70
{
59
- if ( this . parsedValue is not null )
71
+ if ( this . isValidEnum && this . parsedValue is not null )
60
72
{
61
73
value = this . parsedValue . Value ;
62
74
return true ;
63
75
}
64
76
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 ;
76
79
}
77
80
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 ) ;
79
82
80
- public bool Equals ( StringEnum < TEnum > ? other )
83
+ public bool Equals ( StringEnum < TEnum > other )
81
84
{
82
- if ( other is null )
83
- {
84
- return false ;
85
- }
86
-
87
85
var canParseThis = this . TryParse ( out var thisValue ) ;
88
86
var canParseOther = other . TryParse ( out var otherValue ) ;
89
87
@@ -116,6 +114,20 @@ public override int GetHashCode()
116
114
117
115
public override string ToString ( ) => this . StringValue ;
118
116
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
+
119
131
private static ArgumentException GetArgumentException ( string ? value ) => new ( string . Format (
120
132
CultureInfo . InvariantCulture ,
121
133
"Value '{0}' is not a valid '{1}' enum value." ,
@@ -149,14 +161,4 @@ private static TEnum ToEnum(string str)
149
161
150
162
throw new ArgumentException ( str ) ;
151
163
}
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
- }
162
164
}
0 commit comments