Class: BloodContracts::Core::Refined

Inherits:
Object
  • Object
show all
Defined in:
lib/blood_contracts/core/refined.rb

Overview

Base class for refinement type validations

Direct Known Subclasses

Anything, ContractFailure, Pipe, Sum, Tuple

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value, context: {}) ⇒ Refined

Refinement type constructor

Parameters:

  • value (Object)

    that Refined holds and should match

  • [Hash<Symbol, (Hash)

    a customizable set of options



76
77
78
79
80
# File 'lib/blood_contracts/core/refined.rb', line 76

def initialize(value, context: {}, **)
  @errors = []
  @context = context
  @value = value
end

Class Attribute Details

.failure_klassContractFailure

Accessor to define alternative to ContractFailure for #failure method to use

Returns:



53
54
55
# File 'lib/blood_contracts/core/refined.rb', line 53

def failure_klass
  @failure_klass
end

Instance Attribute Details

#contextHash<Symbol, Object>

Matching context, contains extra debugging and output data

Returns:

  • (Hash<Symbol, Object>)


63
64
65
# File 'lib/blood_contracts/core/refined.rb', line 63

def context
  @context
end

#errorsArray<Hash<Refined, String>> (readonly)

List of errors per type

Returns:



69
70
71
# File 'lib/blood_contracts/core/refined.rb', line 69

def errors
  @errors
end

Class Method Details

.===(object) ⇒ Object

Override of case equality operator, to handle Tuple correctly



43
44
45
46
# File 'lib/blood_contracts/core/refined.rb', line 43

def ===(object)
  return object.attributes.values.any?(self) if object.is_a?(Tuple)
  super
end

.and_then(other_type) ⇒ BC::Pipe Also known as: >

Compose types in a Pipe check Pipe passes data from type to type sequentially

Returns:



22
23
24
# File 'lib/blood_contracts/core/refined.rb', line 22

def and_then(other_type)
  BC::Pipe.new(self, other_type)
end

.callRefined

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)

Returns:



40
41
42
43
44
45
# File 'lib/blood_contracts/core/refined.rb', line 40

def match(*args, **kwargs, &block)
  instance = new(*args, **kwargs)
  match = instance.match(&block) || instance
  instance.instance_variable_set(:@match, match)
  match
end

.inherited(new_klass) ⇒ Object



54
55
56
# File 'lib/blood_contracts/core/refined.rb', line 54

def inherited(new_klass)
  new_klass.failure_klass ||= ContractFailure
end

.match(*args, **kwargs, &block) ⇒ Refined

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)

Returns:



34
35
36
37
38
39
# 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

.or_a(other_type) ⇒ BC::Sum Also known as: or_an, |

Compose types in a Sum check Sum passes data from type to type in parallel, only one type have to match

Returns:



11
12
13
# File 'lib/blood_contracts/core/refined.rb', line 11

def or_a(other_type)
  BC::Sum.new(self, other_type)
end

Instance Method Details

#invalid?Boolean

Checks whether the data matches the expectations or not (just negation of #valid?)

Returns:

  • (Boolean)


109
110
111
# File 'lib/blood_contracts/core/refined.rb', line 109

def invalid?
  !valid?
end

#unpackObject

Unpack the original value from the refinement type

Returns:

  • (Object)


117
118
119
# File 'lib/blood_contracts/core/refined.rb', line 117

def unpack
  @unpack ||= mapped
end

#valid?Boolean

Checks whether the data matches the expectations or not

Returns:

  • (Boolean)


100
101
102
# File 'lib/blood_contracts/core/refined.rb', line 100

def valid?
  @match.errors.empty?
end