module Slayer class Command class << self def call(*args, **kwargs, &block) instance = self.new res = __get_result(instance, *args, **kwargs, &block) handle_match(res, instance, block) if block_given? raise CommandNotImplementedError unless res.is_a? Result return res end ruby2_keywords :call if respond_to?(:ruby2_keywords, true) def ok(value: nil, status: :default, message: nil) Result.new(value, status, message) end def err(value: nil, status: :default, message: nil) ok(value: value, status: status, message: message).fail end def err!(value: nil, status: :default, message: nil) unless ENV['SUPPRESS_SLAYER_WARNINGS'] warn '[DEPRECATION] `err!` is deprecated. Please use `return err` instead.' end raise ResultFailureError, err(value: value, status: status, message: message) end def __get_result(instance, *args, **kwargs, &block) res = nil begin res = instance.call(*args, **kwargs, &block) rescue ResultFailureError => e res = e.result end res end private def handle_match(res, instance, block) matcher = Slayer::ResultMatcher.new(res, instance) block.call(matcher) # raise error if not all defaults were handled unless matcher.handled_defaults? raise(ResultNotHandledError, 'The pass or fail condition of a result was not handled') end begin matcher.execute_matching_block ensure matcher.execute_ensure_block end end end def ok(*args) self.class.ok(*args) end ruby2_keywords :ok if respond_to?(:ruby2_keywords, true) def err(*args) self.class.err(*args) end ruby2_keywords :err if respond_to?(:ruby2_keywords, true) def err!(*args) self.class.err!(*args) end ruby2_keywords :err! if respond_to?(:ruby2_keywords, true) def try!(value: nil, status: nil, message: nil) r = yield err!(value: value, status: status || :default, message: message) unless r.is_a?(Result) return r.value if r.ok? err!(value: value || r.value, status: status || r.status, message: message || r.message) end def call raise NotImplementedError, 'Commands must define method `#call`.' end end end