Module: JSONSchemer::Format

Included in:
Schema::Base
Defined in:
lib/json_schemer/format.rb

Constant Summary collapse

EMAIL_REGEX =

this is no good

/\A[^@\s]+@([\p{L}\d-]+\.)+[\p{L}\d\-]{2,}\z/i.freeze
LABEL_REGEX_STRING =
'\p{L}([\p{L}\p{N}\-]*[\p{L}\p{N}])?'
HOSTNAME_REGEX =
/\A(#{LABEL_REGEX_STRING}\.)*#{LABEL_REGEX_STRING}\z/i.freeze
JSON_POINTER_REGEX_STRING =
'(\/([^~\/]|~[01])*)*'
JSON_POINTER_REGEX =
/\A#{JSON_POINTER_REGEX_STRING}\z/.freeze
RELATIVE_JSON_POINTER_REGEX =
/\A(0|[1-9]\d*)(#|#{JSON_POINTER_REGEX_STRING})?\z/.freeze
DATE_TIME_OFFSET_REGEX =
/(Z|[\+\-]([01][0-9]|2[0-3]):[0-5][0-9])\z/i.freeze
UCSCHAR =

IRI components

Regexp.compile(<<-EOS.gsub(/\s+/, ''))
  [\\u00A0-\\uD7FF]|[\\uF900-\\uFDCF]|[\\uFDF0-\\uFFEF]|
  [\\u{10000}-\\u{1FFFD}]|[\\u{20000}-\\u{2FFFD}]|[\\u{30000}-\\u{3FFFD}]|
  [\\u{40000}-\\u{4FFFD}]|[\\u{50000}-\\u{5FFFD}]|[\\u{60000}-\\u{6FFFD}]|
  [\\u{70000}-\\u{7FFFD}]|[\\u{80000}-\\u{8FFFD}]|[\\u{90000}-\\u{9FFFD}]|
  [\\u{A0000}-\\u{AFFFD}]|[\\u{B0000}-\\u{BFFFD}]|[\\u{C0000}-\\u{CFFFD}]|
  [\\u{D0000}-\\u{DFFFD}]|[\\u{E1000}-\\u{EFFFD}]
EOS
IPRIVATE =
Regexp.compile("[\\uE000-\\uF8FF]|[\\u{F0000}-\\u{FFFFD}]|[\\u100000-\\u10FFFD]").freeze
SCHEME =
Regexp.compile("[A-Za-z](?:[A-Za-z0-9+-\.])*").freeze
PORT =
Regexp.compile("[0-9]*").freeze
IP_LITERAL =

Simplified, no IPvFuture

Regexp.compile("\\[[0-9A-Fa-f:\\.]*\\]").freeze
PCT_ENCODED =
Regexp.compile("%[0-9A-Fa-f][0-9A-Fa-f]").freeze
GEN_DELIMS =
Regexp.compile("[:/\\?\\#\\[\\]@]").freeze
SUB_DELIMS =
Regexp.compile("[!\\$&'\\(\\)\\*\\+,;=]").freeze
RESERVED =
Regexp.compile("(?:#{GEN_DELIMS}|#{SUB_DELIMS})").freeze
UNRESERVED =
Regexp.compile("[A-Za-z0-9\._~-]").freeze
IUNRESERVED =
Regexp.compile("[A-Za-z0-9\._~-]|#{UCSCHAR}").freeze
IPCHAR =
Regexp.compile("(?:#{IUNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|:|@)").freeze
IQUERY =
Regexp.compile("(?:#{IPCHAR}|#{IPRIVATE}|/|\\?)*").freeze
IFRAGMENT =
Regexp.compile("(?:#{IPCHAR}|/|\\?)*").freeze.freeze
ISEGMENT =
Regexp.compile("(?:#{IPCHAR})*").freeze
ISEGMENT_NZ =
Regexp.compile("(?:#{IPCHAR})+").freeze
ISEGMENT_NZ_NC =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|@)+").freeze
IPATH_ABEMPTY =
Regexp.compile("(?:/#{ISEGMENT})*").freeze
IPATH_ABSOLUTE =
Regexp.compile("/(?:(?:#{ISEGMENT_NZ})(/#{ISEGMENT})*)?").freeze
IPATH_NOSCHEME =
Regexp.compile("(?:#{ISEGMENT_NZ_NC})(?:/#{ISEGMENT})*").freeze
IPATH_ROOTLESS =
Regexp.compile("(?:#{ISEGMENT_NZ})(?:/#{ISEGMENT})*").freeze
IPATH_EMPTY =
Regexp.compile("").freeze
IREG_NAME =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS}))*").freeze
IHOST =
Regexp.compile("(?:#{IP_LITERAL})|(?:#{IREG_NAME})").freeze
IUSERINFO =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|:)*").freeze
IAUTHORITY =
Regexp.compile("(?:#{IUSERINFO}@)?#{IHOST}(?::#{PORT})?").freeze
IRELATIVE_PART =
Regexp.compile("(?:(?://#{IAUTHORITY}(?:#{IPATH_ABEMPTY}))|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_NOSCHEME})|(?:#{IPATH_EMPTY}))").freeze
IRELATIVE_REF =
Regexp.compile("^#{IRELATIVE_PART}(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze
IHIER_PART =
Regexp.compile("(?:(?://#{IAUTHORITY}#{IPATH_ABEMPTY})|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_ROOTLESS})|(?:#{IPATH_EMPTY}))").freeze
IRI =
Regexp.compile("^#{SCHEME}:(?:#{IHIER_PART})(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze

Instance Method Summary collapse

Instance Method Details

#valid_date_time?(data) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
112
113
114
115
# File 'lib/json_schemer/format.rb', line 109

def valid_date_time?(data)
  DateTime.rfc3339(data)
  DATE_TIME_OFFSET_REGEX.match?(data)
rescue ArgumentError => e
  raise e unless e.message == 'invalid date'
  false
end

#valid_email?(data) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/json_schemer/format.rb', line 117

def valid_email?(data)
  EMAIL_REGEX.match?(data)
end

#valid_hostname?(data) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/json_schemer/format.rb', line 121

def valid_hostname?(data)
  HOSTNAME_REGEX.match?(data) && data.split('.').all? { |label| label.size <= 63 }
end

#valid_ip?(data, type) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
130
# File 'lib/json_schemer/format.rb', line 125

def valid_ip?(data, type)
  ip_address = IPAddr.new(data)
  type == :v4 ? ip_address.ipv4? : ip_address.ipv6?
rescue IPAddr::InvalidAddressError
  false
end

#valid_iri?(data) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/json_schemer/format.rb', line 132

def valid_iri?(data)
  IRI.match?(data)
end

#valid_iri_reference?(data) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/json_schemer/format.rb', line 136

def valid_iri_reference?(data)
  IRELATIVE_REF.match?(data)
end

#valid_json?(data) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
# File 'lib/json_schemer/format.rb', line 102

def valid_json?(data)
  JSON.parse(data)
  true
rescue JSON::ParserError
  false
end

#valid_json_pointer?(data) ⇒ Boolean

Returns:

  • (Boolean)


147
148
149
# File 'lib/json_schemer/format.rb', line 147

def valid_json_pointer?(data)
  JSON_POINTER_REGEX.match?(data)
end

#valid_relative_json_pointer?(data) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/json_schemer/format.rb', line 151

def valid_relative_json_pointer?(data)
  RELATIVE_JSON_POINTER_REGEX.match?(data)
end

#valid_spec_format?(data, format) ⇒ Boolean

Returns:

  • (Boolean)


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
# File 'lib/json_schemer/format.rb', line 63

def valid_spec_format?(data, format)
  case format
  when 'date-time'
    valid_date_time?(data)
  when 'date'
    valid_date_time?("#{data}T04:05:06.123456789+07:00")
  when 'time'
    valid_date_time?("2001-02-03T#{data}")
  when 'email'
    data.ascii_only? && valid_email?(data)
  when 'idn-email'
    valid_email?(data)
  when 'hostname'
    data.ascii_only? && valid_hostname?(data)
  when 'idn-hostname'
    valid_hostname?(data)
  when 'ipv4'
    valid_ip?(data, :v4)
  when 'ipv6'
    valid_ip?(data, :v6)
  when 'uri'
    data.ascii_only? && valid_iri?(data)
  when 'uri-reference'
    data.ascii_only? && (valid_iri?(data) || valid_iri_reference?(data))
  when 'iri'
    valid_iri?(data)
  when 'iri-reference'
    valid_iri?(data) || valid_iri_reference?(data)
  when 'uri-template'
    valid_uri_template?(data)
  when 'json-pointer'
    valid_json_pointer?(data)
  when 'relative-json-pointer'
    valid_relative_json_pointer?(data)
  when 'regex'
    EcmaReValidator.valid?(data)
  end
end

#valid_uri_template?(data) ⇒ Boolean

Returns:

  • (Boolean)


140
141
142
143
144
145
# File 'lib/json_schemer/format.rb', line 140

def valid_uri_template?(data)
  URITemplate.new(data)
  true
rescue URITemplate::Invalid
  false
end