dotfiles from arch
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
local json = require "json"
|
||||
local type = type
|
||||
local next = next
|
||||
local error = error
|
||||
local table_concat = table.concat
|
||||
local table_sort = table.sort
|
||||
local string_rep = string.rep
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local math_type
|
||||
|
||||
if _VERSION == "Lua 5.1" or _VERSION == "Lua 5.2" then
|
||||
local math_floor = math.floor
|
||||
function math_type(v)
|
||||
if v >= -2147483648 and v <= 2147483647 and math_floor(v) == v then
|
||||
return "integer"
|
||||
end
|
||||
return "float"
|
||||
end
|
||||
else
|
||||
math_type = math.type
|
||||
end
|
||||
|
||||
local statusVisited
|
||||
local statusBuilder
|
||||
local statusDep
|
||||
local statusOpt
|
||||
|
||||
local defaultOpt = {
|
||||
newline = "\n",
|
||||
indent = " ",
|
||||
depth = 0,
|
||||
}
|
||||
defaultOpt.__index = defaultOpt
|
||||
|
||||
local function encode_newline()
|
||||
statusBuilder[#statusBuilder+1] = statusOpt.newline..string_rep(statusOpt.indent, statusDep)
|
||||
end
|
||||
|
||||
local encode_map = {}
|
||||
local encode_string = json._encode_string
|
||||
for k ,v in next, json._encode_map do
|
||||
encode_map[k] = v
|
||||
end
|
||||
|
||||
local function encode(v)
|
||||
local res = encode_map[type(v)](v)
|
||||
statusBuilder[#statusBuilder+1] = res
|
||||
end
|
||||
|
||||
function encode_map.string(v)
|
||||
statusBuilder[#statusBuilder+1] = '"'
|
||||
statusBuilder[#statusBuilder+1] = encode_string(v)
|
||||
return '"'
|
||||
end
|
||||
|
||||
function encode_map.table(t)
|
||||
local first_val = next(t)
|
||||
if first_val == nil then
|
||||
if json.isObject(t) then
|
||||
return "{}"
|
||||
else
|
||||
return "[]"
|
||||
end
|
||||
end
|
||||
if statusVisited[t] then
|
||||
error("circular reference")
|
||||
end
|
||||
statusVisited[t] = true
|
||||
if type(first_val) == 'string' then
|
||||
local key = {}
|
||||
for k in next, t do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types: "..k)
|
||||
end
|
||||
key[#key+1] = k
|
||||
end
|
||||
table_sort(key)
|
||||
statusBuilder[#statusBuilder+1] = "{"
|
||||
statusDep = statusDep + 1
|
||||
encode_newline()
|
||||
do
|
||||
local k = key[1]
|
||||
statusBuilder[#statusBuilder+1] = '"'
|
||||
statusBuilder[#statusBuilder+1] = encode_string(k)
|
||||
statusBuilder[#statusBuilder+1] = '": '
|
||||
encode(t[k])
|
||||
end
|
||||
for i = 2, #key do
|
||||
local k = key[i]
|
||||
statusBuilder[#statusBuilder+1] = ","
|
||||
encode_newline()
|
||||
statusBuilder[#statusBuilder+1] = '"'
|
||||
statusBuilder[#statusBuilder+1] = encode_string(k)
|
||||
statusBuilder[#statusBuilder+1] = '": '
|
||||
encode(t[k])
|
||||
end
|
||||
statusDep = statusDep - 1
|
||||
encode_newline()
|
||||
statusVisited[t] = nil
|
||||
return "}"
|
||||
elseif json.supportSparseArray then
|
||||
local max = 0
|
||||
for k in next, t do
|
||||
if math_type(k) ~= "integer" or k <= 0 then
|
||||
error("invalid table: mixed or invalid key types: "..k)
|
||||
end
|
||||
if max < k then
|
||||
max = k
|
||||
end
|
||||
end
|
||||
statusBuilder[#statusBuilder+1] = "["
|
||||
statusDep = statusDep + 1
|
||||
encode_newline()
|
||||
encode(t[1])
|
||||
for i = 2, max do
|
||||
statusBuilder[#statusBuilder+1] = ","
|
||||
encode_newline()
|
||||
encode(t[i])
|
||||
end
|
||||
statusDep = statusDep - 1
|
||||
encode_newline()
|
||||
statusVisited[t] = nil
|
||||
return "]"
|
||||
else
|
||||
if t[1] == nil then
|
||||
error("invalid table: sparse array is not supported")
|
||||
end
|
||||
statusBuilder[#statusBuilder+1] = "["
|
||||
statusDep = statusDep + 1
|
||||
encode_newline()
|
||||
encode(t[1])
|
||||
local count = 2
|
||||
while t[count] ~= nil do
|
||||
statusBuilder[#statusBuilder+1] = ","
|
||||
encode_newline()
|
||||
encode(t[count])
|
||||
count = count + 1
|
||||
end
|
||||
if next(t, count-1) ~= nil then
|
||||
local k = next(t, count-1)
|
||||
if type(k) == "number" then
|
||||
error("invalid table: sparse array is not supported")
|
||||
else
|
||||
error("invalid table: mixed or invalid key types: "..k)
|
||||
end
|
||||
end
|
||||
statusDep = statusDep - 1
|
||||
encode_newline()
|
||||
statusVisited[t] = nil
|
||||
return "]"
|
||||
end
|
||||
end
|
||||
|
||||
local function beautify_option(option)
|
||||
return setmetatable(option or {}, defaultOpt)
|
||||
end
|
||||
|
||||
local function beautify_builder(builder, v, option)
|
||||
statusVisited = {}
|
||||
statusBuilder = builder
|
||||
statusOpt = beautify_option(option)
|
||||
statusDep = statusOpt.depth
|
||||
encode(v)
|
||||
end
|
||||
|
||||
local function beautify(v, option)
|
||||
beautify_builder({}, v, option)
|
||||
return table_concat(statusBuilder)
|
||||
end
|
||||
|
||||
json.beautify = beautify
|
||||
json._beautify_builder = beautify_builder
|
||||
json._beautify_option = beautify_option
|
||||
|
||||
return json
|
||||
Reference in New Issue
Block a user