class BloodContracts::Core::Refined
Base class for refinement type validations
Attributes
Accessor to define alternative to ContractFailure
for failure
method to use
@return [ContractFailure]
Matching context, contains extra debugging and output data
@return [Hash<Symbol, Object>]
List of errors per type
@return [Array<Hash<Refined, String>>]
Public Class Methods
Override of case equality operator, to handle Tuple
correctly
# File lib/blood_contracts/core/refined.rb, line 43 def ===(object) return object.attributes.values.any?(self) if object.is_a?(Tuple) super end
Compose types in a Pipe
check Pipe
passes data from type to type sequentially
@return [BC::Pipe]
# File lib/blood_contracts/core/refined.rb, line 22 def and_then(other_type) BC::Pipe.new(self, other_type) end
# File lib/blood_contracts/core/refined.rb, line 54 def inherited(new_klass) new_klass.failure_klass ||= ContractFailure end
Validate data over refinement type conditions Result is ALWAYS a Refined
, but in cases when validation failed, we return ContractFailure
ancestor or ContractFailure
itself (which is Refined
anyway)
@return [Refined]
# File lib/blood_contracts/core/refined.rb, line 34 def match(*args, **kwargs, &block) instance = new(*args, **kwargs) match = instance.match(&block) || instance instance.instance_variable_set(:@match, match) match end
Refinement type constructor
@param [Object] value that Refined
holds and should match @option [Hash<Symbol, Object>] context to share between types
# File lib/blood_contracts/core/refined.rb, line 76 def initialize(value, context: {}, **) @errors = [] @context = context @value = value end
Public Instance Methods
Checks whether the data matches the expectations or not (just negation of valid?
)
@return [Boolean]
# File lib/blood_contracts/core/refined.rb, line 109 def invalid? !valid? end
Unpack the original value from the refinement type
@return [Object]
# File lib/blood_contracts/core/refined.rb, line 117 def unpack @unpack ||= mapped end
Checks whether the data matches the expectations or not
@return [Boolean]
# File lib/blood_contracts/core/refined.rb, line 100 def valid? @match.errors.empty? end
Protected Instance Methods
Helper to build a ContractFailure
with shared context
@return [ContractFailure]
# File lib/blood_contracts/core/refined.rb, line 127 def failure(error = nil, errors: @errors, **kwargs) error ||= kwargs unless kwargs.empty? errors << error if error self.class.failure_klass.new( { self.class => errors }, context: @context ) end
Transform the value before unpacking
# File lib/blood_contracts/core/refined.rb, line 92 def mapped value end
The type which is the result of data matching process
@return [BC::Refined]
# File lib/blood_contracts/core/refined.rb, line 86 def match raise NotImplementedError end
Turn data into refinement type if it is not already
@return [Object]
# File lib/blood_contracts/core/refined.rb, line 156 def refine_value(value) refined?(value) ? value.match : Anything.new(value) end
# File lib/blood_contracts/core/refined.rb, line 142 def refined?(object) object.class < BloodContracts::Core::Refined end
Turn value into raw data if it is refined
@return [Object]
# File lib/blood_contracts/core/refined.rb, line 164 def unpack_refined(value) refined?(value) ? value.unpack : value end
Helper to turn value into raw data
@return [Object]
# File lib/blood_contracts/core/refined.rb, line 138 def value unpack_refined(@value) end