class Flows::Contract::Tuple
Makes a contract fixed size array.
Underlying contracts' transformations are applied.
@example
name_age = Flows::Contract::Tuple.new(String, Integer) name_age === ['Roman', 29] # => true name_age === [10, 20] # => false
Constants
- ARRAY_CONTRACT
Public Class Methods
new(*contracts)
click to toggle source
@param contracts [Array<Contract, Object>] contract list. {CaseEq} applied to non-contract values.
# File lib/flows/contract/tuple.rb, line 19 def initialize(*contracts) @contracts = contracts.map(&method(:to_contract)) end
Public Instance Methods
check!(other)
click to toggle source
@see Contract#check!
# File lib/flows/contract/tuple.rb, line 24 def check!(other) ARRAY_CONTRACT.check!(other) check_length(other) errors = collect_errors(other) return true if errors.empty? raise Error.new(other, render_errors(other, errors)) end
transform!(other)
click to toggle source
@see Contract#transform!
# File lib/flows/contract/tuple.rb, line 35 def transform!(other) check!(other) other.map.with_index do |elem, index| @contracts[index].transform!(elem) end end
Private Instance Methods
check_length(other)
click to toggle source
# File lib/flows/contract/tuple.rb, line 45 def check_length(other) return if other.length == @contracts.length raise Error.new(other, "array length mismatch: must be #{@contracts.length}, got #{other.length}") end
collect_errors(other)
click to toggle source
# File lib/flows/contract/tuple.rb, line 51 def collect_errors(other) other.each_with_object({}).with_index do |(elem, errors), index| result = @contracts[index].check(elem) errors[index] = result.error if result.err? end end
render_errors(other, errors)
click to toggle source
# File lib/flows/contract/tuple.rb, line 59 def render_errors(other, errors) errors.map do |index, err| elem = other[index] merge_nested_errors( "array element `#{elem.inspect}` with index #{index} is invalid:", err ) end.join("\n") end