1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Text . Json ;
4
+ using System . Text . Json . Serialization ;
5
+ using OpenFeature . Model ;
6
+
7
+ namespace OpenFeature . Contrib . Providers . Flipt . Converters ;
8
+
9
+ /// <summary>
10
+ /// OpenFeature Value type converter
11
+ /// </summary>
12
+ public class OpenFeatureValueConverter : JsonConverter < Value >
13
+ {
14
+ /// <inheritdoc />
15
+ public override Value Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
16
+ {
17
+ var value = new Value ( ) ;
18
+ switch ( reader . TokenType )
19
+ {
20
+ case JsonTokenType . String :
21
+ return reader . TryGetDateTime ( out var dateTimeValue )
22
+ ? new Value ( dateTimeValue )
23
+ : new Value ( reader . GetString ( ) ?? string . Empty ) ;
24
+ case JsonTokenType . True :
25
+ case JsonTokenType . False :
26
+ return new Value ( reader . GetBoolean ( ) ) ;
27
+ case JsonTokenType . Number :
28
+ if ( reader . TryGetInt32 ( out var intValue ) ) return new Value ( intValue ) ;
29
+ if ( reader . TryGetDouble ( out var dblValue ) ) return new Value ( dblValue ) ;
30
+ break ;
31
+ case JsonTokenType . StartArray :
32
+ return new Value ( GenerateValueArray ( ref reader , typeToConvert , options ) ) ;
33
+ case JsonTokenType . StartObject :
34
+ return new Value ( GetStructure ( ref reader , typeToConvert , options ) ) ;
35
+ }
36
+
37
+ return value ;
38
+ }
39
+
40
+ private Structure GetStructure ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
41
+ {
42
+ var startDepth = reader . CurrentDepth ;
43
+ var structureDictionary = new Dictionary < string , Value > ( ) ;
44
+ while ( reader . Read ( ) )
45
+ {
46
+ if ( reader . TokenType == JsonTokenType . PropertyName )
47
+ {
48
+ var key = reader . GetString ( ) ;
49
+ reader . Read ( ) ;
50
+ var val = Read ( ref reader , typeToConvert , options ) ;
51
+ structureDictionary [ key ?? string . Empty ] = val ;
52
+ }
53
+
54
+ if ( reader . TokenType == JsonTokenType . EndObject && reader . CurrentDepth == startDepth ) break ;
55
+ }
56
+
57
+ return new Structure ( structureDictionary ) ;
58
+ }
59
+
60
+
61
+ private IList < Value > GenerateValueArray ( ref Utf8JsonReader reader , Type typeToConvert ,
62
+ JsonSerializerOptions options )
63
+ {
64
+ var valuesArray = new List < Value > ( ) ;
65
+ var startDepth = reader . CurrentDepth ;
66
+
67
+ while ( reader . Read ( ) )
68
+ switch ( reader . TokenType )
69
+ {
70
+ case JsonTokenType . EndArray when reader . CurrentDepth == startDepth :
71
+ return valuesArray ;
72
+ default :
73
+ valuesArray . Add ( Read ( ref reader , typeToConvert , options ) ) ;
74
+ break ;
75
+ }
76
+
77
+ return valuesArray ;
78
+ }
79
+
80
+ /// <inheritdoc />
81
+ public override void Write ( Utf8JsonWriter writer , Value value , JsonSerializerOptions options )
82
+ {
83
+ if ( value . IsList )
84
+ {
85
+ writer . WriteStartArray ( ) ;
86
+ foreach ( var val in value . AsList ! )
87
+ {
88
+ var jsonDoc = JsonDocument . Parse ( JsonSerializer . Serialize ( val . AsObject ,
89
+ JsonConverterExtensions . DefaultSerializerSettings ) ) ;
90
+ jsonDoc . WriteTo ( writer ) ;
91
+ }
92
+
93
+ writer . WriteEndArray ( ) ;
94
+ }
95
+ else
96
+ {
97
+ var jsonDoc = JsonDocument . Parse ( JsonSerializer . Serialize ( value . AsObject ,
98
+ JsonConverterExtensions . DefaultSerializerSettings ) ) ;
99
+ jsonDoc . WriteTo ( writer ) ;
100
+ }
101
+ }
102
+ }
0 commit comments