Mòdulu:paràmitri
La ducumintazzioni di stu mòdulu si pò criari nta Mòdulu:paràmitri/doc
local m_table = require("Mòdulu:tabbella")
local p = {}
p.NUMBER = "number"
p.INT = "int"
p.FLOAT = "float"
p.BOOLEAN = "boolean"
p.UNKNOWN_PARAM = "unknown parameter"
p.MISSING_PARAM = "missing required parameter"
p.EMPTY_PARAM = "empty required parameter"
p.INVALID_VALUE = "invalid value"
p.VALUE_NOT_IN_ENUM = "value not in enum"
p.INVALID_TYPE = "invalid type"
p.ALIAS_TO_UNKNOWN = "alias to undefined parameter"
p.ALIAS_TO_ALIAS = "alias to alias parameter"
p.ALIAS_TO_ITSELF = "alias to itself"
p.ENUM_WITH_CHECKER = "enum with checker"
p.ENUM_INVALID_VALUE = "invalid enum values"
local UNCATCHABLE_ERRORS = {
p.INVALID_TYPE,
p.ALIAS_TO_UNKNOWN,
p.ALIAS_TO_ALIAS,
p.ALIAS_TO_ITSELF,
p.ENUM_WITH_CHECKER,
p.ENUM_INVALID_VALUE,
}
local ERROR_MESSAGES = {
[p.UNKNOWN_PARAM] = 'Paràmitru "%s" scanusciutu',
[p.MISSING_PARAM] = 'Paràmitru addimannatu "%s" assenti',
[p.EMPTY_PARAM] = 'Paràmitru addimannatu "%s" vacanti',
[p.INVALID_VALUE] = 'Valuri nun vàliddu pû paràmitru "%s" ("%s") di tipu %s',
[p.VALUE_NOT_IN_ENUM] = 'Valuri nun vàliddu pû paràmitru "%s" ("%s")',
[p.INVALID_TYPE] = 'Tipu scanusciutu pû paràmitru "%s" ("%s")',
[p.ALIAS_TO_UNKNOWN] = 'Paràmitru "%s", alias abbersu nu paràmitru nun difinutu "%s"',
[p.ALIAS_TO_ALIAS] = 'Paràmitru "%s", alias abbersu nu àutru alias ("%s")',
[p.ALIAS_TO_ITSELF] = 'Paràmitru "%s", alias abbersu iḍḍu stissu',
[p.ENUM_WITH_CHECKER] = 'Lu paràmitru "%s" è n’enumerazzioni c’una pricunnizzioni',
[p.ENUM_INVALID_VALUE] = 'Valuri enumiratu nun vàliddu pû paràmitru "%s" ("%s") di tipu %s',
}
local function buildErrorMessage(errorType, ...)
return {
errorType = errorType,
errorData = { ... }
}
end
local function toBoolean(argValue, argName, scnTypeName, errorType)
if m_table.contains({ "1", "sì", "viru", "sini", "si" }, argValue) then
return true
elseif m_table.contains({ "0", "no", "noni", "farsu","fàusu","fàvusu","falsu","favusu","fausu" }, argValue) then
return false
else
error(buildErrorMessage(errorType, argName, argValue, scnTypeName))
end
end
local function toNumber(argValue, argName, toInt, scnTypeName, errorType)
local val = tonumber(argValue)
if val ~= nil then
if not toInt or toInt and val == math.floor(val) then
return val
end
end
error(buildErrorMessage(errorType, argName, argValue, scnTypeName))
end
local function getValue(expectedType, rawValue, argName, errorType)
local value, scnTypeName
-- Vérification des types des arguments.
if expectedType == nil then
scnTypeName = "catina"
if type(rawValue) ~= "string" then
error(buildErrorMessage(errorType, argName, rawValue, scnTypeName))
end
value = rawValue
elseif expectedType == p.NUMBER then
scnTypeName = "nùmmiru"
value = toNumber(rawValue, argName, false, scnTypeName, errorType)
elseif expectedType == p.INT then
scnTypeName = "nteru"
value = toNumber(rawValue, argName, true, scnTypeName, errorType)
elseif expectedType == p.FLOAT then
scnTypeName = "float"
value = toNumber(rawValue, argName, false, scnTypeName, errorType)
elseif expectedType == p.BOOLEAN then
scnTypeName = "booleanu"
value = toBoolean(rawValue, argName, scnTypeName, errorType)
end
return value, scnTypeName
end
local function checkParametersDefinitions(definedParameters)
local validTypes = { p.BOOLEAN, p.NUMBER, p.INT, p.FLOAT }
for paramName, paramValue in pairs(definedParameters) do
if paramValue.type and not m_table.contains(validTypes, paramValue.type) then
error(buildErrorMessage(p.INVALID_TYPE, paramName, paramValue.type))
end
if paramValue.enum then
if paramValue.checker then
error(buildErrorMessage(p.ENUM_WITH_CHECKER, paramName))
else
for _, enumValue in ipairs(paramValue.enum) do
getValue(paramValue.type, enumValue, paramName, p.ENUM_INVALID_VALUE)
end
end
end
if paramValue.alias_of then
local alias = paramValue.alias_of
if not definedParameters[alias] then
error(buildErrorMessage(p.ALIAS_TO_UNKNOWN, paramName, paramValue.alias_of))
elseif alias == paramName then
error(buildErrorMessage(p.ALIAS_TO_ITSELF, paramName))
elseif definedParameters[alias].alias_of then
error(buildErrorMessage(p.ALIAS_TO_ALIAS, paramName, paramValue.alias_of))
end
end
end
end
local function extractArgumentKey(param, processedArgs, argName, definedParameters)
local key
local outParam
if param.alias_of then
if not processedArgs[param.alias_of] then
key = param.alias_of
outParam = definedParameters[param.alias_of]
end
else
key = argName
outParam = param
end
return key, outParam
end
local function extractArgumentValue(param, key, argName, argValue, processedArgs)
if argValue then
argValue = mw.text.trim(argValue)
end
if argValue == "" then
if param.required and param.allow_empty or not param.required then
argValue = nil
processedArgs[key] = nil
else
error(buildErrorMessage(p.EMPTY_PARAM, argName))
end
end
if argValue then
local value, scnTypeName = getValue(param.type, argValue, argName, p.INVALID_VALUE)
if type(param.enum) == "table" and not m_table.contains(param.enum, value) then
error(buildErrorMessage(p.VALUE_NOT_IN_ENUM, argName, value))
elseif type(param.checker) == "function" and not param.checker(value) then
error(buildErrorMessage(p.INVALID_VALUE, argName, value, scnTypeName))
end
processedArgs[key] = value
end
end
local function parseArguments(args, definedParameters)
local processedArgs = {}
for argName, argValue in pairs(args) do
local param = definedParameters[argName]
if param then
local key, actualParam = extractArgumentKey(param, processedArgs, argName, definedParameters)
if key then
extractArgumentValue(actualParam, key, argName, argValue, processedArgs)
end
else
error(buildErrorMessage(p.UNKNOWN_PARAM, argName))
end
end
return processedArgs
end
local function checkRequiredParameters(processedArgs, definedParameters)
for paramName, paramValue in pairs(definedParameters) do
if processedArgs[paramName] == nil and paramValue.alias_of == nil then
if paramValue.required and not paramValue.allow_empty then
error(buildErrorMessage(p.MISSING_PARAM, paramName))
elseif paramValue.default ~= nil then
processedArgs[paramName] = paramValue.default
end
end
end
end
function p.process(args, definedParameters, silentErrors)
local success, result = pcall(function()
checkParametersDefinitions(definedParameters)
local processedArgs = parseArguments(args, definedParameters)
checkRequiredParameters(processedArgs, definedParameters)
return processedArgs
end)
if not success then
local errorType = result.errorType
local errorData = result.errorData
local errorMessage = mw.ustring.format(ERROR_MESSAGES[errorType], unpack(errorData))
if silentErrors and not m_table.contains(UNCATCHABLE_ERRORS, errorType) then
local argName = errorData[1]
local argValue = type(argName) == "number" and tonumber(argName) or argName
return { argValue, errorType, errorMessage }, false
elseif m_table.contains(UNCATCHABLE_ERRORS, errorType) then
errorMessage = "Erruri nternu: " .. errorMessage
end
error(errorMessage, 0)
end
return result, true
end
function p.checkParametersFromTemplate(frame)
local templateName = mw.ustring.sub(frame:getParent():getTitle(), 8)
local expectedArgs = {}
for _, arg in ipairs(frame.args) do expectedArgs[arg] = true end
local templateArgs = frame:getParent().args
local cats = ''
for templateArg, _ in pairs(templateArgs) do
if not expectedArgs[tostring(templateArg)] then
cats = cats .. '[[Catigurìa:Chiamata dû template ' .. templateName .. ' cû paràmitru scanusciutu "' .. templateArg .. '"]]'
if not mw.title.new('Catigurìa:Chiamata dû template ' .. templateName .. ' cû paràmitru scanusciutu "' .. templateArg .. '"').exists then
cats = cats .. '[[Catigurìa:Chiamata dû template ' .. templateName .. ' c’un paràmitru scanusciutu|' .. templateArg .. ']]'
end
end
end
return cats
end
return p