class BloodContracts::Core::Or
Meta refinement type, represents sum of several refinement types
Attributes
Represents list of types in the sum
@return [Array<Refined>]
Public Class Methods
Inheritance handler:
-
adds current
sum_of
to child -
sets default value for failure_klass
BloodContracts::Core::Refined::inherited
# File lib/blood_contracts/core/sum.rb, line 70 def inherited(new_klass) new_klass.instance_variable_set(:@sum_of, sum_of) new_klass.failure_klass ||= SumContractFailure super end
# File lib/blood_contracts/core/sum.rb, line 26 def inspect; super; end
Metaprogramming around constructor Turns input into Sum
meta-class
@param (see initialze)
rubocop:disable Style/SingleLineMethods
BloodContracts::Core::Refined::new
# File lib/blood_contracts/core/sum.rb, line 19 def new(*args) return super(*args) if @finalized new_sum = args.reduce([]) do |acc, type| type.respond_to?(:sum_of) ? acc + type.sum_of.to_a : acc << type end sum = Class.new(self) { def inspect; super; end } finalize!(sum, new_sum) sum end
Compose types in a Sum
check Sum
passes data from type to type in parallel, only one type have to match
@return [BC::Sum]
# File lib/blood_contracts/core/sum.rb, line 37 def or_a(other_type) sum = Class.new(self) { def inspect; super; end } new_sum = sum_of.to_a if other_type.respond_to?(:sum_of) new_sum += other_type.sum_of.to_a else new_sum << other_type end finalize!(sum, new_sum) sum end
Private Class Methods
@private
# File lib/blood_contracts/core/sum.rb, line 53 def finalize!(new_class, new_sum) new_class.instance_variable_set(:@sum_of, ::Set.new(new_sum.compact)) new_class.instance_variable_set(:@finalized, true) end
Public Instance Methods
List of errors per type during the matching
@return [Array<Hash<Refined, String>>]
# File lib/blood_contracts/core/sum.rb, line 98 def errors @context[:errors] end
The type which is the result of data matching process For Tuple
it verifies that all the attributes data are valid types
@return [BC::Refined]
# File lib/blood_contracts/core/sum.rb, line 82 def match @or_matches = self.class.sum_of.map do |type| type.match(@value, context: @context.dup) end if (match = @or_matches.find(&:valid?)) match else @or_matches.dup.unshift(failure).reduce(:merge!) end end
Private Instance Methods
Helper to build a ContractFailure
with shared context
@return [ContractFailure]
# File lib/blood_contracts/core/sum.rb, line 106 def failure(*) sum_context = @or_matches.map(&:context) @context[:sum_failure_contexts] = sum_context self.class.failure_klass.new(context: @context) end
@private
# File lib/blood_contracts/core/sum.rb, line 113 def inspect "#<sum #{self.class.name} is #{self.class.sum_of.to_a.join(' or ')}"\ " (value=#{@value})>" end