157 lines
3.6 KiB
Lua
157 lines
3.6 KiB
Lua
local color = minetest.get_color_escape_sequence
|
|
local concat = table.concat
|
|
local dump = dump
|
|
local getmetatable = getmetatable
|
|
local insert = table.insert
|
|
local pairs = pairs
|
|
local rep = string.rep
|
|
local sort = table.sort
|
|
local tonumber = tonumber
|
|
local type = type
|
|
|
|
local indent_size
|
|
local max_depth
|
|
|
|
local handlers = {}
|
|
local bucket_order = {'boolean', 'number', 'string'}
|
|
|
|
local color_unknown = color('#C99')
|
|
local color_nil = color('#CCC')
|
|
local color_boolean = color('#9CF')
|
|
local color_number = color('#FF9')
|
|
local color_string = color('#9FF')
|
|
local color_function = color('#9F9')
|
|
local color_thread = color('#9FC')
|
|
local color_table = color('#99F')
|
|
local color_metatable = color('#FC9')
|
|
local color_muted = color('#999')
|
|
local color_userdata = color('#F99')
|
|
|
|
local function check_metatable(sb, value)
|
|
if getmetatable(value) ~= nil then
|
|
insert(sb, color_metatable)
|
|
insert(sb, ' contains metatable')
|
|
end
|
|
end
|
|
|
|
local function dump_value(sb, depth, value, full)
|
|
local t = type(value)
|
|
if handlers[t] == nil then
|
|
insert(sb, color_unknown)
|
|
insert(sb, t)
|
|
else
|
|
return handlers[t](sb, depth, value, full)
|
|
end
|
|
end
|
|
|
|
local function dump_nil(sb, depth, value)
|
|
insert(sb, color_nil)
|
|
insert(sb, 'nil')
|
|
end;
|
|
|
|
local function dump_boolean(sb, depth, value)
|
|
insert(sb, color_boolean)
|
|
insert(sb, dump(value))
|
|
end
|
|
|
|
local function dump_number(sb, depth, value)
|
|
insert(sb, color_number)
|
|
insert(sb, dump(value))
|
|
end
|
|
|
|
local function dump_string(sb, depth, value)
|
|
insert(sb, color_string)
|
|
insert(sb, dump(value))
|
|
end
|
|
|
|
local function dump_function(sb, depth, value)
|
|
insert(sb, color_function)
|
|
insert(sb, 'function')
|
|
end
|
|
|
|
local function dump_thread(sb, depth, value)
|
|
insert(sb, color_thread)
|
|
insert(sb, 'thread')
|
|
end
|
|
|
|
local function dump_table_elements(sb, depth, indent, value, keys)
|
|
for k, v in pairs(keys) do
|
|
insert(sb, indent)
|
|
dump_value(sb, depth, v, false)
|
|
insert(sb, color_muted)
|
|
insert(sb, ' = ')
|
|
dump_value(sb, depth, value[v], true)
|
|
insert(sb, '\n')
|
|
end
|
|
end
|
|
|
|
local function dump_table_expanded(sb, depth, value)
|
|
local indent = rep(' ', depth * indent_size)
|
|
local buckets = {}
|
|
local keys = {}
|
|
|
|
for k, v in pairs(bucket_order) do
|
|
buckets[v] = {}
|
|
end
|
|
|
|
for k, v in pairs(value) do
|
|
insert(buckets[type(k)] or keys, k)
|
|
end
|
|
|
|
for k, v in pairs(buckets) do
|
|
sort(v)
|
|
end
|
|
|
|
insert(sb, color_table)
|
|
insert(sb, '{')
|
|
check_metatable(sb, value)
|
|
insert(sb, '\n')
|
|
|
|
for k, v in pairs(bucket_order) do
|
|
dump_table_elements(sb, depth, indent, value, buckets[v])
|
|
end
|
|
|
|
dump_table_elements(sb, depth, indent, value, keys)
|
|
|
|
insert(sb, rep(' ', (depth - 1) * indent_size))
|
|
insert(sb, color_table)
|
|
insert(sb, '}')
|
|
end
|
|
|
|
local function dump_table(sb, depth, value, full)
|
|
if full and depth < max_depth then
|
|
dump_table_expanded(sb, depth + 1, value)
|
|
else
|
|
insert(sb, color_table)
|
|
insert(sb, 'table')
|
|
check_metatable(sb, value)
|
|
end
|
|
end
|
|
|
|
local function dump_userdata(sb, depth, value, full)
|
|
insert(sb, color_userdata)
|
|
insert(sb, 'userdata ')
|
|
|
|
if full and depth < max_depth then
|
|
dump_table_expanded(sb, depth + 1, getmetatable(value))
|
|
end
|
|
end
|
|
|
|
handlers['nil'] = dump_nil
|
|
handlers.boolean = dump_boolean
|
|
handlers.number = dump_number
|
|
handlers.string = dump_string
|
|
handlers.userdata = dump_userdata
|
|
handlers['function'] = dump_function
|
|
handlers.thread = dump_thread
|
|
handlers.table = dump_table
|
|
|
|
return function(value, options)
|
|
indent_size = tonumber(options.indent_size) or 4
|
|
max_depth = tonumber(options.max_depth) or 1
|
|
|
|
local sb = {}
|
|
dump_value(sb, 0, value, true)
|
|
return concat(sb)
|
|
end
|