Skip to content

Instantly share code, notes, and snippets.

@jeromegn
Created February 13, 2017 17:32
Show Gist options
  • Save jeromegn/fb511bca596d224c717d324cf485d273 to your computer and use it in GitHub Desktop.
Save jeromegn/fb511bca596d224c717d324cf485d273 to your computer and use it in GitHub Desktop.
class Messages
include Enumerable
attr_reader :messages
delegate :each, to: :messages
def initialize(messages = {}) # hash of error messages
@messages = messages
end
def full_messages
@messages.flat_map do |k,v|
v.map(&:humanize)
end
end
def merge!(other_messages)
if other_messages.is_a?(self.class)
other_messages.each do |k,v|
@messages[k] = [] if @messages[k].blank?
@messages[k].concat(v)
end
elsif other_messages.is_a?(Hash) # hash of error messages
other_messages.each do |k,v|
@messages[k] = [] if @messages[k].blank?
if v.is_a?(Array)
@messages[k].concat(v.map {|msg| Message.new(:error, k, msg) })
elsif v.is_a?(String)
@messages[k].push(Message.new(:error, k, msg))
end
@messages[k].uniq! { |msg| "#{msg.level}#{msg.message}" }
end
end
end
def errors
by_level(:error)
end
def warns
by_level(:warn)
end
def infos
by_level(:info)
end
def successes
by_level(:success)
end
def error(*args, **kw_args)
add(*args, level: :error, **kw_args)
end
def warn(*args, **kw_args)
add(*args, level: :warn, **kw_args)
end
def info(*args, **kw_args)
add(*args, level: :info, **kw_args)
end
def success(*args, **kw_args)
add(*args, level: :success, **kw_args)
end
def add(ns, message, level: :error, full_message: nil, source: nil)
@messages[ns] ||= []
@messages[ns].push Message.new(level, ns, message, full_message, source)
end
private
def by_level(level)
Messages.new Hash[messages.map do |ns,msgs|
matches = msgs.select {|m| m.level == level }
next unless matches.present?
[ns, matches]
end.compact]
end
end
Message = Struct.new(:level, :ns, :message, :full_message, :source) do
def humanize
full_message.present? ? full_message : "#{ns.to_s.humanize} #{message}"
end
def error?
level == :error
end
def warn?
level == :warn
end
def info?
level == :info
end
def success?
level == :success
end
def ==(other)
if other.is_a? String
other == message
else
other.level == level &&
other.ns == ns &&
other.message == message &&
other.full_message == full_message &&
other.source == source
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment