Sha256: c7ae5af25309a40aeb1ef57112bf54f0aff78b6193524eeedc930fe5afefa64b

Contents?: true

Size: 1.93 KB

Versions: 4

Compression:

Stored size: 1.93 KB

Contents

# frozen_string_literal: true

module Micro
  module Cases
    class Flow
      class InvalidUseCases < ArgumentError
        def initialize; super('argument must be a collection of `Micro::Case` classes'.freeze); end
      end

      attr_reader :use_cases

      def self.map_use_cases(arg)
        return arg.use_cases if arg.is_a?(Flow)

        Array(arg)
      end

      def self.build(args)
        use_cases = Array(args).flat_map { |arg| map_use_cases(arg) }

        raise InvalidUseCases if use_cases.any? { |klass| !(klass < ::Micro::Case) }

        new(use_cases)
      end

      def initialize(use_cases)
        @use_cases = use_cases
        @first_use_case = use_cases[0]
        @next_use_cases = use_cases[1..-1]
      end

      def call!(input:, result:)
        first_result = __next_use_case_result(@first_use_case, result, input)

        return first_result if @next_use_cases.empty?

        __next_use_cases_result(first_result)
      end

      def call(input = Kind::Empty::HASH)
        call!(input: input, result: Case::Result.new)
      end

      alias __call__ call

      def to_proc
        Proc.new { |arg| call(arg) }
      end

      def then(use_case = nil, &block)
        can_yield_self = respond_to?(:yield_self)

        if block
          raise Error::InvalidInvocationOfTheThenMethod if use_case
          raise NotImplementedError if !can_yield_self

          yield_self(&block)
        else
          return yield_self if !use_case && can_yield_self

          self.call.then(use_case)
        end
      end

      private

        def __next_use_case_result(use_case, result, input)
          use_case.__new__(result, input).__call__
        end

        def __next_use_cases_result(first_result)
          @next_use_cases.reduce(first_result) do |result, use_case|
            break result if result.failure?

            __next_use_case_result(use_case, result, result.data)
          end
        end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
u-case-3.0.0.rc9 lib/micro/cases/flow.rb
u-case-3.0.0.rc8 lib/micro/cases/flow.rb
u-case-3.0.0.rc7 lib/micro/cases/flow.rb
u-case-3.0.0.rc6 lib/micro/cases/flow.rb