Wrapping kw-based Parameters.jl constructor, for deprecation

I have a config object like this:

using Parameters

@with_kw mutable struct Config
    "Param 1"
    param1::Float64

    # ... several other items ...

    "Whether to iterate randomly."
    use_random::Bool = false
end

And now I need to modify it like so, to enable more than 2 strategies:

@with_kw mutable struct Config
    "Param 1"
    param1::Float64

    # ... several other items ...

    "Strategy for iteration, one of 'random' or 'baseline'."
    iter_strategy::String = "random"
end

But this is a breaking change to its definition, so I want to give some deprecation help to the user.

Is there some way I can intercept existing calls to the keyword-based constructor generated by @with_kw, changing a use_random setting to the appropriate iter_strategy value, and issuing a warning that the caller should change their code? Existing callers would have code like Config(param1=1.1, use_random=true) or similar.

Thanks.

FYI this is very similar to Catching deprecated keyword arguments (with Parameters.jl), which doesn’t currently have an answer.

Not sure if that works for your non-MWE, but this is what I (got the ping from the linked post) ended up using:

@kwdef mutable struct Config
    """Param 1"""
    param1::Float64
    
    """Deprecated, please use `iter_strategy = "random"` instead."""
    use_random::Union{Bool, Nothing} = nothing
    
    """Strategy for iteration, one of `random` or `baseline`."""
    iter_strategy::String = (isnothing(use_random) || use_random) ? "random" : "baseline" 
end

Config(; param1 = 1.0, use_random = true)           # Config(1.0, true, "random")
Config(; param1 = 1.0, use_random = false)          # Config(1.0, false, "baseline")
Config(; param1 = 1.0)                              # Config(1.0, nothing, "random")
Config(; param1 = 1.0, iter_strategy = "baseline")  # Config(1.0, nothing, "baseline")
Config(; param1 = 1.0, iter_strategy = "random")    # Config(1.0, nothing, "random")

If you can live with the type change (and the union) as “non-breaking” for the outside, then this might be a “workaround”.

EDIT: You could of course make the default initialization more complex, e.g., catching and preventing that a user passes both arguments.