class Infobar::Message

def directive_default_options

def directive_default_options
  @directive_default_options ||= {}
end

def directive_default_options

def directive_default_options
  self.class.directive_default_options
end

def directives

def directives
  @directives ||= {}
end

def directives

def directives
  self.class.directives
end

def format

def format
  @opts['format']
end

def initialize(opts)

def initialize(opts)
  @opts = opts.each_with_object({}) { |(k, v), h| h[k.to_s] = v }
end

def opts_for(directive)

def opts_for(directive)
  @opts.fetch(directive, directive_default_options[directive])
end

def register(directive, **opts, &block)

def register(directive, **opts, &block)
  directives.key?(directive) and
    warn "Overwriting old directive #{directive}."
  directives[directive]                = block
  directive_default_options[directive] = opts
  self
end

def to_hash

def to_hash
  result = @opts.dup
  result[:format] = result.delete('format')
  result
end

def to_str

def to_str
  keys = directives.keys.sort_by { |k| -k.size }
  format.gsub(/(?<!%)(#{keys * ?|})/) do
    directives[$1].call($1, opts_for($1))
  end
end