Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/object.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Base.isempty(obj::Object) = _k(obj) === notset && _ch(obj) === notset
Base.empty(::Object{K,V}) where {K,V} = Object{K,V}() # empty object

# linear node lookup
@inline function find_node_by_key(obj::Object{K,V}, key::K) where {K,V}
@inline function find_node_by_key(obj::Object{K,V}, key) where {K,V}
while true
_k(obj) !== notset && isequal(_k(obj)::K, key) && return obj
_ch(obj) === notset && break
Expand All @@ -142,9 +142,11 @@ Base.get(f::Base.Callable, obj::Object{Symbol}, key::String) = get(f, obj, Symbo
Base.getindex(obj::Object, key) = get(() -> throw(KeyError(key)), obj, key)
Base.getindex(obj::Object{String}, key::Symbol) = get(() -> throw(KeyError(key)), obj, String(key))
Base.getindex(obj::Object{Symbol}, key::String) = get(() -> throw(KeyError(key)), obj, Symbol(key))
Base.setindex!(obj::Object{String}, value, key::Symbol) = setindex!(obj, value, String(key))
Base.setindex!(obj::Object{String,V}, value, key::AbstractString) where {V} = _setindex!(obj, value, String(key))
Base.setindex!(obj::Object{String,V}, value, key::Symbol) where {V} = _setindex!(obj, value, String(key))
Base.setindex!(obj::Object{Symbol}, value, key::String) = setindex!(obj, value, Symbol(key))
Base.delete!(obj::Object{String}, key::Symbol) = delete!(obj, String(key))
Base.delete!(obj::Object{String,V}, key::AbstractString) where {V} = _delete!(obj, String(key))
Base.delete!(obj::Object{String,V}, key::Symbol) where {V} = _delete!(obj, String(key))
Base.delete!(obj::Object{Symbol}, key::String) = delete!(obj, Symbol(key))
Base.get(obj::Object, key, default) = get(() -> default, obj, key)
Base.get(obj::Object{String}, key::Symbol, default) = get(obj, String(key), default)
Expand All @@ -166,7 +168,7 @@ Base.haskey(obj::Object{String}, key::Symbol) = haskey(obj, String(key))
Base.haskey(obj::Object{Symbol}, key::String) = haskey(obj, Symbol(key))

# setindex! finds node with key and sets value or inserts a new node
function Base.setindex!(obj::Object{K,V}, value, key::K) where {K,V}
function _setindex!(obj::Object{K,V}, value, key::K) where {K,V}
root = obj
while true
if _k(obj) !== notset && isequal(_k(obj)::K, key)
Expand All @@ -180,9 +182,10 @@ function Base.setindex!(obj::Object{K,V}, value, key::K) where {K,V}
Object{K,V}(obj, key, value)
return value
end
Base.setindex!(obj::Object{K,V}, value, key::K) where {K,V} = _setindex!(obj, value, key)

# delete! removes node
function Base.delete!(obj::Object{K,V}, key::K) where {K,V}
function _delete!(obj::Object{K,V}, key::K) where {K,V}
# check empty case
_ch(obj) === notset && return obj
root = parent = obj
Expand All @@ -204,6 +207,7 @@ function Base.delete!(obj::Object{K,V}, key::K) where {K,V}
end
return root
end
Base.delete!(obj::Object{K,V}, key::K) where {K,V} = _delete!(obj, key)

function Base.empty!(obj::Object)
setfield!(obj, :child, notset)
Expand All @@ -214,4 +218,4 @@ end
Base.setproperty!(obj::Object, sym::Symbol, val) = setindex!(obj, val, sym)
Base.setproperty!(obj::Object{String}, sym::Symbol, val) = setindex!(obj, val, String(sym))

Base.merge(a::NamedTuple, b::Object{String,Any}) = merge(a, (Symbol(k) => v for (k, v) in b))
Base.merge(a::NamedTuple, b::Object{String,Any}) = merge(a, (Symbol(k) => v for (k, v) in b))
21 changes: 20 additions & 1 deletion test/object.jl
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,25 @@ using JSON, Test
@test !haskey(empty_obj, "anything")
end

@testset "AbstractString key support for parsed String objects" begin
obj = JSON.parse("{\"foo\": \"bar\"}")
s = "abc.foo.xyz"
k = split(s, ".")[2]

@test k isa SubString{String}
@test haskey(obj, k)
@test get(obj, k, nothing) == "bar"
@test obj[k] == "bar"

obj[k] = "baz"
@test obj["foo"] == "baz"

delete!(obj, k)
@test !haskey(obj, "foo")
@test get(obj, k, "default") == "default"
@test_throws KeyError obj[k]
end

# Test enhanced haskey for Symbol objects with String keys
@testset "Enhanced haskey for Symbol Objects" begin
obj = JSON.Object{Symbol, Any}()
Expand Down Expand Up @@ -404,4 +423,4 @@ using JSON, Test
@test merged_mixed.float == 3.14
@test merged_mixed.bool == true
end
end
end
Loading