Module: JSONSchemer::Format

Includes:
Hostname, URITemplate
Included in:
Schema::Base
Defined in:
lib/json_schemer/format.rb,
lib/json_schemer/format/hostname.rb,
lib/json_schemer/format/uri_template.rb

Defined Under Namespace

Modules: Hostname, URITemplate

Constant Summary collapse

EMAIL_REGEX =

this is no good

/\A[^@\s]+@([\p{L}\d-]+\.)+[\p{L}\d\-]{2,}\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
HOUR_24_REGEX =
/T24/.freeze
LEAP_SECOND_REGEX =
/T\d{2}:\d{2}:6/.freeze
IP_REGEX =
/\A[\h:.]+\z/.freeze
INVALID_QUERY_REGEX =
/\s/.freeze

Constants included from URITemplate

URITemplate::EXPLODE, URITemplate::EXPRESSION, URITemplate::LITERALS, URITemplate::MAX_LENGTH, URITemplate::MODIFIER_LEVEL4, URITemplate::OPERATOR, URITemplate::PCT_ENCODED, URITemplate::PREFIX, URITemplate::URI_TEMPLATE, URITemplate::URI_TEMPLATE_REGEX, URITemplate::VARCHAR, URITemplate::VARIABLE_LIST, URITemplate::VARNAME, URITemplate::VARSPEC

Constants included from Hostname

Hostname::ARABIC_EXTENDED_DIGITS_REGEX, Hostname::ARABIC_INDIC_DIGITS_REGEX, Hostname::CONTEXT_REGEX, Hostname::EXCEPTIONS_DISALLOWED, Hostname::EXCEPTIONS_PVALID, Hostname::GREEK_LOWER_NUMERAL_SIGN, Hostname::HEBREW_PUNCTUATION, Hostname::HOSTNAME_REGEX, Hostname::JOINING_TYPE_D_CHARACTER_CLASS, Hostname::JOINING_TYPE_L_CHARACTER_CLASS, Hostname::JOINING_TYPE_R_CHARACTER_CLASS, Hostname::JOINING_TYPE_T_CHARACTER_CLASS, Hostname::KATAKANA_MIDDLE_DOT_CONTEXT_REGEX, Hostname::KATAKANA_MIDDLE_DOT_REGEX, Hostname::LABEL_CHARACTER_CLASS, Hostname::LABEL_REGEX_STRING, Hostname::LEADING_CHARACTER_CLASS, Hostname::LETTER_DIGITS, Hostname::MARKS, Hostname::MIDDLE_DOT, Hostname::VIRAMA_CHARACTER_CLASS, Hostname::ZERO_WIDTH_NON_JOINER_JOINING_TYPE, Hostname::ZERO_WIDTH_VIRAMA

Instance Method Summary collapse

Methods included from URITemplate

#valid_uri_template?

Methods included from Hostname

#valid_hostname?

Instance Method Details

#iri_escape(data) ⇒ Object



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

def iri_escape(data)
  data.gsub(/[^[:ascii:]]/) do |match|
    us = match
    tmp = +''
    us.each_byte do |uc|
      tmp << sprintf('%%%02X', uc)
    end
    tmp
  end.force_encoding(Encoding::US_ASCII)
end

#parse_uri_scheme(data) ⇒ Object

Raises:

  • (URI::InvalidURIError)


88
89
90
91
92
93
# File 'lib/json_schemer/format.rb', line 88

def parse_uri_scheme(data)
  scheme, _userinfo, _host, _port, _registry, _path, opaque, query, _fragment = URI::RFC3986_PARSER.split(data)
  # URI::RFC3986_PARSER.parse allows spaces in these and I don't think it should
  raise URI::InvalidURIError if INVALID_QUERY_REGEX.match?(query) || INVALID_QUERY_REGEX.match?(opaque)
  scheme
end

#valid_date_time?(data) ⇒ Boolean

Returns:

  • (Boolean)


66
67
68
69
70
71
72
73
# File 'lib/json_schemer/format.rb', line 66

def valid_date_time?(data)
  return false if HOUR_24_REGEX.match?(data)
  datetime = DateTime.rfc3339(data)
  return false if LEAP_SECOND_REGEX.match?(data) && datetime.new_offset.strftime('%H:%M') != '23:59'
  DATE_TIME_OFFSET_REGEX.match?(data)
rescue ArgumentError
  false
end

#valid_email?(data) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
# File 'lib/json_schemer/format.rb', line 75

def valid_email?(data)
  return false unless EMAIL_REGEX.match?(data)
  local, _domain = data.partition('@')
  !local.start_with?('.') && !local.end_with?('.') && !local.include?('..')
end

#valid_ip?(data, family) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
# File 'lib/json_schemer/format.rb', line 81

def valid_ip?(data, family)
  IPAddr.new(data, family)
  IP_REGEX.match?(data)
rescue IPAddr::Error
  false
end

#valid_json?(data) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
# File 'lib/json_schemer/format.rb', line 59

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

#valid_json_pointer?(data) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/json_schemer/format.rb', line 119

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

#valid_regex?(data) ⇒ Boolean

Returns:

  • (Boolean)


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

def valid_regex?(data)
  !!EcmaRegexp.ruby_equivalent(data)
rescue InvalidEcmaRegexp
  false
end

#valid_relative_json_pointer?(data) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/json_schemer/format.rb', line 123

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

#valid_spec_format?(data, format) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/json_schemer/format.rb', line 18

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, Socket::AF_INET)
  when 'ipv6'
    valid_ip?(data, Socket::AF_INET6)
  when 'uri'
    valid_uri?(data)
  when 'uri-reference'
    valid_uri_reference?(data)
  when 'iri'
    valid_uri?(iri_escape(data))
  when 'iri-reference'
    valid_uri_reference?(iri_escape(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'
    valid_regex?(data)
  else
    raise UnknownFormat, format
  end
end

#valid_uri?(data) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
98
99
# File 'lib/json_schemer/format.rb', line 95

def valid_uri?(data)
  !!parse_uri_scheme(data)
rescue URI::InvalidURIError
  false
end

#valid_uri_reference?(data) ⇒ Boolean

Returns:

  • (Boolean)


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

def valid_uri_reference?(data)
  parse_uri_scheme(data)
  true
rescue URI::InvalidURIError
  false
end