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