diff --git a/src/Serialization/main.jl b/src/Serialization/main.jl index ef93399845b6..fa737a46d2c6 100644 --- a/src/Serialization/main.jl +++ b/src/Serialization/main.jl @@ -224,7 +224,7 @@ function save_type_params(s::SerializerState, T::Type, params::S) where S <: Uni end # Named Tuples need to preserve order so they are handled seperate from Dict -function save_type_params(s::SerializerState, T::Type{<:NamedTuple}, params::Vector{<:Pair}) +function save_type_params(s::SerializerState, T::Type{<:NamedTuple}, params::Vector{<:Pair{Symbol, S}}) where S save_data_dict(s) do save_object(s, encode_type(T), :name) save_data_dict(s, :params) do @@ -242,9 +242,7 @@ function save_type_params(s::SerializerState, T::Type{<:NamedTuple}, params::Vec end end -const BasicKeyTypes = Union{String, Symbol, Int} - -function save_type_params(s::SerializerState, T::Type{<:Dict{S, U}}, params::Vector{<:Pair{S, V}}) where {U, V, S <: BasicKeyTypes} +function save_type_params(s::SerializerState, T::Type{<:Dict{S, U}}, params::Vector{<:Pair{S, V}}) where {U, V, S <: Union{Int, String}} save_data_dict(s) do save_object(s, encode_type(T), :name) save_data_dict(s, :params) do @@ -257,6 +255,20 @@ function save_type_params(s::SerializerState, T::Type{<:Dict{S, U}}, params::Vec end end +# this function is exactly the same as above, it is here to distinguish from the function below +function save_type_params(s::SerializerState, T::Type{<:Dict{Symbol, U}}, params::Vector{<:Pair{Symbol, V}}) where {U, V} + save_data_dict(s) do + save_object(s, encode_type(T), :name) + save_data_dict(s, :params) do + save_object(s, encode_type(Symbol), :key_type) + isempty(params) && save_object(s, encode_type(U), :value_type) + for param in params + save_type_params(s, param.second..., Symbol(param.first)) + end + end + end +end + function save_type_params(s::SerializerState, T::Type, params::Vector{<:Pair{Symbol, S}}) where S save_data_dict(s) do @@ -269,6 +281,7 @@ function save_type_params(s::SerializerState, T::Type, end end +# i'll need this at some point in the refator #function save_type_params(s::SerializerState, T::Type{<:Dict{S, U}}, params::Vector{<:Pair}) where {S, U} # save_data_dict(s) do # save_object(s, encode_type(T), :name) @@ -299,58 +312,73 @@ function load_type_params(s::DeserializerState) end return T, nothing end + + !haskey(s, :params) && return T, load_typed_object(s) - if haskey(s, :params) - subtype, params = load_node(s, :params) do obj - if typeof(obj) <: Union{JSON3.Array, Vector} - tuple_params = load_array_node(s) do _ - load_type_params(s) - end - return collect(zip(tuple_params...)) - elseif haskey(s, :tuple_params) - tuple_params = load_array_node(s, :tuple_params) do _ - load_type_params(s) - end - tuple_types, named_tuple_params = collect(zip(tuple_params...)) - names = load_object(s, Vector{Symbol}, :names) - return (tuple(names...), Tuple{tuple_types...}), named_tuple_params - elseif haskey(s, :key_type) - S = load_node(s, :key_type) do _ - decode_type(s) - end - params_dict = Dict{S, Any}() - if S <: Union{String, Symbol, Int} - value_types = Type[] - for (k, _) in s.obj - k == :key_type && continue - if k == :value_type - load_node(s, k) do _ - push!(value_types, decode_type(s)) - end - continue - end - key = S == Int ? parse(Int, string(k)) : S(k) - params_dict[key] = load_type_params(s, k) - push!(value_types, params_dict[key][1]) + return load_type_params(s, T) +end + +function load_type_params(s::DeserializerState, T::Type{<: Union{MatVecType, Set}}) + subtype, params = load_type_params(s, :params) + return T{subtype}, params +end + +function load_type_params(s::DeserializerState, T::Type{Tuple}) + subtype, params = load_node(s, :params) do _ + tuple_params = load_array_node(s) do _ + load_type_params(s) + end + return collect(zip(tuple_params...)) + end + return T{subtype...}, params +end + +function load_type_params(s::DeserializerState, T::Type{NamedTuple}) + subtype, params = load_node(s, :params) do obj + tuple_params = load_array_node(s, :tuple_params) do _ + load_type_params(s) + end + tuple_types, named_tuple_params = collect(zip(tuple_params...)) + names = load_object(s, Vector{Symbol}, :names) + return (tuple(names...), Tuple{tuple_types...}), named_tuple_params + end + return T{subtype...}, params +end + +function load_type_params(s::DeserializerState, T::Type{Dict}) + subtype, params = load_node(s, :params) do obj + S = load_node(s, :key_type) do _ + decode_type(s) + end + params_dict = Dict{S, Any}() + if S <: Union{String, Symbol, Int} + value_types = Type[] + for (k, _) in obj + k == :key_type && continue + if k == :value_type + load_node(s, k) do _ + push!(value_types, decode_type(s)) end - return (S, Union{value_types...}), params_dict + continue end - else - load_type_params(s) + key = S == Int ? parse(Int, string(k)) : S(k) + params_dict[key] = load_type_params(s, k) + push!(value_types, params_dict[key][1]) end - end - if T <: Union{MatVecType, Set} - return T{subtype}, params - elseif T <: Union{Tuple, NamedTuple} - return T{subtype...}, params - elseif T <: Dict - return Dict{subtype...}, params + return (S, Union{value_types...}), params_dict else - return T, params + error{"not implented yet"} end - else - return T, load_typed_object(s) end + + return Dict{subtype...}, params +end + +function load_type_params(s::DeserializerState, T::Type) + subtype, params = load_node(s, :params) do obj + load_type_params(s) + end + return T, params end function load_typed_object(s::DeserializerState, key::Symbol; override_params::Any = nothing)