Class: NxtSchema::Node::Base
- Inherits:
-
Object
- Object
- NxtSchema::Node::Base
- Defined in:
- lib/nxt_schema/node/base.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#additional_keys_strategy ⇒ Object
Returns the value of attribute additional_keys_strategy.
-
#all_nodes ⇒ Object
Returns the value of attribute all_nodes.
-
#applied ⇒ Object
Returns the value of attribute applied.
-
#context ⇒ Object
Returns the value of attribute context.
-
#errors ⇒ Object
Returns the value of attribute errors.
-
#input ⇒ Object
Returns the value of attribute input.
-
#level ⇒ Object
Returns the value of attribute level.
-
#locale ⇒ Object
Returns the value of attribute locale.
-
#name ⇒ Object
Returns the value of attribute name.
-
#namespace ⇒ Object
Returns the value of attribute namespace.
-
#options ⇒ Object
Returns the value of attribute options.
-
#parent_node ⇒ Object
Returns the value of attribute parent_node.
-
#root ⇒ Object
Returns the value of attribute root.
-
#schema_errors ⇒ Object
Returns the value of attribute schema_errors.
-
#schema_errors_key ⇒ Object
Returns the value of attribute schema_errors_key.
-
#type ⇒ Object
Returns the value of attribute type.
-
#type_system ⇒ Object
(also: #types)
Returns the value of attribute type_system.
-
#validation_errors ⇒ Object
Returns the value of attribute validation_errors.
-
#validations ⇒ Object
Returns the value of attribute validations.
-
#value ⇒ Object
Returns the value of attribute value.
Instance Method Summary collapse
- #add_error(error, index = schema_errors_key) ⇒ Object
- #add_validators(validator) ⇒ Object
- #apply_validations ⇒ Object
- #build_validations ⇒ Object
- #default(default_value, &block) ⇒ Object
-
#initialize(name: name_from_index, type:, parent_node:, **options, &block) ⇒ Base
constructor
A new instance of Base.
- #leaf? ⇒ Boolean
- #maybe(maybe_value, &block) ⇒ Object
- #meta(value = NxtSchema::Undefined.new) ⇒ Object
- #optional(optional_value = nil, &block) ⇒ Object
- #parent(level = 1) ⇒ Object (also: #up)
- #presence(presence_value = nil, &block) ⇒ Object
- #presence? ⇒ Boolean
- #root? ⇒ Boolean
- #schema_errors? ⇒ Boolean
- #valid? ⇒ Boolean
- #validate(key, *args, &block) ⇒ Object
- #validate_all_nodes ⇒ Object
- #validate_with(&block) ⇒ Object
- #validation_errors? ⇒ Boolean
- #validator(key, *args) ⇒ Object
- #value_or_default_value(value) ⇒ Object
Constructor Details
#initialize(name: name_from_index, type:, parent_node:, **options, &block) ⇒ Base
Returns a new instance of Base.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/nxt_schema/node/base.rb', line 4 def initialize(name: name_from_index, type:, parent_node:, **, &block) @name = name @parent_node = parent_node @options = @type_system = resolve_type_system @additional_keys_strategy = resolve_additional_keys_strategy @type = type @schema_errors_key = .fetch(:schema_errors_key, :itself) @validations = [] @level = parent_node ? parent_node.level + 1 : 0 @all_nodes = parent_node ? (parent_node.all_nodes || {}) : {} @is_root = parent_node.nil? @root = parent_node.nil? ? self : parent_node.root @errors = {} @context = nil @applied = false @input = nil @value = NxtSchema::Undefined.new @locale = .fetch(:locale) { parent_node&.locale || 'en' } # Note that it is not possible to use present? on an instance of NxtSchema::Schema since it inherits from Hash evaluate_block(block) if block_given? end |
Instance Attribute Details
#additional_keys_strategy ⇒ Object
Returns the value of attribute additional_keys_strategy.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def additional_keys_strategy @additional_keys_strategy end |
#all_nodes ⇒ Object
Returns the value of attribute all_nodes.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def all_nodes @all_nodes end |
#applied ⇒ Object
Returns the value of attribute applied.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def applied @applied end |
#context ⇒ Object
Returns the value of attribute context.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def context @context end |
#errors ⇒ Object
Returns the value of attribute errors.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def errors @errors end |
#input ⇒ Object
Returns the value of attribute input.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def input @input end |
#level ⇒ Object
Returns the value of attribute level.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def level @level end |
#locale ⇒ Object
Returns the value of attribute locale.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def locale @locale end |
#name ⇒ Object
Returns the value of attribute name.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def name @name end |
#namespace ⇒ Object
Returns the value of attribute namespace.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def namespace @namespace end |
#options ⇒ Object
Returns the value of attribute options.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def @options end |
#parent_node ⇒ Object
Returns the value of attribute parent_node.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def parent_node @parent_node end |
#root ⇒ Object
Returns the value of attribute root.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def root @root end |
#schema_errors ⇒ Object
Returns the value of attribute schema_errors.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def schema_errors @schema_errors end |
#schema_errors_key ⇒ Object
Returns the value of attribute schema_errors_key.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def schema_errors_key @schema_errors_key end |
#type ⇒ Object
Returns the value of attribute type.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def type @type end |
#type_system ⇒ Object Also known as: types
Returns the value of attribute type_system.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def type_system @type_system end |
#validation_errors ⇒ Object
Returns the value of attribute validation_errors.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def validation_errors @validation_errors end |
#validations ⇒ Object
Returns the value of attribute validations.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def validations @validations end |
#value ⇒ Object
Returns the value of attribute value.
28 29 30 |
# File 'lib/nxt_schema/node/base.rb', line 28 def value @value end |
Instance Method Details
#add_error(error, index = schema_errors_key) ⇒ Object
127 128 129 130 131 |
# File 'lib/nxt_schema/node/base.rb', line 127 def add_error(error, index = schema_errors_key) validation_errors[index] ||= [] validation_errors[index] << error false end |
#add_validators(validator) ⇒ Object
198 199 200 201 202 |
# File 'lib/nxt_schema/node/base.rb', line 198 def add_validators(validator) [:validate] ||= [] [:validate] = Array(.fetch(:validate, [])) [:validate] << validator end |
#apply_validations ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/nxt_schema/node/base.rb', line 142 def apply_validations # We don't run validations in case there are schema errors # to avoid weird errors # First reject empty schema_errors schema_errors.reject! { |_, v| v.empty? } # TODO: Is this correct? - Do not apply validations when maybe criteria applies? unless schema_errors[schema_errors_key]&.any? && !maybe_criteria_applies?(value) build_validations validations.each do |validation| args = [self, value] validation.call(*args.take(validation.arity)) end end if self.is_a?(NxtSchema::Node::Collection) && value.respond_to?(:each) value.each_with_index do |item, index| validation_errors[index]&.reject! { |_, v| v.empty? } end end validation_errors.reject! { |_, v| v.empty? } self end |
#build_validations ⇒ Object
169 170 171 172 |
# File 'lib/nxt_schema/node/base.rb', line 169 def build_validations = Array(.fetch(:validate, [])) self.validations = end |
#default(default_value, &block) ⇒ Object
58 59 60 61 62 |
# File 'lib/nxt_schema/node/base.rb', line 58 def default(default_value, &block) .merge!(default: default_value) evaluate_block(block) if block_given? self end |
#leaf? ⇒ Boolean
188 189 190 |
# File 'lib/nxt_schema/node/base.rb', line 188 def leaf? false end |
#maybe(maybe_value, &block) ⇒ Object
81 82 83 84 85 |
# File 'lib/nxt_schema/node/base.rb', line 81 def maybe(maybe_value, &block) .merge!(maybe: maybe_value) evaluate_block(block) if block_given? self end |
#meta(value = NxtSchema::Undefined.new) ⇒ Object
64 65 66 67 68 69 70 71 |
# File 'lib/nxt_schema/node/base.rb', line 64 def (value = NxtSchema::Undefined.new) if value.is_a?(NxtSchema::Undefined) @meta else @meta = value self end end |
#optional(optional_value = nil, &block) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/nxt_schema/node/base.rb', line 87 def optional(optional_value = nil, &block) raise ArgumentError, 'Optional nodes can only exist within schemas' unless parent.is_a?(NxtSchema::Node::Schema) .merge!(optional: optional_value || block) self end |
#parent(level = 1) ⇒ Object Also known as: up
52 53 54 |
# File 'lib/nxt_schema/node/base.rb', line 52 def parent(level = 1) level.times.inject(self) { |acc| acc.parent_node } end |
#presence(presence_value = nil, &block) ⇒ Object
94 95 96 97 98 99 |
# File 'lib/nxt_schema/node/base.rb', line 94 def presence(presence_value = nil, &block) raise ArgumentError, 'Present nodes can only exist within schemas' unless parent.is_a?(NxtSchema::Node::Schema) .merge!(presence: presence_value || block) self end |
#presence? ⇒ Boolean
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/nxt_schema/node/base.rb', line 101 def presence? @presence ||= begin presence_option = [:presence] [:presence] = if presence_option.respond_to?(:call) Callable.new(presence_option).call(self, value) else presence_option end end end |
#root? ⇒ Boolean
184 185 186 |
# File 'lib/nxt_schema/node/base.rb', line 184 def root? @is_root end |
#schema_errors? ⇒ Boolean
174 175 176 177 |
# File 'lib/nxt_schema/node/base.rb', line 174 def schema_errors? schema_errors.reject! { |_, v| v.empty? } schema_errors.any? end |
#valid? ⇒ Boolean
192 193 194 195 196 |
# File 'lib/nxt_schema/node/base.rb', line 192 def valid? raise SchemaNotAppliedError, 'Schema was not applied yet' unless applied? validation_errors.empty? end |
#validate(key, *args, &block) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/nxt_schema/node/base.rb', line 113 def validate(key, *args, &block) if key.is_a?(Symbol) validator = validator(key, *args) elsif key.respond_to?(:call) validator = key else raise ArgumentError, "Don't know how to resolve validator from: #{key}" end add_validators(validator) evaluate_block(block) if block_given? self end |
#validate_all_nodes ⇒ Object
133 134 135 136 137 138 139 140 |
# File 'lib/nxt_schema/node/base.rb', line 133 def validate_all_nodes sorted_nodes = all_nodes.values.sort do |node, other_node| [node.level, (!node.leaf?).to_s] <=> [other_node.level, (!other_node.leaf?).to_s] end # we have to start from the bottom, leafs before others on the same level sorted_nodes.reverse_each(&:apply_validations) end |
#validate_with(&block) ⇒ Object
208 209 210 211 212 |
# File 'lib/nxt_schema/node/base.rb', line 208 def validate_with(&block) add_validators( ->(node) { NxtSchema::Node::ValidateWithProxy.new(node).validate(&block) } ) end |
#validation_errors? ⇒ Boolean
179 180 181 182 |
# File 'lib/nxt_schema/node/base.rb', line 179 def validation_errors? validation_errors.reject! { |_, v| v.empty? } validation_errors.any? end |
#validator(key, *args) ⇒ Object
204 205 206 |
# File 'lib/nxt_schema/node/base.rb', line 204 def validator(key, *args) Validators::Registry::VALIDATORS.resolve(key).new(*args).build end |
#value_or_default_value(value) ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/nxt_schema/node/base.rb', line 73 def value_or_default_value(value) if !value && .key?(:default) DefaultValueEvaluator.new(self, .fetch(:default)).call else value end end |