Class: Karafka::Core::Contractable::Contract
- Inherits:
-
Object
- Object
- Karafka::Core::Contractable::Contract
- Extended by:
- Karafka::Core::Configurable
- Defined in:
- lib/karafka/core/contractable/contract.rb
Overview
This contract does NOT support rules inheritance as it was never needed in Karafka
Base contract for all the contracts that check data format
Class Attribute Summary collapse
-
.rules ⇒ Array<Rule>
readonly
All the validation rules defined for a given contract.
Class Method Summary collapse
-
.nested(path) ⇒ Object
Allows for definition of a scope/namespace for nested validations.
- .optional(*keys, &block) ⇒ Object
-
.required(*keys, &block) ⇒ Object
Defines a rule for a required field (required means, that will automatically create an error if missing).
- .virtual(&block) ⇒ Object
Instance Method Summary collapse
-
#call(data, scope: EMPTY_ARRAY) ⇒ Result
Runs the validation.
-
#validate!(data, error_class, scope: EMPTY_ARRAY) ⇒ Boolean
True.
Methods included from Karafka::Core::Configurable
Class Attribute Details
.rules ⇒ Array<Rule> (readonly)
Returns all the validation rules defined for a given contract.
30 31 32 |
# File 'lib/karafka/core/contractable/contract.rb', line 30 def rules @rules end |
Class Method Details
.nested(path) ⇒ Object
Allows for definition of a scope/namespace for nested validations
40 41 42 43 44 45 |
# File 'lib/karafka/core/contractable/contract.rb', line 40 def nested(path, &) init_accu @nested << path instance_eval(&) @nested.pop end |
.optional(*keys, &block) ⇒ Object
59 60 61 62 |
# File 'lib/karafka/core/contractable/contract.rb', line 59 def optional(*keys, &block) init_accu @rules << Rule.new(@nested + keys, :optional, block).freeze end |
.required(*keys, &block) ⇒ Object
Defines a rule for a required field (required means, that will automatically create an error if missing)
52 53 54 55 |
# File 'lib/karafka/core/contractable/contract.rb', line 52 def required(*keys, &block) init_accu @rules << Rule.new(@nested + keys, :required, block).freeze end |
.virtual(&block) ⇒ Object
Virtual rules have different result expectations. Please see contracts or specs for details.
68 69 70 71 |
# File 'lib/karafka/core/contractable/contract.rb', line 68 def virtual(&block) init_accu @rules << Rule.new([], :virtual, block).freeze end |
Instance Method Details
#call(data, scope: EMPTY_ARRAY) ⇒ Result
Runs the validation
The per-rule handling is inlined instead of dispatching to per-type methods because this runs per rule per validation, including the per-message validations in WaterDrop. Required and optional rules share the whole flow except the missing-key handling. ‘DIG_MISS` is compared via `#equal?` so we never dispatch `#==` to the validated (user-provided) values.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/karafka/core/contractable/contract.rb', line 94 def call(data, scope: EMPTY_ARRAY) errors = [] self.class.rules.each do |rule| if rule.type == :virtual result = rule.validator.call(data, errors, self) next if result == true result&.each do |sub_result| sub_result[0] = scope + sub_result[0] end errors.push(*result) else for_checking = dig(data, rule.path) if DIG_MISS.equal?(for_checking) errors << [scope + rule.path, :missing] if rule.type == :required else result = rule.validator.call(for_checking, data, errors, self) next if result == true errors << [scope + rule.path, result || :format] end end end return Result.success if errors.empty? Result.new(errors, self) end |
#validate!(data, error_class, scope: EMPTY_ARRAY) ⇒ Boolean
Returns true.
135 136 137 138 139 140 141 |
# File 'lib/karafka/core/contractable/contract.rb', line 135 def validate!(data, error_class, scope: EMPTY_ARRAY) result = call(data, scope: scope) return true if result.success? raise error_class, result.errors end |