aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util.lua56
-rwxr-xr-xutil_test.lua38
2 files changed, 94 insertions, 0 deletions
diff --git a/util.lua b/util.lua
index 3d10e95..6aa4b92 100644
--- a/util.lua
+++ b/util.lua
@@ -316,4 +316,60 @@ util.visual_chars_in_line = function(win, line, nchars)
return line_len
end
+--- Utility table function
+util.table = {}
+
+--- Recursively copy a table and all its members.
+-- @param tbl the table to copy
+-- @return a deep copy of the table
+function util.table.deep_copy(tbl)
+ local cpy = {}
+ for k, v in pairs(tbl) do
+ if type(v) ~= 'table' then
+ cpy[k] = v
+ else
+ cpy[k] = util.table.deep_copy(v)
+ end
+ end
+
+ for i, v in ipairs(tbl) do
+ if type(v) ~= 'table' then
+ cpy[i] = v
+ else
+ cpy[i] = util.table.deep_copy(v)
+ end
+ end
+ return cpy
+end
+
+--- Recursively merge two tables.
+-- This method modifies the weak table, if this is not intended make sure you
+-- use a deep copy of the weak table.
+-- The members of the strong table override members of the weak one.
+-- @param weak table which's members are potentially overridden
+-- @param strong table which's members override ones from the weak table
+-- @return the merged table
+function util.table.merge(weak, strong)
+ -- merge named members
+ for k, v in pairs(strong) do
+ -- potentially override the weak member
+ if type(v) ~= 'table' then
+ weak[k] = v
+ else
+ weak[k] = util.table.merge(weak[k] or {}, v)
+ end
+ end
+
+ -- merge numbered members
+ for i, v in ipairs(strong) do
+ -- potentially override the weak member
+ if type(v) ~= 'table' then
+ weak[i] = v
+ else
+ weak[i] = util.table.merge(weak[i] or {}, v)
+ end
+ end
+ return weak
+end
+
return util
diff --git a/util_test.lua b/util_test.lua
index a0f4218..661b9f5 100755
--- a/util_test.lua
+++ b/util_test.lua
@@ -30,4 +30,42 @@ function test_visual_chars_in_line() -- luacheck: ignore 111
lunatest.assert_equal(util.visual_chars_in_line(win, s, #s), 6)
end
+function test_table_deep_copy() -- luacheck: ignore 111
+ local t = {1, 2, 3, foo = {4, 5, bar = 'bar'}}
+ local cpy = util.table.deep_copy(t)
+
+ lunatest.assert_table(cpy)
+ lunatest.assert_len(3, cpy)
+ lunatest.assert_table(cpy.foo)
+ lunatest.assert_len(2, cpy.foo)
+ for i, v in ipairs(t) do
+ lunatest.assert_equal(v, cpy[i])
+ end
+
+ t[2] = 12
+ lunatest.assert_not_equal(t[2], cpy[2])
+ t.foo[2] = 13
+ lunatest.assert_not_equal(t.foo[2], cpy.foo[2])
+end
+
+function test_table_merge() -- luacheck: ignore 111
+ local t = {1, 2, foo = {bar = {nose = 'nose'}}}
+ local t2 = {3, foo = {4, 5, bar = {bar = 'bar'}}}
+ lunatest.assert_table(t)
+ lunatest.assert_table(t2)
+
+ util.table.merge(t, t2)
+
+ lunatest.assert_table(t)
+ lunatest.assert_len(2, t)
+ lunatest.assert_table(t.foo)
+ lunatest.assert_len(2, t.foo)
+
+ lunatest.assert_equal(t[1], t2[1])
+ lunatest.assert_equal(t[2], 2)
+
+ lunatest.assert_equal(t.foo.bar.bar, 'bar')
+ lunatest.assert_equal(t.foo.bar.nose, 'nose')
+end
+
lunatest.run()