Clients/Client2020/ExtraContent/LuaPackages/UGCValidationImpl/util/validateWithSchema.lua

100 lines
2.4 KiB
Lua

local function checkName(nameList, instanceName)
if type(nameList) == "table" then
for _, name in pairs(nameList) do
if name == instanceName then
return true
end
end
elseif type(nameList) == "string" then
return nameList == instanceName
end
return false
end
local function getReadableName(nameList)
if type(nameList) == "table" then
return table.concat(nameList, " or ")
elseif type(nameList) == "string" then
return nameList
end
return "*"
end
local function validateWithSchemaHelper(schema, instance, authorizedSet)
-- validate
if instance.ClassName ~= schema.ClassName or (schema.Name ~= nil and not checkName(schema.Name, instance.Name)) then
return { success = false }
end
-- validate children
if schema._children then
for _, childSchema in pairs(schema._children) do
local found = false
local mostRecentFailure
for _, child in pairs(instance:GetChildren()) do
local result = validateWithSchemaHelper(childSchema, child, authorizedSet)
if result.success then
found = true
break
elseif result.message then
mostRecentFailure = result
end
end
if not found and not childSchema._optional then
if mostRecentFailure then
return mostRecentFailure
else
return {
success = false,
message = "Could not find a "
.. childSchema.ClassName
.. " called "
.. getReadableName(childSchema.Name)
.. " inside "
.. instance.Name
}
end
end
end
end
authorizedSet[instance] = true
return { success = true }
end
local function validateWithSchema(schema, instance)
if instance.ClassName ~= schema.ClassName or (schema.Name ~= nil and schema.Name ~= instance.Name) then
return {
success = false,
message = "Expected top-level instance to be a " .. schema.ClassName,
}
end
local authorizedSet = {}
local result = validateWithSchemaHelper(schema, instance, authorizedSet)
if not result.success then
return result
end
-- check for extra descendants
local unauthorizedDescendantPaths = {}
for _, descendant in pairs(instance:GetDescendants()) do
if authorizedSet[descendant] == nil then
unauthorizedDescendantPaths[#unauthorizedDescendantPaths + 1] = descendant:GetFullName()
end
end
if #unauthorizedDescendantPaths > 0 then
return {
success = false,
message = "Unexpected Descendants:\n" .. table.concat(unauthorizedDescendantPaths, "\n")
}
end
return { success = true }
end
return validateWithSchema