lib/plumb/tuple_class.rb
# frozen_string_literal: true require 'plumb/composable' module Plumb class TupleClass include Composable attr_reader :children def initialize(*children) @children = children.map { |t| Composable.wrap(t) }.freeze freeze end def of(*types) self.class.new(*types) end alias [] of def call(result) return result.invalid(errors: 'must be an Array') unless result.value.is_a?(::Array) return result.invalid(errors: 'must have the same size') unless result.value.size == @children.size errors = {} values = @children.map.with_index do |type, idx| val = result.value[idx] r = type.resolve(val) errors[idx] = ["expected #{type.inspect}, got #{val.inspect}", r.errors].flatten unless r.valid? r.value end return result.valid(values) unless errors.any? result.invalid(errors:) end private def _inspect "Tuple[#{@children.map(&:inspect).join(', ')}]" end end end