class Flows::Contract::Either

Allows to combine two or more contracts with “or” logic.

First matching contract from provided list will be used.

@example

str_or_sym = Flows::Contract::Either.new(String, Symbol)

str_or_sym === 'AAA'
# => true

str_or_sym === :AAA
# => true

str_or_sym === 111
# => false

Public Class Methods

new(*contracts) click to toggle source

@param contracts [Array<Contract, Object>] contract list. Non-contract elements will be wrapped with {CaseEq}.

# File lib/flows/contract/either.rb, line 20
def initialize(*contracts)
  raise 'Contract list must not be empty' if contracts.length.zero?

  @contracts = contracts.map(&method(:to_contract))
end

Public Instance Methods

check!(other) click to toggle source

@see Contract#check!

# File lib/flows/contract/either.rb, line 27
def check!(other)
  errors = @contracts.each_with_object([]) do |con, errs|
    result = con.check(other)

    return true if result.ok?

    errs << result.error
  end

  raise Error.new(other, errors.join("\nOR "))
end
transform!(other) click to toggle source

@see Contract#transform!

# File lib/flows/contract/either.rb, line 40
def transform!(other)
  errors = @contracts.each_with_object([]) do |con, errs|
    result = con.transform(other)

    return result.unwrap if result.ok?

    errs << result.error
  end

  raise Error.new(other, errors.join("\nOR "))
end