Skip to content

Support getting JsonFSharpOptions and a list of overrides from JsonFSharpConverter #112

@AlexeyRaga

Description

@AlexeyRaga

This is useful for being able to "extend" an existing JsonFSharpConverter in a way that is "just like the existing one, but altered".

It can be used from within other JsonConverters, when they decide that parts of the format should be altered.

Use case:

I have a type

type Envelope<'a> =
    { id : int
      headers : Map<string, string>
      data : 'a }

in which 'a can be an F# type, often a union type.
I am writing a JsonConverter (the factory) to be able to format the value according to some standard, like:

{
    "id": 1,
    "headers":
    {
        "fizz": "buzz",
        "foo": "bar"
    },
    "messageType": "Events.Order.Cancelled",
    "data":
    {
        "id": 123,
        "reason": "just"
    }
}

Note that in this case messageType sits outside of the data, so data has to be formatted as JsonUnionEncoding.ExternalTag ||| JsonUnionEncoding.NamedFields, regardless of how the formatter is configured otherwise.
So I want to override this for the 'a within that envelope.

The logical case here seems to be to add an override for the type within the factory.
But I wanted to preserve other overrides that might be configured, since that 'a can internally contain any of these.

I tried to add an override for typedefof<Envelope<_>> at the top level, but it obviously didn't work since It means providing options for the Envelope itself and not for the 'a inside it.

If JsonFSharpConverter provided the way of extracting options and overrides then it would be possible to do something like (pseudocode):

override this.CreateConverter(typeToConvert, options) =
    let fsConverter = options.Converters |> findFsharpConverter // returns existing one or default
    let newConverter = JsonFSharpOptions(fsConverter.options, fsConverter.overrides |> updatedOverridesForMyType)
   
    let safeOptions = JsonSerializerOptions(options)
    safeOptions.Converters |> replaceFsharpConverter newConverter

    // now use safeOptions instead of options

Ideally it'd be great to be able to declare an override for generic parameters, like "for the parameter within this generic use this override", but I don't even know how to express that :)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions