Class: BloodContracts::Core::Tuple
- Defined in:
- lib/blood_contracts/core/tuple.rb
Overview
Meta refinement type, represents product of several refinement types
Class Attribute Summary collapse
-
.attributes ⇒ Array<Refined>
readonly
List of types in the Tuple.
-
.failure_klass ⇒ ContractFailure
Accessor to define alternative to ContractFailure for #failure method to use.
-
.names ⇒ Array<Symbol>
readonly
Names of attributes.
Instance Attribute Summary collapse
-
#values ⇒ Array<Object>
readonly
List of values in Tuple.
Attributes inherited from Refined
Class Method Summary collapse
-
.attribute(name, type = nil, &block) ⇒ Object
Helper which registers attribute in the Tuple, also defines a reader.
- .inherited(new_klass) ⇒ Object
-
.new(*args, **kwargs, &block) ⇒ Object
Metaprogramming around constructor Turns input into Tuple meta-class.
Instance Method Summary collapse
-
#attribute_errors ⇒ Hash<String, ContractFailure>
Subset of attributes which are invalid.
-
#attributes ⇒ Hash<String, Refined>
Hash of attributes (name & type pairs).
-
#initialize(*values, context: {}) ⇒ Tuple
constructor
Tuple constructor, builds Tuple from list of data values.
-
#mapped ⇒ Array<Object>
Turns match into array of unpacked values.
-
#match ⇒ BC::Refined
The type which is the result of data matching process For Tuple it verifies that all the attributes data are valid types.
-
#unpack_h ⇒ Hash<String, ContractFailure>
(also: #to_hash, #to_h, #unpack_attributes)
Unpacked value in form of a hash per attribute.
Methods inherited from Refined
===, and_then, call, #invalid?, match, or_a, #unpack, #valid?
Constructor Details
#initialize(*values, context: {}) ⇒ Tuple
Tuple constructor, builds Tuple from list of data values
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/blood_contracts/core/tuple.rb', line 125 def initialize(*values, context: {}, **) @context = context @context[:attributes] ||= {} additional_context = values.last if values.last.is_a?(Hash) additional_context ||= {} @values = parse_values_from_context(context.merge(additional_context)) @values ||= values @errors = [] end |
Class Attribute Details
.attributes ⇒ Array<Refined> (readonly)
List of types in the Tuple
12 13 14 |
# File 'lib/blood_contracts/core/tuple.rb', line 12 def attributes @attributes end |
.failure_klass ⇒ ContractFailure
Accessor to define alternative to ContractFailure for #failure method to use
63 64 65 |
# File 'lib/blood_contracts/core/tuple.rb', line 63 def failure_klass @failure_klass end |
.names ⇒ Array<Symbol> (readonly)
Names of attributes
18 19 20 |
# File 'lib/blood_contracts/core/tuple.rb', line 18 def names @names end |
Instance Attribute Details
#values ⇒ Array<Object> (readonly)
List of values in Tuple
118 119 120 |
# File 'lib/blood_contracts/core/tuple.rb', line 118 def values @values end |
Class Method Details
.attribute(name, type = nil, &block) ⇒ Object
Helper which registers attribute in the Tuple, also defines a reader
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/blood_contracts/core/tuple.rb', line 43 def attribute(name, type = nil, &block) if type.nil? type = type_from_block(name, &block) else raise ArgumentError unless type < Refined end @attributes << type @names << name define_method(name) do match.context.dig(:attributes, name) end end |
.inherited(new_klass) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/blood_contracts/core/tuple.rb', line 64 def inherited(new_klass) new_klass.instance_variable_set(:@attributes, []) new_klass.instance_variable_set(:@names, []) new_klass.instance_variable_set(:@finalized, true) new_klass.failure_klass ||= TupleContractFailure super end |
.new(*args, **kwargs, &block) ⇒ Object
Metaprogramming around constructor Turns input into Tuple meta-class
rubocop:disable Style/SingleLineMethods
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/blood_contracts/core/tuple.rb', line 26 def new(*args, **kwargs, &block) args = lookup_hash_args(*args, kwargs) return super(*args, **kwargs) if @finalized names = args.pop.delete(:names) if args.last.is_a?(Hash) raise ArgumentError unless args.all? { |type| type < Refined } tuple = Class.new(self) { def inspect; super; end } tuple.instance_variable_set(:@attributes, args) tuple.instance_variable_set(:@names, names.to_a) tuple.instance_variable_set(:@finalized, true) tuple.class_eval(&block) if block_given? tuple end |
Instance Method Details
#attribute_errors ⇒ Hash<String, ContractFailure>
Subset of attributes which are invalid
191 192 193 |
# File 'lib/blood_contracts/core/tuple.rb', line 191 def attribute_errors {} end |
#attributes ⇒ Hash<String, Refined>
Hash of attributes (name & type pairs)
183 184 185 |
# File 'lib/blood_contracts/core/tuple.rb', line 183 def attributes @context[:attributes] end |
#mapped ⇒ Array<Object>
Turns match into array of unpacked values
158 159 160 |
# File 'lib/blood_contracts/core/tuple.rb', line 158 def mapped @matches.map(&:unpack) end |
#match ⇒ BC::Refined
The type which is the result of data matching process For Tuple it verifies that all the attributes data are valid types
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/blood_contracts/core/tuple.rb', line 143 def match @matches = attributes_enumerator.map do |(type, value), index| attribute_name = self.class.names[index] attributes.store( attribute_name, type.match(value, context: @context.dup) ) end return if (failures = @matches.select(&:invalid?)).empty? failures.unshift(failure).reduce(:merge!) end |
#unpack_h ⇒ Hash<String, ContractFailure> Also known as: to_hash, to_h, unpack_attributes
Unpacked value in form of a hash per attribute
172 173 174 |
# File 'lib/blood_contracts/core/tuple.rb', line 172 def unpack_h @unpack_h ||= attributes.transform_values(&:unpack) end |