Tarmil / FSharp.SystemTextJson

System.Text.Json extensions for F# types
MIT License
323 stars 44 forks source link

Allow overriding property and union case attributes in options #181

Open Tarmil opened 4 months ago

Tarmil commented 4 months ago

Allow specifying which attributes should apply to a given property or union case in the options. This is useful to override the format of a type that is not under the developer's control, or simply to keep DTOs lean.

Example:

type MyRecord = { x: int }

let options =
    JsonFSharpOptions()
        .WithOverrides(fun o -> dict [
            typeof<MyRecord>, o.WithOverrideProperty("x", [JsonNameAttribute "y"])
        ])
        .ToJsonSerializerOptions()

JsonSerializer.Serialize({ x = 1 }, o)
// --> {"y":1}

Example combined with #180 to fully control the format of the standard library's Result<'ok, 'error>:

let options =
    JsonFSharpOptions()
        .WithOverrides(fun o -> dict [
            typedefof<Result<_, _>>, o
                .WithUnionInternalTag()
                .WithUnionNamedFields()
                .WithUnionTagName("isSuccess")
                .WithOverrideCase("Ok", [
                    JsonNameAttribute true
                    JsonNameAttribute("value", Field = "ResultValue")
                ])
                .WithOverrideCase("Error", [
                    JsonNameAttribute false
                    JsonNameAttribute("error", Field = "ErrorValue")
                ])
        ])

JsonSerializer.Serialize(Ok 42, options)
// --> {"isSuccess":true,"value":42}

JsonSerializer.Serialize(Error "Internal error", options)
// --> {"isSuccess":false,"error":"Internal error"}