class Atacama::Transaction

Attributes

return_option[R]

Public Class Methods

add_step(params) click to toggle source

@private

# File lib/atacama/transaction.rb, line 71
def add_step(params)
  steps.push(Definition.call(params))
end
inherited(subclass) click to toggle source
Calls superclass method Atacama::Contract::inherited
# File lib/atacama/transaction.rb, line 20
def inherited(subclass)
  super(subclass)
  subclass.returns_option return_option, return_type
  steps.each do |step|
    subclass.step(step.name, with: step.with, yielding: step.yielding)
  end
end
new(context: {}, steps: {}) click to toggle source
Calls superclass method Atacama::Contract::new
# File lib/atacama/transaction.rb, line 81
def initialize(context: {}, steps: {})
  super(context: context)
  @overrides = steps
  @return_value = nil
end
returns_option(key, type = nil) click to toggle source

Return the value of a given Option in the pipeline.

@param key [Symbol] the option to read @param type [Dry::Type?] the type object to optionally check

# File lib/atacama/transaction.rb, line 32
def returns_option(key, type = nil)
  @return_option = key

  returns(
    Types.Instance(Result).constructor do |options|
      Atacama.check(type, options.value) do |e|
        raise ResultTypeMismatchError, Atacama.format_exception(self, e,
          "Option(#{key.inspect}) returned from the Transaction was the incorrect type.",
        )
      end

      options
    end
  )
end
step(name, with: nil, yielding: nil, &block) click to toggle source

Add a step to the processing queue.

@example

step :extract, with: UserParamsExtractor

@example a yielding step

step :wrap, with: Wrapper do
  step :extract, with: UserParamsExtractor
end

@param name [Symbol] a unique name for a step @param with [Contract, Proc, nil] the callable to execute

@yield The captured block allows defining of child steps. The wrapper must implement yield.

# File lib/atacama/transaction.rb, line 62
def step(name, with: nil, yielding: nil, &block)
  add_step({
    name: name,
    with: with,
    yielding: yielding || block_given? ? Class.new(self, &block) : nil
  })
end
steps() click to toggle source

@private

# File lib/atacama/transaction.rb, line 76
def steps
  @steps ||= []
end

Public Instance Methods

call() click to toggle source

Trigger execution of the Transaction pipeline.

@return [Atacama::Transaction::Result] final result with value

# File lib/atacama/transaction.rb, line 90
def call
  execute(self.class.steps)
  Result.call(value: return_value, transaction: context)
end

Private Instance Methods

evaluate(step) click to toggle source
# File lib/atacama/transaction.rb, line 107
def evaluate(step)
  if overridden?(step)
    evaluate_override(step)
  elsif step.method_invocation?
    evaluate_method(step)
  elsif step.proc_invocation?
    evaluate_proc(step)
  else
    evaluate_instance(step)
  end
end
evaluate_instance(step) click to toggle source
# File lib/atacama/transaction.rb, line 139
def evaluate_instance(step)
  step.with.new(context: context) \
      .call { execute(step.yielding.steps) }
      .tap { |result| step.with.validate_return(result) }
end
evaluate_method(step) click to toggle source
# File lib/atacama/transaction.rb, line 128
def evaluate_method(step)
  send(step.name) do
    execute(step.yielding.steps)
  end
end
evaluate_override(step) click to toggle source
# File lib/atacama/transaction.rb, line 123
def evaluate_override(step)
  callable = @overrides[step.name]
  instance_exec(&callable)
end
evaluate_proc(step) click to toggle source
# File lib/atacama/transaction.rb, line 134
def evaluate_proc(step)
  callable = step.with
  instance_exec(&callable)
end
execute(steps) click to toggle source
# File lib/atacama/transaction.rb, line 97
def execute(steps)
  steps.each do |step|
    break if @return_value
    evaluate(step).tap do |result|
      @return_value = result.value if result.is_a? Values::Return
      context.merge!(result.value) if result.is_a? Values::Option
    end
  end
end
overridden?(step) click to toggle source
# File lib/atacama/transaction.rb, line 119
def overridden?(step)
  @overrides.key?(step.name)
end
return_value() click to toggle source
# File lib/atacama/transaction.rb, line 145
def return_value
  @return_value || return_value_from_option || nil
end
return_value_from_option() click to toggle source
# File lib/atacama/transaction.rb, line 149
def return_value_from_option
  self.class.return_option && context[self.class.return_option]
end