lib/micro/case.rb in u-case-2.6.0 vs lib/micro/case.rb in u-case-3.0.0.rc1

- old
+ new

@@ -1,42 +1,50 @@ # frozen_string_literal: true require 'kind' require 'micro/attributes' +require 'micro/case/version' + module Micro class Case - require 'micro/case/version' require 'micro/case/utils' require 'micro/case/result' require 'micro/case/error' require 'micro/case/safe' require 'micro/case/strict' - require 'micro/case/flow/reducer' - require 'micro/case/flow' - require 'micro/case/safe/flow' + require 'micro/cases' + include Micro::Attributes.without(:strict_initialize) + def self.call(options = {}) + new(options).call + end + def self.to_proc Proc.new { |arg| call(arg) } end - def self.Flow(args) - Flow::Reducer.build(Array(args)) + def self.call! + self end - def self.>>(use_case) - Flow([self, use_case]) + def self.flow(*args) + @__flow_use_cases = args end - def self.&(use_case) - Safe::Flow([self, use_case]) - end + def self.inherited(subclass) + subclass.attributes(self.attributes_data({})) + subclass.extend ::Micro::Attributes.const_get('Macros::ForSubclasses'.freeze) - def self.call(options = {}) - new(options).call + if self.send(:__flow_use_cases) && !subclass.name.to_s.end_with?(FLOW_STEP) + raise "Wooo, you can't do this! Inherits from a use case which has an inner flow violates "\ + "one of the project principles: Solve complex business logic, by allowing the composition of use cases. "\ + "Instead of doing this, declare a new class/constant with the steps needed.\n\n"\ + "Related issue: https://github.com/serradura/u-case/issues/19\n" + end end def self.__new__(result, arg) instance = new(arg) instance.__set_result__(result) @@ -48,42 +56,36 @@ arg.is_a?(Hash) ? result.__set_transitions_accessible_attributes__(arg) : arg __new__(result, input).call end - FLOW_STEP = 'Flow_Step'.freeze + def self.__flow_builder + Cases::Flow + end - private_constant :FLOW_STEP + def self.__flow_get + return @__flow if defined?(@__flow) + end - def self.__call! - return const_get(FLOW_STEP) if const_defined?(FLOW_STEP, false) + private_class_method def self.__flow_set(args) + return if __flow_get - class_eval("class #{FLOW_STEP} < #{self.name}; private def __call; __call_use_case; end; end") - end + def self.use_cases; __flow_get.use_cases; end - def self.call! - self + self.class_eval('def use_cases; self.class.use_cases; end') + + @__flow = __flow_builder.build(args) end - def self.inherited(subclass) - subclass.attributes(self.attributes_data({})) - subclass.extend ::Micro::Attributes.const_get('Macros::ForSubclasses'.freeze) + FLOW_STEP = 'Flow_Step'.freeze - if self.send(:__flow_use_cases) && !subclass.name.to_s.end_with?(FLOW_STEP) - raise "Wooo, you can't do this! Inherits from a use case which has an inner flow violates "\ - "one of the project principles: Solve complex business logic, by allowing the composition of use cases. "\ - "Instead of doing this, declare a new class/constant with the steps needed.\n\n"\ - "Related issue: https://github.com/serradura/u-case/issues/19\n" - end - end + private_constant :FLOW_STEP - def self.__flow_reducer - Flow::Reducer - end + def self.__call! + return const_get(FLOW_STEP) if const_defined?(FLOW_STEP, false) - def self.__flow_get - return @__flow if defined?(@__flow) + class_eval("class #{FLOW_STEP} < #{self.name}; private def __call; __call_use_case; end; end") end private_class_method def self.__flow_use_cases return @__flow_use_cases if defined?(@__flow_use_cases) end @@ -91,32 +93,14 @@ private_class_method def self.__flow_use_cases_get Array(__flow_use_cases) .map { |use_case| use_case == self ? self.__call! : use_case } end - private_class_method def self.__flow_use_cases_set(args) - @__flow_use_cases = args - end - - private_class_method def self.__flow_set(args) - return if __flow_get - - def self.use_cases; __flow_get.use_cases; end - - self.class_eval('def use_cases; self.class.use_cases; end') - - @__flow = __flow_reducer.build(args) - end - def self.__flow_set! __flow_set(__flow_use_cases_get) if !__flow_get && __flow_use_cases end - def self.flow(*args) - __flow_use_cases_set(args) - end - def initialize(input) __setup_use_case(input) end def call! @@ -164,35 +148,38 @@ def __call_use_case_flow self.class.__flow_get.call(@__input) end - def Success(arg = :ok) - value, type = block_given? ? [yield, arg] : [arg, :ok] + def Success(type = :ok, result: nil) + value = result || type - __get_result_with(true, value, type) + __get_result(true, value, type) end - def Failure(arg = :error) - value = block_given? ? yield : arg - type = __map_failure_type(value, block_given? ? arg : :error) + MapFailureType = -> (value, type) do + return type if type != :error + return value if value.is_a?(Symbol) + return :exception if value.is_a?(Exception) - __get_result_with(false, value, type) + type end - def __map_failure_type(arg, type) - return type if type != :error - return arg if arg.is_a?(Symbol) - return :exception if arg.is_a?(Exception) + def Failure(type = :error, result: nil) + value = result || type - type + type = MapFailureType.call(value, type) + + __get_result(false, value, type) end - def __get_result__ + def __result__ @__result ||= Result.new end - def __get_result_with(is_success, value, type) - __get_result__.__set__(is_success, value, type, self) + def __get_result(is_success, value, type) + __result__.__set__(is_success, value, type, self) end + + private_constant :MapFailureType end end