From 064ab5bb562eacf4994d50e32fb2be138223fd43 Mon Sep 17 00:00:00 2001 From: YongheeKim Date: Thu, 27 Jun 2024 00:42:53 +0900 Subject: [PATCH] Replaced `get_element` methods with JSONPointer package --- src/schema.jl | 48 ++++-------------------------------------------- test/runtests.jl | 8 ++++---- 2 files changed, 8 insertions(+), 48 deletions(-) diff --git a/src/schema.jl b/src/schema.jl index 5406e65..401ae95 100644 --- a/src/schema.jl +++ b/src/schema.jl @@ -3,18 +3,6 @@ # Use of this source code is governed by an MIT-style license that can be found # in the LICENSE.md file or at https://opensource.org/licenses/MIT. -# Transform escaped characters in JPaths back to their original value. -function unescape_jpath(raw::String) - ret = replace(replace(raw, "~0" => "~"), "~1" => "/") - m = match(r"%([0-9A-F]{2})", ret) - if m !== nothing - for c in m.captures - ret = replace(ret, "%$(c)" => Char(parse(UInt8, "0x$(c)"))) - end - end - return ret -end - function type_to_dict(x) return Dict(name => getfield(x, name) for name in fieldnames(typeof(x))) end @@ -35,36 +23,6 @@ function update_id(uri::URIs.URI, s::String) return URIs.URI(; els...) end -function get_element(schema, path::AbstractString) - for element in split(path, "/"; keepempty = false) - schema = _recurse_get_element(schema, unescape_jpath(String(element))) - end - return schema -end - -function _recurse_get_element(schema::Any, ::String) - return error( - "unmanaged type in ref resolution $(typeof(schema)): $(schema).", - ) -end - -function _recurse_get_element(schema::AbstractDict, element::String) - if !haskey(schema, element) - error("missing property '$(element)' in $(schema).") - end - return schema[element] -end - -function _recurse_get_element(schema::AbstractVector, element::String) - index = tryparse(Int, element) # Remember that `index` is 0-indexed! - if index === nothing - error("expected integer array index instead of '$(element)'.") - elseif index >= length(schema) - error("item index $(index) is larger than array $(schema).") - end - return schema[index+1] -end - function get_remote_schema(uri::URIs.URI) io = IOBuffer() r = Downloads.request(string(uri); output = io, throw = false) @@ -89,7 +47,8 @@ function find_ref( if path == "" || path == "#" # This path refers to the root schema. return id_map[string(uri)] elseif startswith(path, "#/") # This path is a JPointer. - return get_element(id_map[string(uri)], path[3:end]) + p = JSONPointer.Pointer(path; shift_index=true) + return get_pointer(id_map[string(uri)], p) end uri = update_id(uri, path) els = type_to_dict(uri) @@ -114,7 +73,8 @@ function find_ref( ).data end end - return get_element(id_map[string(uri2)], uri.fragment) + p = JSONPointer.Pointer(uri.fragment; shift_index = true) + return get_pointer(id_map[string(uri2)], p) end # Recursively find all "$ref" fields and resolve their path. diff --git a/test/runtests.jl b/test/runtests.jl index 1fa2e67..a0608c3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -265,7 +265,7 @@ end @testset "errors" begin @test_throws( - ErrorException("missing property 'Foo' in $(Dict{String,Any}())."), + KeyError("Foo"), JSONSchema.Schema("""{ "type": "object", "properties": {"version": {"\$ref": "#/definitions/Foo"}}, @@ -274,7 +274,7 @@ end ) @test_throws( - ErrorException("unmanaged type in ref resolution $(Int64): 1."), + ArgumentError("JSON pointer does not match the data-structure. I tried (and failed) to index 1 with the key: Foo"), JSONSchema.Schema("""{ "type": "object", "properties": {"version": {"\$ref": "#/definitions/Foo"}}, @@ -282,7 +282,7 @@ end }""") ) @test_throws( - ErrorException("expected integer array index instead of 'Foo'."), + ArgumentError("JSON pointer does not match the data-structure. I tried (and failed) to index Any[1, 2] with the key: Foo"), JSONSchema.Schema("""{ "type": "object", "properties": {"version": {"\$ref": "#/definitions/Foo"}}, @@ -290,7 +290,7 @@ end }""") ) @test_throws( - ErrorException("item index 3 is larger than array $(Any[1, 2])."), + BoundsError, JSONSchema.Schema("""{ "type": "object", "properties": {"version": {"\$ref": "#/definitions/3"}},