Sha256: 5e7df0d073a5811960d6c5b7ac324dd3e9bf381e58c942a092e20d983621daa2

Contents?: true

Size: 1.6 KB

Versions: 1

Compression:

Stored size: 1.6 KB

Contents

# frozen_string_literal: true

module Course
  class Operation
    class << self
      def call(*input, &block)
        new.call(*input, &block)
      end

      def step(name = nil, **options, &block)
        steps << Course::Step.new(name, block, **options)
      end

      def steps
        @steps ||= []
      end

      def inherited(child)
        child.instance_variable_set('@steps', @steps.clone)
      end
    end

    def call(*input, &block)
      execute_steps(*input, &block)
      return yield result if block_given?
      result
    end

    def result
      Course::Result.new(output: @output, failure: @failure)
    end

    private

    def fail(type, data = nil)
      raise FailureError, Failure.new(type, data)
    end

    def execute_steps(*input)
      @output = self.class.steps.inject(input, &method(:execute))
    rescue FailureError => e
      @failure = e.failure
    end

    def execute(next_input, step)
      if step.method?
        execute_step(method(step.target), *next_input)
      elsif step.block?
        execute_step(step.block, *next_input)
      else
        execute_operation(step.target, *next_input)
      end
    end

    def execute_step(next_step, *input)
      if input.is_a?(Array) && (next_step.arity == input.count || next_step.arity == -1)
        next_step.call(*input)
      else
        next_step.call(input)
      end
    end

    def execute_operation(klass, *input)
      klass.call(*input) do |res|
        res.on_success do |output|
          return output
        end
        res.on_fail do |err|
          raise FailureError, err
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
course-0.2.1 lib/course/operation.rb