Skip to content

Commit

Permalink
[#180] Allow overriding generic types
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarmil committed Mar 30, 2024
1 parent 1b6dbd9 commit befd95a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/FSharp.SystemTextJson/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,19 @@ let overrideOptions (ty: Type) (defaultOptions: JsonFSharpOptions) =
if isNull overrides then
applyAttributeOverride ()
else
match overrides.TryGetValue(ty) with
| true, options -> options |> inheritUnionEncoding
| false, _ -> applyAttributeOverride ()
let overrideOpt =
let mutable options = Unchecked.defaultof<_>
if
overrides.TryGetValue(ty, &options)
|| (ty.IsGenericType
&& overrides.TryGetValue(ty.GetGenericTypeDefinition(), &options))
then
ValueSome options
else
ValueNone
match overrideOpt with
| ValueSome options -> options |> inheritUnionEncoding
| ValueNone -> applyAttributeOverride ()

let isWrappedString (ty: Type) =
TypeCache.isUnion ty
Expand Down
33 changes: 33 additions & 0 deletions tests/FSharp.SystemTextJson.Tests/Test.Union.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,39 @@ module NonStruct =
.ToJsonSerializerOptions()
Assert.Equal("""{"tag2":"A","x":123,"y":"abc"}""", JsonSerializer.Serialize(Override.A(123, "abc"), o))

[<Fact>]
let ``should apply explicit overrides on generic type`` () =
let o =
JsonFSharpOptions
.Default()
.WithUnionInternalTag()
.WithUnionNamedFields()
.WithOverrides(fun o -> dict [ typedefof<Result<_, _>>, o.WithUnionTagName("Result") ])
.ToJsonSerializerOptions()
Assert.Equal("""{"Result":"Ok","ResultValue":"abc"}""", JsonSerializer.Serialize(Ok "abc", o))

[<Fact>]
let ``should apply explicit override on specific type over generic type`` () =
let o =
JsonFSharpOptions
.Default()
.WithUnionInternalTag()
.WithUnionNamedFields()
.WithOverrides(fun o ->
dict
[ typeof<Result<string, string>>, o.WithUnionTagName("SpecificResult")
typedefof<Result<_, _>>, o.WithUnionTagName("GenericResult") ]
)
.ToJsonSerializerOptions()
Assert.Equal(
"""{"GenericResult":"Ok","ResultValue":42}""",
JsonSerializer.Serialize((Ok 42: Result<int, string>), o)
)
Assert.Equal(
"""{"SpecificResult":"Ok","ResultValue":"abc"}""",
JsonSerializer.Serialize((Ok "abc": Result<string, string>), o)
)

type NamedAfterTypesA = NTA of int

type NamedAfterTypesB = NTB of int * string
Expand Down

0 comments on commit befd95a

Please sign in to comment.