class AASM::Core::Invoker

and array-based callbacks for different entities.
for invoking literal-based, proc-based, class-based
main invoker class which encapsulates the logic
#

def class_invoker

def class_invoker
  @class_invoker ||= Invokers::ClassInvoker
                     .new(subject, record, args)
                     .with_failures(failures)
end

def initialize(subject, record, args)

def initialize(subject, record, args)
  @subject = subject
  @record = record
  @args = args
  @options = {}
  @failures = []
  @default_return_value = DEFAULT_RETURN_VALUE
end

def invoke

rubocop:disable Metrics/AbcSize
def invoke
  return invoke_array if subject.is_a?(Array)
  return literal_invoker.invoke if literal_invoker.may_invoke?
  return proc_invoker.invoke if proc_invoker.may_invoke?
  return class_invoker.invoke if class_invoker.may_invoke?
  default_return_value
end

def invoke_array

def invoke_array
  return subject.all? { |item| sub_invoke(item) } if options[:guard]
  return subject.all? { |item| !sub_invoke(item) } if options[:unless]
  subject.map { |item| sub_invoke(item) }
end

def literal_invoker

def literal_invoker
  @literal_invoker ||= Invokers::LiteralInvoker
                       .new(subject, record, args)
                       .with_failures(failures)
end

def proc_invoker

def proc_invoker
  @proc_invoker ||= Invokers::ProcInvoker
                    .new(subject, record, args)
                    .with_failures(failures)
end

def sub_invoke(new_subject)

def sub_invoke(new_subject)
  self.class.new(new_subject, record, args)
      .with_failures(failures)
      .with_options(options)
      .invoke
end

def with_default_return_value(value)

def with_default_return_value(value)
  @default_return_value = value
  self
end

def with_failures(failures)

def with_failures(failures)
  @failures = failures
  self
end

def with_options(options)

def with_options(options)
  @options = options
  self
end