Module:Highway shields/defs

local p = {}

local format = string.format

Shield = {formatArgs = {"route"}}

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

function Shield:shield(args) self:preprocess(args) return self:exception(args) or self:default(args) end

function Shield:update(args) return end

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

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

function Shield:default(args) local formatArgs = self.formatArgs local formatArguments = {} for i,v in ipairs(formatArgs) do       formatArguments[i] = args[v] end local subtypes = self.subtypes or {} local subtype = args.subtype or '' local subtypeShield = subtypes[subtype] if subtypeShield then return format(subtypeShield, unpack(formatArguments)) end local by100 = self.by100 local formatStr = "" if by100 then local less = by100.less local more = by100.more local route = tonumber(args.route) formatStr = (route < 100) and less or more else formatStr = self.formatStr end return formatStr and format(formatStr, unpack(formatArguments)) or false end

Type = Shield:new

function Type:shield(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 local state = self[stateName] return state and state:shield(args) or nil end

function Type:addShield(state, shield) self[state] = shield end

UniqueType = Type:new

function UniqueType:update(args) local state = args.state local shield = args.shield if state then self.states[state] = true end if shield and not(self.uniqueShield) then self.uniqueShield = shield end end

function UniqueType:shield(args) local stateArg = args.state local states = self.states if states[stateArg] then local uniqueShield = self.uniqueShield return uniqueShield:shield(args) else return nil end end

Alias = {}

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

function Alias:shield(args) local type = self.type setmetatable(args, {__index = self}) if self.state then args.stateOrig = args.state args.state = self.state end return type:shield(args) end

Country = {}

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

function Country:addType(key, type) self[key] = type end

Country.addShield = Country.addType

function Country:shield(args) local type = self[args.type] return type and type:shield(args) end

function Country:type(typeToCheck) local type = self[typeToCheck] if not(type) then type = Type:new self[typeToCheck] = type end return type end

function Country:uniqueType(typeToCheck) local type = self[typeToCheck] if not(type) then type = UniqueType:new{states = {}} self[typeToCheck] = type end return type end

ShieldPreprocessors = {}

p.Country = Country p.Shield = Shield p.Type = Type p.UniqueType = UniqueType p.Alias = Alias p.ShieldPreprocessors = ShieldPreprocessors

return p