File

util/jsonpointer.lua @ 13027:012d6e7b723a

integration tests: Preserve unmocked time.monotonic() With monotonic() frozen, timers may fail to trigger. This caused problems after the new util.startup changes that moved the server-started event to a timer. The timer wouldn't trigger, the event didn't fire, and prosody would fail to daemonize. All the tests that depend on specific time behaviour are depending on wall clock time, so only mocking util.time.now() and os.time() fixes those.
author Matthew Wild <mwild1@gmail.com>
date Thu, 06 Apr 2023 14:00:54 +0100
parent 12781:22066b02887f
line wrap: on
line source

local m_type = math.type;

local function unescape_token(escaped_token)
	local unescaped = escaped_token:gsub("~1", "/"):gsub("~0", "~")
	return unescaped
end

local function resolve_json_pointer(ref, path)
	local ptr_len = #path + 1
	for part, pos in path:gmatch("/([^/]*)()") do
		local token = unescape_token(part)
		if not (type(ref) == "table") then
			return nil
		end
		local idx = next(ref)
		local new_ref

		if type(idx) == "string" then
			new_ref = ref[token]
		elseif m_type(idx) == "integer" then
			local i = tonumber(token)
			if token == "-" then
				i = #ref + 1
			end
			new_ref = ref[i + 1]
		else
			return nil, "invalid-table"
		end

		if pos == ptr_len then
			return new_ref
		elseif type(new_ref) == "table" then
			ref = new_ref
		elseif not (type(ref) == "table") then
			return nil, "invalid-path"
		end

	end
	return ref
end

return { resolve = resolve_json_pointer }