diff --git a/src/interface.jl b/src/interface.jl index 17ef0c5..3d48613 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -235,7 +235,7 @@ Does **not** mutate the input; it always allocates new containers. # Examples ```jldoctest -julia> using JSON +julia> using JSON, DataStructures julia> d = Dict( "a" => 4, "b" => 6, @@ -278,67 +278,67 @@ OrderedDict{String,Int} with 3 entries: "b" => 2 ``` """ -function dictify(x; keytype::Type=Any, sort_order::Union{Nothing, Vector}=nothing) - # Dict-like objects - if x isa AbstractDict - out = OrderedDict{keytype, Any}() - - # 1. Process and normalize all keys from the input dictionary - processed_dict = OrderedDict{keytype, Any}() - for (k, v) in x - if keytype === String - newk = string(k) - elseif keytype === Symbol - newk = Symbol(string(k)) - else - newk = k - end - processed_dict[newk] = dictify(v; keytype=keytype, sort_order=sort_order) - end +function dictify(x::T; keytype::Type=Any, sort_order::Union{Nothing, Vector}=nothing + )::OrderedDict where {T<:AbstractDict} + # Dict-like objects + out = OrderedDict{keytype, Any}() + + # 1. Process and normalize all keys from the input dictionary + processed_dict = OrderedDict{keytype, Any}() + for (k, v) in x + if keytype === String + newk = string(k) + elseif keytype === Symbol + newk = Symbol(string(k)) + else + newk = k + end + processed_dict[newk] = dictify(v; keytype=keytype, sort_order=sort_order) + end - # 2. If a sort order is specified, apply it - if !isnothing(sort_order) - # Normalize the sort_order elements to match the requested keytype - normalized_order = map(sort_order) do tk - if keytype === String - return string(tk) - elseif keytype === Symbol - return Symbol(string(tk)) - else - return tk - end - end + # 2. If a sort order is specified, apply it + if !isnothing(sort_order) + # Normalize the sort_order elements to match the requested keytype + normalized_order = map(sort_order) do tk + if keytype === String + return string(tk) + elseif keytype === Symbol + return Symbol(string(tk)) + else + return tk + end + end - # First, insert keys that match the requested order - for target_key in normalized_order - if haskey(processed_dict, target_key) - out[target_key] = processed_dict[target_key] - end - end + # First, insert keys that match the requested order + for target_key in normalized_order + if haskey(processed_dict, target_key) + out[target_key] = processed_dict[target_key] + end + end - # Then, append any remaining keys that weren't in the sort_order - for (k, v) in processed_dict - if !haskey(out, k) - out[k] = v - end - end - else - # If no sort order is given, just use the processed dict - out = processed_dict - end + # Then, append any remaining keys that weren't in the sort_order + for (k, v) in processed_dict + if !haskey(out, k) + out[k] = v + end + end + else + # If no sort order is given, just use the processed dict + out = processed_dict + end - return out - - # Arrays / vectors: map elements recursively - elseif x isa AbstractArray - return [dictify(element; keytype=keytype, sort_order=sort_order) for element in x] - - # Everything else: return as-is - else - return x - end + return out end +function dictify(x::T; keytype::Type=Any, sort_order::Union{Nothing, Vector}=nothing + ) where {T<:AbstractArray} + return [dictify(element; keytype=keytype, sort_order=sort_order) for element in x] +end + +function dictify(x; keytype::Type=Any, sort_order::Union{Nothing, Vector}=nothing + ) + return x +end # ---------------------------------------------- 100 --------------------------------------------- #