Class: JSONSchemer::Schema::Base

Inherits:
Object
  • Object
show all
Includes:
Format
Defined in:
lib/json_schemer/schema/base.rb

Direct Known Subclasses

Draft4, Draft6, Draft7

Constant Summary collapse

ID_KEYWORD =
'$id'
DEFAULT_REF_RESOLVER =
proc { |uri| raise UnknownRef, uri.to_s }.freeze
NET_HTTP_REF_RESOLVER =
proc { |uri| JSON.parse(Net::HTTP.get(uri)) }.freeze
BOOLEANS =
Set[true, false].freeze

Constants included from Format

Format::EMAIL_REGEX, Format::GEN_DELIMS, Format::HOSTNAME_REGEX, Format::IAUTHORITY, Format::IFRAGMENT, Format::IHIER_PART, Format::IHOST, Format::IPATH_ABEMPTY, Format::IPATH_ABSOLUTE, Format::IPATH_EMPTY, Format::IPATH_NOSCHEME, Format::IPATH_ROOTLESS, Format::IPCHAR, Format::IPRIVATE, Format::IP_LITERAL, Format::IQUERY, Format::IREG_NAME, Format::IRELATIVE_PART, Format::IRELATIVE_REF, Format::IRI, Format::ISEGMENT, Format::ISEGMENT_NZ, Format::ISEGMENT_NZ_NC, Format::IUNRESERVED, Format::IUSERINFO, Format::JSON_POINTER_REGEX, Format::JSON_POINTER_REGEX_STRING, Format::LABEL_REGEX_STRING, Format::PCT_ENCODED, Format::PORT, Format::RELATIVE_JSON_POINTER_REGEX, Format::RESERVED, Format::SCHEME, Format::SUB_DELIMS, Format::UCSCHAR, Format::UNRESERVED

Instance Method Summary collapse

Methods included from Format

#valid_date_time?, #valid_email?, #valid_format?, #valid_hostname?, #valid_ip?, #valid_iri?, #valid_iri_reference?, #valid_json?, #valid_json_pointer?, #valid_relative_json_pointer?, #valid_uri_template?

Constructor Details

#initialize(schema, format: true, formats: nil, keywords: nil, ref_resolver: DEFAULT_REF_RESOLVER) ⇒ Base

Returns a new instance of Base.



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/json_schemer/schema/base.rb', line 20

def initialize(
  schema,
  format: true,
  formats: nil,
  keywords: nil,
  ref_resolver: DEFAULT_REF_RESOLVER
)
  @root = schema
  @format = format
  @formats = formats
  @keywords = keywords
  @ref_resolver = ref_resolver == 'net/http' ? NET_HTTP_REF_RESOLVER : ref_resolver
end

Instance Method Details

#valid?(data, schema = root, pointer = '', parent_uri = nil) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/json_schemer/schema/base.rb', line 34

def valid?(data, schema = root, pointer = '', parent_uri = nil)
  validate(data, schema, pointer, parent_uri).none?
end

#validate(data, schema = root, pointer = '', parent_uri = nil) {|error(data, schema, pointer, 'enum')| ... } ⇒ Object

Yields:

  • (error(data, schema, pointer, 'enum'))


38
39
40
41
42
43
44
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/json_schemer/schema/base.rb', line 38

def validate(data, schema = root, pointer = '', parent_uri = nil)
  return enum_for(:validate, data, schema, pointer, parent_uri) unless block_given?

  return if schema == true
  if schema == false
    yield error(data, schema, pointer, 'schema')
    return
  end

  return if schema.empty?

  type = schema['type']
  enum = schema['enum']
  all_of = schema['allOf']
  any_of = schema['anyOf']
  one_of = schema['oneOf']
  not_schema = schema['not']
  if_schema = schema['if']
  then_schema = schema['then']
  else_schema = schema['else']
  format = schema['format']
  ref = schema['$ref']
  id = schema[id_keyword]

  parent_uri = join_uri(parent_uri, id)

  if ref
    validate_ref(data, schema, pointer, parent_uri, ref, &Proc.new)
    return
  end

  validate_format(data, schema, pointer, format, &Proc.new) if format && format?

  if keywords
    keywords.each do |keyword, callable|
      if schema.key?(keyword)
        result = callable.call(data, schema, pointer)
        if result.is_a?(Array)
          result.each { |error| yield error }
        elsif !result
          yield error(data, schema, pointer, keyword)
        end
      end
    end
  end

  yield error(data, schema, pointer, 'enum') if enum && !enum.include?(data)
  yield error(data, schema, pointer, 'const') if schema.key?('const') && schema['const'] != data

  yield error(data, schema, pointer, 'allOf') if all_of && !all_of.all? { |subschema| valid?(data, subschema, pointer, parent_uri) }
  yield error(data, schema, pointer, 'anyOf') if any_of && !any_of.any? { |subschema| valid?(data, subschema, pointer, parent_uri) }
  yield error(data, schema, pointer, 'oneOf') if one_of && !one_of.one? { |subschema| valid?(data, subschema, pointer, parent_uri) }
  yield error(data, schema, pointer, 'not') if !not_schema.nil? && valid?(data, not_schema, pointer, parent_uri)

  if if_schema && valid?(data, if_schema, pointer, parent_uri)
    yield error(data, schema, pointer, 'then') if !then_schema.nil? && !valid?(data, then_schema, pointer, parent_uri)
  elsif if_schema
    yield error(data, schema, pointer, 'else') if !else_schema.nil? && !valid?(data, else_schema, pointer, parent_uri)
  end

  case type
  when nil
    validate_class(data, schema, pointer, parent_uri, &Proc.new)
  when String
    validate_type(data, schema, pointer, parent_uri, type, &Proc.new)
  when Array
    if valid_type = type.find { |subtype| valid?(data, { 'type' => subtype }, pointer, parent_uri) }
      validate_type(data, schema, pointer, parent_uri, valid_type, &Proc.new)
    else
      yield error(data, schema, pointer, 'type')
    end
  end
end