Class: JSONSchemer::OpenAPI31::Vocab::Base::Discriminator

Inherits:
Keyword
  • Object
show all
Includes:
Format::JSONPointer
Defined in:
lib/json_schemer/openapi31/vocab/base.rb

Constant Summary

Constants included from Format::JSONPointer

Format::JSONPointer::JSON_POINTER_REGEX, Format::JSONPointer::JSON_POINTER_REGEX_STRING, Format::JSONPointer::RELATIVE_JSON_POINTER_REGEX

Constants included from JSONSchemer::Output

JSONSchemer::Output::FRAGMENT_ENCODE_REGEX

Instance Attribute Summary collapse

Attributes inherited from Keyword

#parent, #parsed, #root, #value

Attributes included from JSONSchemer::Output

#keyword, #schema

Instance Method Summary collapse

Methods included from Format::JSONPointer

#valid_json_pointer?, #valid_relative_json_pointer?

Methods inherited from Keyword

#absolute_keyword_location, #initialize, #schema_pointer

Constructor Details

This class inherits a constructor from JSONSchemer::Keyword

Instance Attribute Details

#skip_ref_onceObject

Returns the value of attribute skip_ref_once.



39
40
41
# File 'lib/json_schemer/openapi31/vocab/base.rb', line 39

def skip_ref_once
  @skip_ref_once
end

Instance Method Details

#error(formatted_instance_location:) ⇒ Object



41
42
43
# File 'lib/json_schemer/openapi31/vocab/base.rb', line 41

def error(formatted_instance_location:, **)
  "value at #{formatted_instance_location} does not match `discriminator` schema"
end

#validate(instance, instance_location, keyword_location, context) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/json_schemer/openapi31/vocab/base.rb', line 45

def validate(instance, instance_location, keyword_location, context)
  property_name = value.fetch('propertyName')
  mapping = value['mapping'] || {}

  return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Hash) && instance.key?(property_name)

  property = instance.fetch(property_name)
  ref = mapping.fetch(property, property)

  ref_schema = nil
  unless ref.start_with?('#') && valid_json_pointer?(ref.delete_prefix('#'))
    ref_schema = begin
      root.resolve_ref(URI.join(schema.base_uri, "#/components/schemas/#{ref}"))
    rescue InvalidRefPointer
      nil
    end
  end
  ref_schema ||= root.resolve_ref(URI.join(schema.base_uri, ref))

  return if skip_ref_once == ref_schema.absolute_keyword_location

  nested = []

  if schema.parsed.key?('anyOf') || schema.parsed.key?('oneOf')
    subschemas = schema.parsed['anyOf']&.parsed || []
    subschemas += schema.parsed['oneOf']&.parsed || []
    subschemas.each do |subschema|
      if subschema.parsed.fetch('$ref').ref_schema.absolute_keyword_location == ref_schema.absolute_keyword_location
        nested << subschema.validate_instance(instance, instance_location, keyword_location, context)
      end
    end
  else
    ref_schema.parsed['allOf']&.skip_ref_once = schema.absolute_keyword_location
    nested << ref_schema.validate_instance(instance, instance_location, keyword_location, context)
  end

  result(instance, instance_location, keyword_location, (nested.any? && nested.all?(&:valid)), nested)
ensure
  self.skip_ref_once = nil
end