module Eco module API class UseCases class UseCase < BaseCase @types = BaseCase.types attr_reader :name, :type, :times_launched attr_reader :options def initialize(name, type:, root:, &block) invalid_type_err = InvalidType.new( "Invalid type for '#{name}'.", type: type, types: self.class.types ) raise invalid_type_err unless self.class.valid_type?(type) super() self.root = root @callback = block @name = name @type = type @times_launched = 0 end def source_object return nil unless callback_from_loader? callback_self end def chainer # @todo: root is a Eco::API::UseCases that will not point to this new case. # => Moreover, the name and type will be the same as self Eco::API::UseCases::UseCaseChain.new(usecase: self, root: @root) end def root=(value) msg = "Root should be a Eco::API::UseCases. Given: #{value.class}" raise ArgumentError, msg unless value.is_a?(Eco::API::UseCases) @root = value end # Actual launch of the usecase # @param io [Eco::API::UseCases::BaseIO] an input/output helper with the necessary parameters. # @param kargs [Hash] hash with symbol keys. # @option kargs [Eco::API::Common::People::Entries, Eco::API::Organization::People] :input # the input data of reference. # @option kargs [Eco::API::Organization::People] :people object. # @option kargs [Eco::API:Session] :session # @option kargs [Hash] :options hash with symbol keys (i.e. behaviour modifiers, cli trackers, filters, etc.) # @return [Eco::API::UseCases::UseCaseIO] an io with the result in output def launch(io: nil, **kargs) params = io&.params(keyed: true, all: true) || {} kargs = params.merge(kargs).merge(usecase: self) UseCaseIO.new(**kargs).tap do |uio| @options = uio.options uio.session.logger.debug("#{self.class}: going to process '#{name}'") set_session_n_options(uio) if callback_from_loader? uio.output = callback.call(*uio.params) @times_launched += 1 end end # When it was defined from a Loader class it retrieves the object. # @return [Eco::API::Common::Loaders::Base, NilClass] def classed_definition callback_self if callback_from_loader? end protected attr_reader :callback def callback_self eval("self", callback.binding, __FILE__, __LINE__) end def callback_from_loader? callback_self.is_a?(Eco::API::Common::Loaders::Base) end # Set the instance variables `@session` and `@options` # in the use case definition # @note this only works when the use case was defined # via an children class of `Eco::API::Common::Loaders::Base` def set_session_n_options(uio) # rubocop:disable Naming/AccessorMethodName return false unless callback_from_loader? opts = uio.options || @options sess = uio.session peo = uio.people ent = uio.input use_case_self = self callback_self.instance_eval do @session = sess @options = opts if peo @people = peo singleton_class.attr_reader(:people) unless respond_to?(:people) end if ent # entries/input @input = ent singleton_class.attr_reader(:input) unless respond_to?(:input) # Below problematic code... usage has cases where entries = (gets assigned) # @entries = ent # singleton_class.attr_reader(:entries) unless respond_to?(:entries) end # `self` is the use case itself (when used the Loader) next unless is_a?(Eco::API::Common::Loaders::CaseBase) @usecase = use_case_self singleton_class.attr_reader(:usecase) unless respond_to?(:usecase) end true end end end end end