-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtextutils.lua
More file actions
135 lines (118 loc) · 3.8 KB
/
textutils.lua
File metadata and controls
135 lines (118 loc) · 3.8 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
---@source https://raw.githubusercontent.com/cc-tweaked/CC-Tweaked/876fd8ddb805365c33942afb81d6da7cbd0cbca5/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua
local TextUtils = {}
--#region local functions
local g_tLuaKeywords = {
["and"] = true,
["break"] = true,
["do"] = true,
["else"] = true,
["elseif"] = true,
["end"] = true,
["false"] = true,
["for"] = true,
["function"] = true,
["if"] = true,
["in"] = true,
["local"] = true,
["nil"] = true,
["not"] = true,
["or"] = true,
["repeat"] = true,
["return"] = true,
["then"] = true,
["true"] = true,
["until"] = true,
["while"] = true,
}
--- A version of the ipairs iterator which ignores metamethods
local function inext(tbl, i)
i = (i or 0) + 1
local v = rawget(tbl, i)
if v == nil then return nil else return i, v end
end
local serialize_infinity = math.huge
local function serialize_impl(t, tracking, indent, opts)
local sType = type(t)
if sType == "table" then
if tracking[t] ~= nil then
if tracking[t] == false then
error("Cannot serialize table with repeated entries", 0)
else
error("Cannot serialize table with recursive entries", 0)
end
end
tracking[t] = true
local result
if next(t) == nil then
-- Empty tables are simple
result = "{}"
else
-- Other tables take more work
local open, sub_indent, open_key, close_key, equal, comma = "{\n", indent .. " ", "[ ", " ] = ", " = ", ",\n"
if opts.compact then
open, sub_indent, open_key, close_key, equal, comma = "{", "", "[", "]=", "=", ","
end
result = open
local seen_keys = {}
for k, v in inext, t do
seen_keys[k] = true
result = result .. sub_indent .. serialize_impl(v, tracking, sub_indent, opts) .. comma
end
for k, v in next, t do
if not seen_keys[k] then
local sEntry
if type(k) == "string" and not g_tLuaKeywords[k] and string.match(k, "^[%a_][%a%d_]*$") then
sEntry = k .. equal .. serialize_impl(v, tracking, sub_indent, opts) .. comma
else
sEntry = open_key .. serialize_impl(k, tracking, sub_indent, opts) .. close_key .. serialize_impl(v, tracking, sub_indent, opts) .. comma
end
result = result .. sub_indent .. sEntry
end
end
result = result .. indent .. "}"
end
if opts.allow_repetitions then
tracking[t] = nil
else
tracking[t] = false
end
return result
elseif sType == "string" then
return string.format("%q", t)
elseif sType == "number" then
if t ~= t then --nan
return "0/0"
elseif t == serialize_infinity then
return "1/0"
elseif t == -serialize_infinity then
return "-1/0"
else
return tostring(t)
end
elseif sType == "boolean" or sType == "nil" then
return tostring(t)
else
return "Cannot serialize type " .. sType
end
end
--#endregion
function TextUtils.serialize(t, opts)
local tTracking = {}
return serialize_impl(t, tTracking, "", opts or {})
end
---@param s string
---@return table | nil
function TextUtils.unserialize(s)
if type(s) ~= "string" then
return nil
end
local func = loadstring("return " .. s, "unserialize", "t", {})
if func then
local ok, result = pcall(func)
if ok then
return result
end
end
return nil
end
return TextUtils