lib/simple_service.rb
require 'simple_service/result'
require 'simple_service/configuration'
require 'simple_service/version'
module SimpleService
def self.included(klass)
klass.extend ClassMethods
klass.include InstanceMethods
self.configure
end
class << self
attr_accessor :configuration
end
def self.configure
self.configuration ||= Configuration.new
yield(configuration) if block_given?
end
module ClassMethods
def command(command_name)
@commands ||= []
@commands << command_name
end
def commands(*args)
@commands ||= []
@commands += args
end
def call(kwargs={})
service = self.new
# if kwargs is a result obj then pull its hash out via #value
service.result.value = kwargs.is_a?(Result) ? kwargs.value : kwargs
get_commands(service).each do |cmnd|
service = execute_command(cmnd, service)
break if service.result.failure?
end
service.result
end
def get_commands(service)
if !@commands.nil? && @commands.any?
@commands
elsif service.respond_to?(:call)
[:call]
else
raise "No commands defined for #{self.to_s}, define at least one " \
'command or implement the #call method'
end
end
def execute_command(cmnd, service)
service.current_command = cmnd
command_output = if cmnd.is_a?(Class)
cmnd.call(service.result.value)
elsif cmnd.is_a?(Symbol)
if service.method(cmnd).arity.zero?
service.public_send(cmnd)
else
service.public_send(cmnd, **service.result.value)
end
end
if command_output.is_a?(Result)
service.result.append_result(command_output)
end
service
end
end
module InstanceMethods
def result
@result ||= Result.new
end
def current_command
@current_command
end
def current_command=(cmnd)
@current_command = cmnd
end
def commands
self.class.instance_variable_get('@commands') || []
end
def success(result_value)
result.success!(self.class, current_command, result_value)
end
def failure(result_value)
result.failure!(self.class, current_command, result_value)
end
end
end