1
+ using System ;
1
2
using System . IO ;
2
3
using GitVersion . Model . Configuration ;
4
+ using YamlDotNet . Core ;
5
+ using YamlDotNet . Core . Events ;
3
6
using YamlDotNet . Serialization ;
4
7
using YamlDotNet . Serialization . NamingConventions ;
5
8
@@ -11,6 +14,7 @@ public static Config Read(TextReader reader)
11
14
{
12
15
var deserializer = new DeserializerBuilder ( )
13
16
. WithNamingConvention ( HyphenatedNamingConvention . Instance )
17
+ . WithTypeConverter ( new YamlNullableEnumTypeConverter ( ) )
14
18
. Build ( ) ;
15
19
var deserialize = deserializer . Deserialize < Config > ( reader ) ;
16
20
return deserialize ?? new Config ( ) ;
@@ -21,8 +25,70 @@ public static void Write(Config config, TextWriter writer)
21
25
var serializer = new SerializerBuilder ( )
22
26
. ConfigureDefaultValuesHandling ( DefaultValuesHandling . OmitDefaults )
23
27
. WithNamingConvention ( HyphenatedNamingConvention . Instance )
28
+ . WithTypeConverter ( new YamlNullableEnumTypeConverter ( ) )
24
29
. Build ( ) ;
25
30
serializer . Serialize ( writer , config ) ;
26
31
}
27
32
}
33
+
34
+ public class YamlNullableEnumTypeConverter : IYamlTypeConverter
35
+ {
36
+ public bool Accepts ( Type type )
37
+ {
38
+ return Nullable . GetUnderlyingType ( type ) ? . IsEnum ?? false ;
39
+ }
40
+
41
+ public object ReadYaml ( IParser parser , Type type )
42
+ {
43
+ type = Nullable . GetUnderlyingType ( type ) ?? throw new ArgumentException ( "Expected nullable enum type for ReadYaml" ) ;
44
+
45
+ if ( parser . Accept < NodeEvent > ( out var @event ) )
46
+ {
47
+ if ( NodeIsNull ( @event ) )
48
+ {
49
+ parser . SkipThisAndNestedEvents ( ) ;
50
+ return null ;
51
+ }
52
+ }
53
+
54
+ var scalar = parser . Consume < Scalar > ( ) ;
55
+ try
56
+ {
57
+ return Enum . Parse ( type , scalar . Value , ignoreCase : true ) ;
58
+ }
59
+ catch ( Exception ex )
60
+ {
61
+ throw new Exception ( $ "Invalid value: \" { scalar . Value } \" for { type . Name } ", ex ) ;
62
+ }
63
+ }
64
+
65
+ public void WriteYaml ( IEmitter emitter , object value , Type type )
66
+ {
67
+ type = Nullable . GetUnderlyingType ( type ) ?? throw new ArgumentException ( "Expected nullable enum type for WriteYaml" ) ;
68
+
69
+ if ( value != null )
70
+ {
71
+ var toWrite = Enum . GetName ( type , value ) ?? throw new InvalidOperationException ( $ "Invalid value { value } for enum: { type } ") ;
72
+ emitter . Emit ( new Scalar ( null , null , toWrite , ScalarStyle . Any , true , false ) ) ;
73
+ }
74
+ }
75
+
76
+ private static bool NodeIsNull ( NodeEvent nodeEvent )
77
+ {
78
+ // http://yaml.org/type/null.html
79
+
80
+ if ( nodeEvent . Tag == "tag:yaml.org,2002:null" )
81
+ {
82
+ return true ;
83
+ }
84
+
85
+ if ( nodeEvent is Scalar scalar && scalar . Style == ScalarStyle . Plain )
86
+ {
87
+ var value = scalar . Value ;
88
+ return value is "" or "~" or "null" or "Null" or "NULL" ;
89
+ }
90
+
91
+ return false ;
92
+ }
93
+ }
28
94
}
0 commit comments