@@ -177,8 +177,8 @@ module private Case =
177177 else
178178 i <- i + 1
179179
180- let casesByName ( fsOptions : JsonFSharpOptionsRecord ) ( cases : Case []) =
181- if fsOptions.UnionTagCaseInsensitive then
180+ let casesByName caseInsensitive ( cases : Case []) =
181+ if caseInsensitive then
182182 let dict = Dictionary( JsonNameComparer( StringComparer.OrdinalIgnoreCase))
183183 for c in cases do
184184 for name in c.Names do
@@ -221,7 +221,8 @@ module private Case =
221221 match reader.TryGetInt32() with
222222 | true , intName -> JsonName.Int intName
223223 | false , _ -> failExpecting " union tag" & reader ty
224- | JsonTokenType.String -> JsonName.String( reader.GetString())
224+ | JsonTokenType.String
225+ | JsonTokenType.PropertyName -> JsonName.String( reader.GetString())
225226 | _ -> failExpecting " union tag" & reader ty
226227
227228 let isNamedFromReaderString ( case : Case ) ( reader : byref < Utf8JsonReader >) ( found : byref < ValueOption < _ >>) =
@@ -297,6 +298,12 @@ module private Case =
297298 | JsonName.Int name -> writer.WriteNumber( fsOptions.UnionTagName, name)
298299 | JsonName.Bool name -> writer.WriteBoolean( fsOptions.UnionTagName, name)
299300
301+ let writeCaseNameAsValue ( writer : Utf8JsonWriter ) ( case : Case ) =
302+ match case.Names[ 0 ] with
303+ | JsonName.String name -> writer.WriteStringValue( name)
304+ | JsonName.Int name -> writer.WriteNumberValue( name)
305+ | JsonName.Bool name -> writer.WriteBooleanValue( name)
306+
300307
301308type JsonUnionConverter < 'T >
302309 internal ( options: JsonSerializerOptions, fsOptions: JsonFSharpOptionsRecord, cases: UnionCaseInfo[]) =
@@ -361,7 +368,7 @@ type JsonUnionConverter<'T>
361368 else
362369 ValueNone
363370
364- let casesByName = Case.casesByName fsOptions cases
371+ let casesByName = Case.casesByName fsOptions.UnionTagCaseInsensitive cases
365372
366373 let getCaseByPropertyName ( reader : byref < Utf8JsonReader >) =
367374 match Case.tryGetCaseByPropertyName casesByName cases & reader with
@@ -614,12 +621,6 @@ type JsonUnionConverter<'T>
614621 else
615622 writeFieldsAsArray writer case value options
616623
617- let writeCaseNameAsValue ( writer : Utf8JsonWriter ) ( case : Case ) =
618- match case.Names[ 0 ] with
619- | JsonName.String name -> writer.WriteStringValue( name)
620- | JsonName.Int name -> writer.WriteNumberValue( name)
621- | JsonName.Bool name -> writer.WriteBooleanValue( name)
622-
623624 let writeAdjacentTag ( writer : Utf8JsonWriter ) ( case : Case ) ( value : obj ) ( options : JsonSerializerOptions ) =
624625 writer.WriteStartObject()
625626 Case.writeCaseNameAsField fsOptions writer case
@@ -641,7 +642,7 @@ type JsonUnionConverter<'T>
641642 writeFieldsAsRestOfObject writer case value options
642643 else
643644 writer.WriteStartArray()
644- writeCaseNameAsValue writer case
645+ Case. writeCaseNameAsValue writer case
645646 writeFieldsAsRestOfArray writer case value options
646647
647648 let writeUntagged ( writer : Utf8JsonWriter ) ( case : Case ) ( value : obj ) ( options : JsonSerializerOptions ) =
@@ -680,7 +681,7 @@ type JsonUnionConverter<'T>
680681 let tag = tagReader value
681682 let case = cases[ tag]
682683 if unwrapFieldlessTags && case.Fields.Length = 0 then
683- writeCaseNameAsValue writer case
684+ Case. writeCaseNameAsValue writer case
684685 else
685686 match baseFormat with
686687 | JsonUnionEncoding.AdjacentTag -> writeAdjacentTag writer case value options
@@ -758,15 +759,23 @@ type JsonEnumLikeUnionConverter<'T> internal (options: JsonSerializerOptions, fs
758759
759760 let tagReader = FSharpValue.PreComputeUnionTagReader( typeof< 'T>, true )
760761
761- let cases =
762+ let casesAsProperty =
762763 let namingPolicy =
763764 match fsOptions.UnionTagNamingPolicy with
764765 | null -> options.PropertyNamingPolicy
765766 | p -> p
766767 FSharpType.GetUnionCases( typeof< 'T>, true )
767768 |> Array.map ( Case.get namingPolicy fsOptions options)
768769
769- let casesByName = Case.casesByName fsOptions cases
770+ let casesAsValue =
771+ FSharpType.GetUnionCases( typeof< 'T>, true )
772+ |> Array.map ( Case.get fsOptions.UnionTagNamingPolicy fsOptions options)
773+
774+ let casesByNameAsProperty =
775+ Case.casesByName ( fsOptions.UnionTagCaseInsensitive || options.PropertyNameCaseInsensitive) casesAsProperty
776+
777+ let casesByNameAsValue =
778+ Case.casesByName fsOptions.UnionTagCaseInsensitive casesAsValue
770779
771780 let nullValue =
772781 tryGetNullValue fsOptions typeof< 'T> |> ValueOption.map ( fun x -> x :?> 'T)
@@ -783,20 +792,33 @@ type JsonEnumLikeUnionConverter<'T> internal (options: JsonSerializerOptions, fs
783792 | JsonTokenType.Number
784793 | JsonTokenType.True
785794 | JsonTokenType.False ->
786- let case = Case.getCaseByTagReader casesByName cases typeof< 'T> & reader
795+ let case =
796+ Case.getCaseByTagReader casesByNameAsValue casesAsValue typeof< 'T> & reader
787797 case.Ctor [||] :?> 'T
788798 | _ -> failExpecting " string" & reader typeToConvert
789799
790- override this.ReadAsPropertyName ( reader , typeToConvert , options ) =
791- this.Read(& reader, typeToConvert, options)
800+ override this.ReadAsPropertyName ( reader , typeToConvert , _options ) =
801+ match reader.TokenType with
802+ | JsonTokenType.Null ->
803+ nullValue
804+ |> ValueOption.defaultWith ( fun () -> failf " Union %s can't be deserialized from null" typeof< 'T>. FullName)
805+ | JsonTokenType.PropertyName
806+ | JsonTokenType.String
807+ | JsonTokenType.Number
808+ | JsonTokenType.True
809+ | JsonTokenType.False ->
810+ let case =
811+ Case.getCaseByTagReader casesByNameAsProperty casesAsProperty typeof< 'T> & reader
812+ case.Ctor [||] :?> 'T
813+ | _ -> failExpecting " string" & reader typeToConvert
792814
793815 override this.Write ( writer , value , _options ) =
794816 let tag = tagReader value
795- Case.writeCaseNameAsField fsOptions writer cases [ tag]
817+ Case.writeCaseNameAsValue writer casesAsValue [ tag]
796818
797819 override this.WriteAsPropertyName ( writer , value , _options ) =
798820 let tag = tagReader value
799- writer.WritePropertyName( cases [ tag]. NamesAsString[ 0 ])
821+ writer.WritePropertyName( casesAsProperty [ tag]. NamesAsString[ 0 ])
800822
801823type JsonUnionConverter ( fsOptions : JsonFSharpOptions ) =
802824 inherit JsonConverterFactory()
0 commit comments