module Cuprum::Matching::ClassMethods

Class methods extend-ed into a class when the module is included.

Public Instance Methods

match(status, error: nil, value: nil, &block) click to toggle source

Defines a match clause for the matcher.

@param status [Symbol] The status to match. The clause will match a

result only if the result has the same status as the match clause.

@param error [Class] The type of error to match. If given, the clause

will match a result only if the result error is an instance of the
given class, or an instance of a subclass.

@param value [Class] The type of value to match. If given, the clause

will match a result only if the result value is an instance of the
given class, or an instance of a subclass.

@yield The code to execute on a successful match. @yieldparam result [Cuprum::Result] The matched result.

# File lib/cuprum/matching.rb, line 27
def match(status, error: nil, value: nil, &block)
  validate_status!(status)
  validate_error!(error)
  validate_value!(value)

  clause  = MatchClause.new(block, error, status, value)
  clauses = match_clauses[status]
  index   = clauses.bsearch_index { |item| clause <= item } || -1

  # Clauses are sorted from most specific to least specific.
  clauses.insert(index, clause)
end
match_result(result:) click to toggle source

@private

# File lib/cuprum/matching.rb, line 41
def match_result(result:)
  status_clauses(result.status).find do |clause|
    clause.matches_result?(result: result)
  end
end
matches_result?(result:) click to toggle source

@private

# File lib/cuprum/matching.rb, line 48
def matches_result?(result:)
  status_clauses(result.status).reverse_each.any? do |clause|
    clause.matches_result?(result: result)
  end
end
matches_status?(error:, status:, value:) click to toggle source

@private

# File lib/cuprum/matching.rb, line 55
def matches_status?(error:, status:, value:)
  status_clauses(status).reverse_each.any? do |clause|
    clause.matches_details?(error: error, value: value)
  end
end

Protected Instance Methods

match_clauses() click to toggle source
# File lib/cuprum/matching.rb, line 63
def match_clauses
  @match_clauses ||= Hash.new { |hsh, key| hsh[key] = [] }
end

Private Instance Methods

status_clauses(status) click to toggle source
# File lib/cuprum/matching.rb, line 69
def status_clauses(status)
  ancestors
    .select { |ancestor| ancestor < Cuprum::Matching }
    .map { |ancestor| ancestor.match_clauses[status] }
    .reduce([], &:concat)
    .sort
end
validate_error!(error) click to toggle source
# File lib/cuprum/matching.rb, line 77
def validate_error!(error)
  return if error.nil? || error.is_a?(Module)

  raise ArgumentError,
    'error must be a Class or Module',
    caller(1..-1)
end
validate_status!(status) click to toggle source
# File lib/cuprum/matching.rb, line 85
def validate_status!(status)
  if status.nil? || status.to_s.empty?
    raise ArgumentError, "status can't be blank", caller(1..-1)
  end

  return if status.is_a?(Symbol)

  raise ArgumentError, 'status must be a Symbol', caller(1..-1)
end
validate_value!(value) click to toggle source
# File lib/cuprum/matching.rb, line 95
def validate_value!(value)
  return if value.nil? || value.is_a?(Module)

  raise ArgumentError,
    'value must be a Class or Module',
    caller(1..-1)
end