@@ -2,8 +2,20 @@ local t_insert = table.insert
22
33local M = {}
44
5+ local indentCache = {}
6+ local function indentFor (k )
7+ if k < 1 then
8+ return " "
9+ end
10+ if not indentCache [k ] then
11+ indentCache [k ] = string.rep (" \t " , k )
12+ end
13+ return indentCache [k ]
14+ end
15+ local function strSort (a , b )
16+ return tostring (a ) < tostring (b )
17+ end
518--- @alias StringifyTypes string | number | boolean | nil | table<StringifyTypes , StringifyTypes>
6-
719local function writeStringify (buf , value , allowNewlines , tabs )
820 local valType = type (value )
921 if not tabs then
@@ -22,39 +34,40 @@ local function writeStringify(buf, value, allowNewlines, tabs)
2234 buf [# buf + 1 ] = " {\n "
2335 -- ipairs compatible keys are done first so we can use the array syntax for them
2436 local arrayKeys = {}
25- local indent = string.rep ( " \t " , tabs )
37+ local indent = indentFor ( tabs )
2638 for k , v in ipairs (value ) do
2739 arrayKeys [k ] = true
2840 buf [# buf + 1 ] = indent
2941 writeStringify (buf , v , allowNewlines , tabs + 1 )
3042 buf [# buf + 1 ] = " ,\n "
3143 end
3244
33- local mapKeys = { }
34- for key in pairs (value ) do t_insert (mapKeys , key ) end
35- table.sort (mapKeys , function (a , b )
36- return tostring (a ) < tostring (b )
37- end )
45+ local mapKeys = {}
46+ for key in pairs (value ) do
47+ -- avoid printing array-style items twice
48+ if not arrayKeys [key ] then
49+ t_insert (mapKeys , key )
50+ end
51+ end
52+ table.sort (mapKeys , strSort )
3853
3954 for _ , k in ipairs (mapKeys ) do
40- if not arrayKeys [k ] then
41- if type (k ) == " string" and k :find (" \n " ) and allowNewlines then
42- -- multiline strings as keys need the space around the key value to parse correctly
43- buf [# buf + 1 ] = indent .. " [ "
44- writeStringify (buf , k , allowNewlines , nil )
45- buf [# buf + 1 ] = " ] = "
46- else
47- buf [# buf + 1 ] = indent .. " ["
48- writeStringify (buf , k , allowNewlines , nil )
49- buf [# buf + 1 ] = " ] = "
50- end
51- writeStringify (buf , value [k ], allowNewlines , tabs + 1 )
52- buf [# buf + 1 ] = " ,\n "
55+ if type (k ) == " string" and allowNewlines and k :find (" \n " ) then
56+ -- multiline strings as keys need the space around the key value to parse correctly
57+ buf [# buf + 1 ] = indent .. " [ "
58+ writeStringify (buf , k , allowNewlines , nil )
59+ buf [# buf + 1 ] = " ] = "
60+ else
61+ buf [# buf + 1 ] = indent .. " ["
62+ writeStringify (buf , k , allowNewlines , nil )
63+ buf [# buf + 1 ] = " ] = "
5364 end
65+ writeStringify (buf , value [k ], allowNewlines , tabs + 1 )
66+ buf [# buf + 1 ] = " ,\n "
5467 end
55- buf [# buf + 1 ] = string.rep ( " \t " , tabs - 1 ) .. " }"
68+ buf [# buf + 1 ] = indentFor ( tabs - 1 ) .. " }"
5669 else
57- error (" Disallowed stringify type " .. valType )
70+ error (" Disallowed stringify type " .. valType )
5871 end
5972end
6073-- Converts a table to a string which will be valid Lua. The result will ipairs to utilise the array
@@ -108,4 +121,4 @@ return %s
108121 return f :close () or false
109122end
110123
111- return M
124+ return M
0 commit comments