module Eco module API module UseCases class UseCaseIO TYPES = [:import, :filter, :transform, :sync, :export] ALL_PARAMS = [:input, :people, :session, :options] TYPE_PARAMS = { import: [:input, :session], filter: [:people, :session, :options], transform: [:people, :session], export: [:people, :session, :options] } attr_reader :usecase attr_reader :input, :people, :session, :options attr_accessor :output class << self def valid_type?(type) TYPES.include?(type) end def type_params(type) raise "Invalid type '#{type.to_s}'" if !valid_type?(type) TYPE_PARAMS[type] end end def initialize(input: nil, people: nil, session:, options: {}, usecase:) self.usecase = usecase @output = nil validate_args(input: input, people: people, session: session, options: options) @input = input @people = people @session = session @options = options end def usecase=(value) raise "It should be a UseCase. Given: #{value}" if !value.is_a?(UseCase) @usecase = value end def type @usecase.type end def params(input: nil, people: nil, session: nil, options: {}, keyed: false) opts = @options.merge(options&.dup || {}) input ||= @input people ||= @people session ||= @session kargs = {} kargs.merge!(input: input) if input_required? kargs.merge!(people: people) if people_required? kargs.merge!(session: session, options: opts, usecase: usecase) keyed ? kargs : kargs.values end def chain(usecase:) raise "It should be a UseCase. Given: #{usecase}" if !usecase.is_a?(UseCase) kargs = params(keyed: true) # TODO: review chaining framework (redirection should depend on self.type as well) case usecase.type when :import kargs[:input] = output when :filter kargs[:people] = output when :transform, :sync, :export # no redirections => should it redirect the input? end self.class.new(kargs) end protected private def validate_args(input:, people:, session:, options:) case when !session.is_a?(Eco::API::Session) raise "A UseCase needs a Session object. Given: #{session}" when input_required? && !input raise "UseCase of type '#{type}' requires a valid input. None given" when people_required? && !people.is_a?(Eco::API::Organization::People) raise "UseCase of type '#{type}' requires a People object. Given: #{people}" when !options || (options && !options.is_a?(Hash)) raise "To inject dependencies via ':options' it should be a Hash object. Given: #{options}" when options_required? && !options raise "UseCase of type '#{type}' requires a Hash ':options' object." end true end def input_required? [:import, :sync].include?(type) end def people_required? [:filter, :transform, :sync, :export].include?(type) end def options_required? [:filter].include?(type) end end end end end