Module: MCPClient::SchemaValidator::Composition
- Included in:
- MCPClient::SchemaValidator
- Defined in:
- lib/mcp_client/schema_validator/composition.rb
Overview
How complete a verdict on one value is. Extended into SchemaValidator, so the methods are its own; Evaluation applies the composition keywords themselves and reads the answers here.
A composition branch is evaluated speculatively (its errors are a verdict, not output). anyOf and allOf are monotonic, so a branch that passes as far as the validator can evaluate it is accepted; not, oneOf and if are not, so a branch that still holds an unevaluated assertion applying to the instance is :undecided and never a match, while one decided by its evaluated keywords (or carrying only annotations) is a full verdict.
Every standard assertion whose verdict this validator can reach is
evaluated (Instances#validate_object,
Instances#validate_array, Scalars#validate_number,
and the unevaluated keywords from the annotations Evaluation
collects), so what is left here is only what genuinely cannot be
decided: a dynamic reference whose target the dynamic scope could
re-bind, and format where it asserts.
Instance Method Summary collapse
-
#contains_max(schema, dialect) ⇒ Numeric?
The number of matching items
containsallows, when the dialect defines the companion and it is a number. -
#contains_min(schema, dialect) ⇒ Numeric
The number of matching items
containsrequires: its companion where the dialect defines one and gives it a number, else the default of 1 (JSON Schema 2020-12 Validation Section 6.4.4). -
#partial_keywords?(schema, dialect, data, _ctx) ⇒ Boolean
Whether a schema object carries an assertion the validator does not evaluate (in the dialect in force) that applies to this instance, so its verdict is only partial.
-
#pattern_matches?(pattern, name, deadline = nil) ⇒ Boolean
Match a server-supplied pattern against a property name.
-
#property_present?(data, name) ⇒ Boolean
Whether the instance carries the property in either key form.
Instance Method Details
#contains_max(schema, dialect) ⇒ Numeric?
Returns the number of matching items contains
allows, when the dialect defines the companion and it is a number.
53 54 55 56 |
# File 'lib/mcp_client/schema_validator/composition.rb', line 53 def contains_max(schema, dialect) max = schema['maxContains'] if keyword_known?('maxContains', dialect) max if max.is_a?(Numeric) end |
#contains_min(schema, dialect) ⇒ Numeric
The number of matching items contains requires: its companion
where the dialect defines one and gives it a number, else the
default of 1 (JSON Schema 2020-12 Validation Section 6.4.4).
46 47 48 49 |
# File 'lib/mcp_client/schema_validator/composition.rb', line 46 def contains_min(schema, dialect) min = schema['minContains'] if keyword_known?('minContains', dialect) min.is_a?(Numeric) ? min : 1 end |
#partial_keywords?(schema, dialect, data, _ctx) ⇒ Boolean
Whether a schema object carries an assertion the validator does not
evaluate (in the dialect in force) that applies to this instance, so
its verdict is only partial. Annotations (format in 2019-09 and
2020-12, contentSchema) decide nothing and leave the verdict whole;
draft-07 format asserts (Validation Section 7.2), and the validator
does not evaluate formats, so a string branch carrying one is
undecided there. Dynamic references are evaluated, against the
dynamic scope, and leave no verdict partial.
38 39 40 |
# File 'lib/mcp_client/schema_validator/composition.rb', line 38 def partial_keywords?(schema, dialect, data, _ctx) dialect == DRAFT_07 && data.is_a?(String) && schema.key?('format') end |
#pattern_matches?(pattern, name, deadline = nil) ⇒ Boolean
Match a server-supplied pattern against a property name. Both come from the peer, so — exactly like validate_pattern — the match runs under the validation-wide deadline: a backtracking expression here must not be able to hold the calling thread.
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/mcp_client/schema_validator/composition.rb', line 74 def pattern_matches?(pattern, name, deadline = nil) remaining = pattern_budget_remaining(deadline) raise Aborted, "validation time budget exhausted before pattern #{clip(pattern.inspect)}" if remaining.zero? ecma_regexp(pattern, remaining, deadline).match?(name) rescue Regexp::TimeoutError raise Aborted, "pattern #{clip(pattern.inspect)} exceeded the #{PATTERN_MATCH_TIMEOUT}s matching budget" rescue RegexpError, TypeError false end |
#property_present?(data, name) ⇒ Boolean
Returns whether the instance carries the property in either key form.
62 63 64 65 |
# File 'lib/mcp_client/schema_validator/composition.rb', line 62 def property_present?(data, name) name = name.to_s data.key?(name) || data.key?(name.to_sym) end |