summaryrefslogtreecommitdiff
path: root/server/src/utility/table.lua
blob: 1c6b21d112053d781715b6d8024a844ff71b5f57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
local table_sort = table.sort
local string_rep = string.rep
local type = type
local pairs = pairs
local ipairs = ipairs
local math_type = math.type

local TAB = setmetatable({}, { __index = function (self, n)
    self[n] = string_rep('\t', n)
    return self[n]
end})

local KEY = {}

function table.dump(tbl)
    if type(tbl) ~= 'table' then
        error('Must be a table')
    end
    local table_mark = {}
    local lines = {}
    lines[#lines+1] = '{'
    local function unpack(tbl, tab)
        if table_mark[tbl] then
            error('Cyclic references are not allowed.')
        end
        table_mark[tbl] = true
        local keys = {}
        for key in pairs(tbl) do
            if type(key) == 'string' then
                if key:find('[^%w_]') then
                    KEY[key] = ('[%q]'):format(key)
                else
                    KEY[key] = key
                end
            elseif math_type(key) == 'integer' then
                KEY[key] = ('[%d]'):format(key)
            else
                error('Key must be `string` or `integer`')
            end
            keys[#keys+1] = key
        end
        table_sort(keys, function (a, b)
            return KEY[a] < KEY[b]
        end)
        for _, key in ipairs(keys) do
            local value = tbl[key]
            local tp = type(value)
            if tp == 'table' then
                lines[#lines+1] = ('%s%s = {'):format(TAB[tab+1], KEY[key])
                unpack(value, tab+1)
                lines[#lines+1] = ('%s},'):format(TAB[tab+1])
            elseif tp == 'string' or tp == 'number' or tp == 'boolean' then
                lines[#lines+1] = ('%s%s = %q,'):format(TAB[tab+1], KEY[key], value)
            else
                error(('Unsupport value type: [%s]'):format(tp))
            end
        end
    end
    unpack(tbl, 0)
    lines[#lines+1] = '}'
    return table.concat(lines, '\n')
end