module Flows::Plugin::OutputContract

Allows to make a contract check and transformation for `#call` method execution in any class.

Plugin applies a wrapper to a `#call` instance method. This wrapper will do the following:

Plugin provides DSL to express expected result statuses and assigned contracts. Contracts definition reuses {Contract.make} to execute block and get a contract.

@example with one possible output contract

class DoJob
  include Flows::Result::Helpers
  include Flows::Plugin::OutputContract

  success_with :ok do
    Integer
  end

  def call(a, b)
    ok_data(a + b)
  end
end

DoJob.new.call(1, 2).unwrap
# => 3

DoJob.new.call('a', 'b')
# Flows::Contract::Error exception raised

@example with multiple contracts

class DoJob
  include Flows::Result::Helpers
  include Flows::Plugin::OutputContract

  success_with :int_sum do
    Integer
  end

  success_with :float_sum do
    Float
  end

  failure_with :err do
    hash_of(
      key: Symbol,
      msg: String
    )
  end

  def call(a, b)
    if a.is_a?(Float) || b.is_a?(Float)
      ok_data(a + b, status: :float_sum)
    elsif a.is_a?(Integer) && b.is_a?(Integer)
      ok_data(a + b, status: :int_sum)
    else
      err(key: :unexpected_type, msg: "Unexpected argument types")
    end
  end
end

Public Class Methods

included(mod) click to toggle source

@api private

# File lib/flows/plugin/output_contract.rb, line 79
def self.included(mod)
  mod.extend(DSL)
  mod.prepend(Wrapper)
end