I'd use a slightly different approach; rather than trying to generalize everything to the nth degree, I'd just write individual functions for the "special case" addons:
Code:
local SavedVariables = {
["_NPCScan.Overlay"] = {
["_NPCScanOverlayOptions"] = true,
},
["Altoholic"] = {
["AltoholicDB"] = function(t)
return {
["global"] = {
["options"] = {
["ShowMinimap"] = t.global.options.ShowMinimap,
}
}
}
end,
},
}
local function copyTable(src, dst)
if type(src) ~= "table" then
return {}
end
if type(dst) ~= "table" then
dst = {}
end
for k, v in pairs(src) do
if type(v) == "table" then
dst[k] = copyTable(v, dst[k])
elseif type(v) ~= type(dst[k]) then
dst[k] = v
end
end
for k, v in pairs(dst) do
if type(src[k]) == nil then
-- "not src[k]" won't work as desired for values of "false"
dst[k] = nil
end
end
end
ExportedSV = {}
function ExportSV()
for addon, svars in pairs(SavedVariables) do
ExportedSV[addon] = ExportedSV[addon] or {}
for name, data in pairs(svars) do
local svar = _G[name]
if svar then
if type(data) == "boolean" then
-- we want the whole thing
if type(svar) == "table" then
ExportedSV[addon][name] = copyTable(data)
else
-- not a table, just copy the value
ExportedSV[addon][name] = svar
end
elseif type(data) == "function" then
-- we only want part of it
ExportedSV[addon][name] = data(svar)
end
end
end
end
end
If you really wanted something totally generic, you'd want to factor out the "find and copy this key at any depth" code into its own function that could be called recursively, like the "copy this table" code, but it would probably be more of a headache than it's worth. If you're already writing out by hand which keys you want to copy, it's hardly more work to just write out a quick function that gets the wanted keys and builds a skeleton table with them.
Also, I made a small change in the "copy this table" function; see the in-code comment.