Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pretty printing #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
54 changes: 42 additions & 12 deletions json.lua
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,33 @@ for k, v in pairs(escape_char_map) do
end


local function make_indent(state)
return string.rep(" ", state.currentIndentLevel * state.opts.indent)
end


local function escape_char(c)
return escape_char_map[c] or string.format("\\u%04x", c:byte())
end


local function encode_nil(val)
local function encode_nil()
return "null"
end


local function encode_table(val, stack)
local function encode_table(val, state)
local res = {}
stack = stack or {}
local stack = state.stack
local pretty = state.opts.indent > 0

local close_indent = make_indent(state)
local comma = pretty and ",\n" or ","
local colon = pretty and ": " or ":"
local open_brace = pretty and "{\n" or "{"
local close_brace = pretty and ("\n" .. close_indent .. "}") or "}"
local open_bracket = pretty and "[\n" or "["
local close_bracket = pretty and ("\n" .. close_indent .. "]") or "]"

-- Circular reference?
if stack[val] then error("circular reference") end
Expand All @@ -78,22 +92,26 @@ local function encode_table(val, stack)
error("invalid table: sparse array")
end
-- Encode
for i, v in ipairs(val) do
table.insert(res, encode(v, stack))
for _, v in ipairs(val) do
state.currentIndentLevel = state.currentIndentLevel + 1
table.insert(res, make_indent(state) .. encode(v, state))
state.currentIndentLevel = state.currentIndentLevel - 1
end
stack[val] = nil
return "[" .. table.concat(res, ",") .. "]"
return open_bracket .. table.concat(res, comma) .. close_bracket

else
-- Treat as an object
for k, v in pairs(val) do
if type(k) ~= "string" then
error("invalid table: mixed or invalid key types")
end
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
state.currentIndentLevel = state.currentIndentLevel + 1
table.insert(res, make_indent(state) .. encode(k, state) .. colon .. encode(v, state))
state.currentIndentLevel = state.currentIndentLevel - 1
end
stack[val] = nil
return "{" .. table.concat(res, ",") .. "}"
return open_brace .. table.concat(res, comma) .. close_brace
end
end

Expand Down Expand Up @@ -121,18 +139,30 @@ local type_func_map = {
}


encode = function(val, stack)
encode = function(val, state)
local t = type(val)
local f = type_func_map[t]
if f then
return f(val, stack)
return f(val, state)
end
error("unexpected type '" .. t .. "'")
end


function json.encode(val)
return ( encode(val) )
local function add_default_opts(opts)
opts = opts or {}
opts.indent = opts.indent or 0
return opts
end


function json.encode(val, opts)
local state = {
opts = add_default_opts(opts),
currentIndentLevel = 0,
stack = {}
}
return encode(val, state)
end


Expand Down