lib/eco/api/usecases/use_case.rb in eco-helpers-0.6.17 vs lib/eco/api/usecases/use_case.rb in eco-helpers-0.7.1

- old
+ new

@@ -8,167 +8,50 @@ import: [:input, :session], filter: [:people, :session, :options], transform: [:people, :session], export: [:people, :session, :options] } - MAX_CHAINS = 70 - @@num_chains = 0 - attr_reader :name, :type, :times_used + attr_reader :name, :type, :times_launched + 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(name, type:, root:, options: {}, &block) + raise "Undefine usecase type #{type}. Please, use any of #{TYPES}" unless self.class.valid_type?(type) self.root = root - @case = block - @name = name - @type = type - @options = options - - @chains = [] - @resolved_chains = nil - @times_used = 0 + @case = block + @name = name + @type = type + @options = options + @times_launched = 0 end def root=(value) - raise "You cannot change root UseGroup once the chains have been resolved" if @resolved_chains raise "Root should be a UseGroup. Given: #{value}" if !value.is_a?(UseGroup) @root = value end - def use(preserve_chains: false, recursive: false) - newcase = UseCase.new(@name, type: @type, root: @root, options: @options, &@case) - if preserve_chains - chain_use = {preserve_chains: recursive, recursive: recursive} - @chains = @chains.map do |usecase| - if usecase.respond_to? :call - Proc.new do |usegroup| - usecase = usecase.call(usegroup) - usecase.use(chain_use).chain_to(newcase) - usecase - end - else - usecase.use(chain_use).chain_to(newcase) - usecase - end - end - end - newcase - end + def launch(input: nil, people: nil, session:, options: {}) + data = UseCaseIO.new(usecase: self, input: input, people: people, session: session, options: options) - def process(input: nil, people: nil, session:, options: {}) - raise "This case has been already used. To create multiple instances of same use case, use 'use' method" if @done - validate_args(input: input, people: people, session: session, options: options) + data.output = @case.call(data.params) + @times_launched += 1 - opts = options&.dup - opts = @options.merge(opts || {}) - - case @type - when :import - out = input = @case.call(input, session, opts) - when :filter - out = people = @case.call(people, session, opts) - when :transform - out = jobs = into_a(@case.call(people, session, opts)) - when :sync - out = jobs = into_a(@case.call(input, people, session, opts)) - when :export - out = stat = @case.call(people, session, opts) - end - @times_used += 1 - data_model = { self => { - data: { input: input, people: people, session: session, options: opts, output: out } + io: data } } - post_usecase(data_model) - end - - def chain(usecase = nil) - @@num_chains += 1 - raise "Reached maximum number of chained use cases (#{MAX_CHAINS}). Looks like a recursive cyclic chain 'use'" if @@num_chains >= MAX_CHAINS - raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase) - raise "Missuse. Please use either parameter or block but not both" if block_given? && usecase - usecase = block_given?? Proc.new : usecase - @chains.push(usecase) - self - end - - def self.valid_type(type) - TYPES.include?(type) - end - - def self.type_params(type) - raise "Invalid type '#{type.to_s}'" if !valid_type?(type) - TYPE_PARAMS[type] - end - - protected - - def chain_to(usecase) - raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase) - usecase.chain(self) - end - - def resolved_chains(use_group = nil) - return @resolved_chains if @resolved_chains - raise "Only UseGroup object can resolve chains. Given: #{use_group} " if use_group && !use_group.is_a?(UseGroup) - - use_group = use_group || @root - @resolved_chains = @chains.map do |usecase| - usecase = usecase.call(use_group) if usecase.respond_to? :call - raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase) - usecase.resolved_chains(use_group) - usecase - end - @resolved_chains - end - - private - - def post_usecase(data_model) - return data_model if resolved_chains.empty? - data_model[self][:chains] = {} unless data_model[self][:chains] - - resolved_chains.each do |usecase| - # chained cases use same params as parent case (out of simplicity) - params = data_model[self][:data].slice(*ALL_PARAMS) #TYPE_PARAMS[usecase.type]) - data_model[self][:chains].merge(usecase.process(params)) - end - data_model - end - - 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.to_s}' requires a valid input. None given" - when people_required? && !people.is_a?(Eco::API::Organization::People) - raise "UseCase of type '#{@type.to_s}' 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.to_s}' 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 - - def into_a(value) - value = [].push(value) unless value.is_a?(Array) - value end end end