Harbor

branch main
showing the latest snapshot on main
json.lua 1.4 KB · Lua
gpu/tools/lua/json.lua 0644 Raw
local json = {}

local escapes = {
	['"'] = '\\"',
	['\\'] = '\\\\',
	['\b'] = '\\b',
	['\f'] = '\\f',
	['\n'] = '\\n',
	['\r'] = '\\r',
	['\t'] = '\\t',
}

local function is_array(t)
	local max = 0
	local count = 0
	for k, _ in pairs(t) do
		if type(k) ~= "number" or k < 1 or k % 1 ~= 0 then
			return false
		end
		if k > max then max = k end
		count = count + 1
	end
	return max == count
end

local function encode_string(s)
	return '"' .. tostring(s):gsub('[%z\1-\31\\"]', function(c)
		return escapes[c] or string.format("\\u%04x", c:byte())
	end) .. '"'
end

local function encode_value(v)
	local tv = type(v)
	if tv == "nil" then
		return "null"
	elseif tv == "boolean" then
		return v and "true" or "false"
	elseif tv == "number" then
		return tostring(v)
	elseif tv == "string" then
		return encode_string(v)
	elseif tv == "table" then
		local out = {}
		if is_array(v) then
			for i = 1, #v do
				out[#out + 1] = encode_value(v[i])
			end
			return "[" .. table.concat(out, ",") .. "]"
		end
		local keys = {}
		for k, _ in pairs(v) do keys[#keys + 1] = k end
		table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
		for _, k in ipairs(keys) do
			out[#out + 1] = encode_string(k) .. ":" .. encode_value(v[k])
		end
		return "{" .. table.concat(out, ",") .. "}"
	end
	error("cannot JSON encode " .. tv)
end

function json.encode(v)
	return encode_value(v)
end

return json