summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-11-14 23:28:02 +0800
committerruki <[email protected]>2025-11-14 23:28:02 +0800
commit31cab9106eeb43897e641ae80d5557d3b24c35f3 (patch)
tree1fd2797edf71be1086074b18c5958072751138ef
parent1da60acf10492426338a6802b537589361e8c6b6 (diff)
add pretty support for json module
-rwxr-xr-xtests/modules/json/test.lua20
-rw-r--r--xmake/core/base/json.lua65
2 files changed, 73 insertions, 12 deletions
diff --git a/tests/modules/json/test.lua b/tests/modules/json/test.lua
index a09f0918a..b2e53481b 100755
--- a/tests/modules/json/test.lua
+++ b/tests/modules/json/test.lua
@@ -38,6 +38,16 @@ function test_json_encode(t)
t:are_equal(json_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
t:are_equal(json_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
t:are_equal(json_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
+ local pretty_expected = table.concat({
+ "{",
+ " \"name\": \"xmake\",",
+ " \"targets\": [",
+ " \"foo\",",
+ " \"bar\"",
+ " ]",
+ "}"
+ }, "\n")
+ t:are_equal(json_encode({name = "xmake", targets = {"foo", "bar"}}, {pretty = true, indent = 4}), pretty_expected)
end
function test_pure_json_decode(t)
@@ -59,4 +69,14 @@ function test_pure_json_encode(t)
t:are_equal(json_pure_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
t:are_equal(json_pure_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
t:are_equal(json_pure_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
+ local pretty_expected = table.concat({
+ "{",
+ " \"name\": \"xmake\",",
+ " \"targets\": [",
+ " \"foo\",",
+ " \"bar\"",
+ " ]",
+ "}"
+ }, "\n")
+ t:are_equal(json.encode({name = "xmake", targets = {"foo", "bar"}}, {pure = true, pretty = true, indent = 4}), pretty_expected)
end
diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua
index c93d298a9..2ed363461 100644
--- a/xmake/core/base/json.lua
+++ b/xmake/core/base/json.lua
@@ -130,7 +130,14 @@ function json._pure_parse_num_val(str, pos)
return val, pos + #num_str
end
-function json._pure_stringify(obj, as_key)
+function json._pure_stringify(obj, level, as_key, opt)
+ opt = opt or {}
+ level = level or 0
+ local pretty = opt.pretty
+ local indent_step = pretty and (opt.indent or 4) or nil
+ local newline = pretty and "\n" or ""
+ local curr_indent = indent_step and string.rep(" ", indent_step * level) or nil
+ local child_indent = indent_step and string.rep(" ", indent_step * (level + 1)) or nil
local s = {}
local kind = json._pure_kind_of(obj)
if kind == "array" then
@@ -138,9 +145,25 @@ function json._pure_stringify(obj, as_key)
os.raise("can\'t encode array as key.")
end
s[#s + 1] = '['
- for i, val in ipairs(obj) do
- if i > 1 then s[#s + 1] = ',' end
- s[#s + 1] = json._pure_stringify(val)
+ local arrlen = #obj
+ if pretty and arrlen > 0 then
+ s[#s + 1] = newline
+ end
+ for idx = 1, arrlen do
+ if idx > 1 then
+ s[#s + 1] = ','
+ if pretty then
+ s[#s + 1] = newline
+ end
+ end
+ if pretty then
+ s[#s + 1] = child_indent
+ end
+ s[#s + 1] = json._pure_stringify(obj[idx], level + 1, false, opt)
+ end
+ if pretty and arrlen > 0 then
+ s[#s + 1] = newline
+ s[#s + 1] = curr_indent
end
s[#s + 1] = ']'
elseif kind == "table" then
@@ -148,11 +171,26 @@ function json._pure_stringify(obj, as_key)
os.raise("can\'t encode table as key.")
end
s[#s + 1] = '{'
+ local first = true
for k, v in pairs(obj) do
- if #s > 1 then s[#s + 1] = ',' end
- s[#s + 1] = json._pure_stringify(k, true)
+ if not first then
+ s[#s + 1] = ','
+ end
+ if pretty then
+ s[#s + 1] = newline
+ s[#s + 1] = child_indent
+ end
+ s[#s + 1] = json._pure_stringify(k, level + 1, true, opt)
s[#s + 1] = ':'
- s[#s + 1] = json._pure_stringify(v)
+ if pretty then
+ s[#s + 1] = ' '
+ end
+ s[#s + 1] = json._pure_stringify(v, level + 1, false, opt)
+ first = false
+ end
+ if pretty and not first then
+ s[#s + 1] = newline
+ s[#s + 1] = curr_indent
end
s[#s + 1] = '}'
elseif kind == "string" then
@@ -237,7 +275,7 @@ end
-- encode json string using pua lua
function json._pure_encode(luatable, opt)
- return json._pure_stringify(luatable)
+ return json._pure_stringify(luatable, 0, false, opt)
end
-- support empty array
@@ -281,11 +319,14 @@ end
-- @return the json string
--
function json.encode(luatable, opt)
- local encode = cjson and cjson.encode or json._pure_encode
- if opt and opt.pure then
- encode = json._pure_encode
+ local use_pure = not cjson or (opt and (opt.pure or opt.pretty))
+ local encode = use_pure and json._pure_encode or cjson.encode
+ local ok, jsonstr_or_errors
+ if use_pure then
+ ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable, opt)
+ else
+ ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable)
end
- local ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable)
if not ok then
return nil, string.format("encode json failed, %s", jsonstr_or_errors)
end