Module:Infobox road/abbrev/defs

local p = {}

local format = string.format

Abbr = {formatArgs = {"route"}}

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

function Abbr:abbr(args) self:preprocess(args) return self:exception(args) or self:default(args) end

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

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

function Abbr: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 = Abbr:new

function Type:abbr(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:abbr(args) or nil end

Country = {}

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

function Country:newWithSimpleAbbrs(abbrs) local country = self:new for i,v in pairs(abbrs) do       local abbr = Abbr:new{formatStr = v}        if type(i) == "string" then country[i] = abbr else for _,t in pairs(i) do               country[t] = abbr 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:abbr(args) local type = self:type(args) return type and type:abbr(args) or error("Invalid type", 0) end

p.Abbr = Abbr p.Type = Type p.Country = Country return p