Module:Infobox road/abbrev/defs

Documentation for this module may be created at Module:Infobox road/abbrev/defs/doc

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