Detecting presence of kwdef defaults

For a while I have struggled with trying to figure out how to properly allow the Unmarshal.jl package to play with kwdef fields, in particular default fields.

The logic typically was given a struct type T that I want to unmarshal, the code iterates over the list of fields, searches for each field in the parsed json object and adds that into the parameter list in order to call a default constructor T with the full parameter list. If the field is not found in the parsed JSON and the field in not of type nullable, missing etc. an error is thrown.

The code is non-stringent in that extra fields present in the parsed JSON are ignored, if not needed by the object specifically. (If for example the JSON is created by non Julia tools with extra fields, not modelled in the Julia object).

That generally works, unless you have something special like not allowing a default constructor, in which case, the user had the option to specialise the unmarshal function call for their special type.

However adding the kwdef as a standard feature makes things more complex. And potentially a number of approaches:

  1. Force user to specialise unmarshal for all kwdef structs. This seems unnecesary, if they still just want default type behaviour.

  2. Now I need some method in order to be able to determine if a field has a default value (kwdef is present by implication). So iterate only over the fields, if not in parsed JSON, check for nullable,missing handling, check if it has a default value and populate the positional parameter with the default.

  3. Alternatively Need some method to check if kwdef is present. If kwdef is present, switch to using a kw constructor (Not sure how to programatically do that to build this? A Named Tuple?), but again the problem of default fields, unless I now switch to using the parsed JSON as the master of supplied fields. My preference would be to not use the parsed JSON input as master, but rather still use do it based on the Julia struct definition.

Is something like this possible with the existing kwdef macro, or would the macro need to be expanded to expose things that can be queried by new functions about the struct?

There’s no easy/reasonable programmatic way to determine if a struct was defined using the @kwdef macro, but I’ve thought as well that it would be nice to have something queryable that could be used to detect this.

I’ve been working on some new code for JSON and just require the user to define JSONBase.kwdef(::Type{MyType}) = true in order to “hook in” to construction via keyword arguments that match fields from the struct.

For the default field value, I don’t think this should be a concern because you only pass field values that were actually present in the JSON since when you call T(; kws...), if you don’t pass a specific field it will use the default it was defined with via the @kwdef macro anyway.

Hope that helps.