Module:Infobox road/link/defs

local p = {}

local format = mw.ustring.format

Link = {formatArgs = {"route"}}

function Link:new(obj) obj = obj or {} setmetatable(obj, self) self.__index = self return obj end

function Link:link(args) self:preprocess(args) return self:exception(args) or self:default(args) end

function Link:preprocess(args) local preprocessors = self.preprocessors or {} for i,preprocessor in ipairs(preprocessors) do       preprocessor(args) end end

function Link:exception(args) local exceptions = self.exceptions or {} local route = args.route return exceptions[route] end

function Link:default(args) local formatArgs = self.formatArgs local formatArguments = {} for i,v in ipairs(formatArgs) do       formatArguments[i] = args[v] end local formatStr = self.formatStr return formatStr and format(formatStr, unpack(formatArguments)) or false end

Type = Link:new

function Type:link(args) self:preprocess(args) return self:fromState(args) or self:exception(args) or self:default(args) end

function Type:fromState(args) local stateName = args.state or args.province local state = self[stateName] return state and state:link(args) or nil end

Country = {}

function Country:new(obj) obj = obj or {} setmetatable(obj, self) self.__index = self return obj end

function Country:newWithSimpleLinks(links) local country = self:new for i,v in pairs(links) do       local link = Link:new{formatStr = v}        if type(i) == "string" then country[i] = link else for _,t in pairs(i) do               country[t] = link end end end return country end

function Country:typeOverride(args) return end

function Country:type(args) local type = args.type or '' return self:typeOverride(args) or self[type] or self.default end

function Country:link(args) local type = self:type(args) return type and type:link(args) or error("Invalid type", 0) end

p.Link = Link p.Type = Type p.Country = Country return p