Class: Udb::Schema

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Includes:
Idl::Schema
Defined in:
lib/udb/schema.rb

Instance Method Summary collapse

Constructor Details

#initialize(schema_hash) ⇒ Schema

Returns a new instance of Schema.

Raises:

  • (ArgumentError)


19
20
21
22
23
# File 'lib/udb/schema.rb', line 19

def initialize(schema_hash)
    raise ArgumentError, "Expecting hash" unless schema_hash.is_a?(Hash)

    @schema_hash = schema_hash
end

Instance Method Details

#empty?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/udb/schema.rb', line 173

def empty?
  @schema_hash.empty?
end

#is_power_of_two?(num) ⇒ Boolean

Returns:

  • (Boolean)


233
234
235
236
# File 'lib/udb/schema.rb', line 233

def is_power_of_two?(num)
  return false if num < 1
  return (num & (num-1)) == 0
end

#large2hex(value) ⇒ Object

Convert large integers to hex str.



155
156
157
158
159
160
161
162
163
# File 'lib/udb/schema.rb', line 155

def large2hex(value)
  if value.nil?
    ""
  elsif value.is_a?(Integer)
    (value > 999) ? "0x" + value.to_s(16) : value.to_s
  else
    value.to_s
  end
end

#max_valInteger

Returns The maximum value the schema allows. Only valid if #max_val_known? is true.

Returns:

  • (Integer)

    The maximum value the schema allows. Only valid if #max_val_known? is true



207
208
209
210
211
212
213
214
215
216
217
# File 'lib/udb/schema.rb', line 207

def max_val
  if @schema_hash.key?("const")
    @schema_hash["const"]
  elsif @schema_hash.key?("enum")
    @schema_hash["enum"].max
  elsif @schema_hash.key?("maximum")
    @schema_hash["maximum"]
  else
    raise "unexpected"
  end
end

#max_val_known?Boolean

Returns if the maximum value of the schema is known, i.e., is a restricted integer.

Returns:

  • (Boolean)

    if the maximum value of the schema is known, i.e., is a restricted integer



189
190
191
192
193
194
# File 'lib/udb/schema.rb', line 189

def max_val_known?
  to_idl_type.kind == :bits && \
    (@schema_hash.key?("const") || \
     @schema_hash.key?("maximum") || \
     @schema_hash.key?("enum"))
end

#merge(other_schema) ⇒ Object

Raises:

  • (ArgumentError)


165
166
167
168
169
170
171
# File 'lib/udb/schema.rb', line 165

def merge(other_schema)
  raise ArgumentError, "Expecting Schema" unless (other_schema.is_a?(Schema) || other_schema.is_a?(Hash))

  other_hash = other_schema.is_a?(Schema) ? other_schema.instance_variable_get(:@schema_hash) : other_schema

  Schema.new(@schema_hash.merge(other_hash))
end

#min_valInteger

Returns The minimum value the schema allows. Only valid if #min_val_known? is true.

Returns:

  • (Integer)

    The minimum value the schema allows. Only valid if #min_val_known? is true



221
222
223
224
225
226
227
228
229
230
231
# File 'lib/udb/schema.rb', line 221

def min_val
  if @schema_hash.key?("const")
    @schema_hash["const"]
  elsif @schema_hash.key?("enum")
    @schema_hash["enum"].min
  elsif @schema_hash.key?("minimum")
    @schema_hash["minimum"]
  else
    raise "unexpected"
  end
end

#min_val_known?Boolean

Returns if the minimum value of the schema is known, i.e., is a restricted integer.

Returns:

  • (Boolean)

    if the minimum value of the schema is known, i.e., is a restricted integer



198
199
200
201
202
203
# File 'lib/udb/schema.rb', line 198

def min_val_known?
  to_idl_type.kind == :bits && \
    (@schema_hash.key?("const") || \
     @schema_hash.key?("minimum") || \
     @schema_hash.key?("enum"))
end

#num_bits(min, max) ⇒ Object

If min to max range represents an unsigned number of bits, return the number of bits. Otherwise return 0



240
241
242
243
# File 'lib/udb/schema.rb', line 240

def num_bits(min, max)
    return 0 unless min == 0
    is_power_of_two?(max+1) ? max.bit_length : 0
end

#single_value?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'lib/udb/schema.rb', line 177

def single_value?
    @schema_hash.key?("const")
end

#to_hHash

Returns Hash representation of the JSON Schema.

Returns:

  • (Hash)

    Hash representation of the JSON Schema



32
# File 'lib/udb/schema.rb', line 32

def to_h = @schema_hash

#to_idl_typeIdl::Type

Returns THe IDL-equivalent type for this schema object.

Returns:

  • (Idl::Type)

    THe IDL-equivalent type for this schema object



246
247
248
# File 'lib/udb/schema.rb', line 246

def to_idl_type
  Idl::Type.from_json_schema(@schema_hash)
end

#to_pretty_s(schema_hash = @schema_hash) ⇒ String

Returns A human-readable description of the schema.

Returns:

  • (String)

    A human-readable description of the schema

Raises:

  • (ArgumentError)


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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/udb/schema.rb', line 65

def to_pretty_s(schema_hash = @schema_hash)
  raise ArgumentError, "Expecting hash" unless schema_hash.is_a?(Hash)
  raise ArgumentError, "Expecting non-empty hash" if schema_hash.empty?

  if schema_hash.key?("const")
    large2hex(schema_hash["const"])
  elsif schema_hash.key?("enum")
    "[#{schema_hash["enum"].join(', ')}]"
  elsif schema_hash.key?("type")
    case schema_hash["type"]
    when "integer"
      min = schema_hash["minimum"]
      minstr = large2hex(min)
      max = schema_hash["maximum"]
      maxstr = large2hex(max)
      if min && max
        sz = num_bits(min, max)
        (sz > 0) ? "#{sz}-bit integer" : "#{minstr} to #{maxstr}"
      elsif min
        "&#8805; #{minstr}"
      elsif max
        "&#8804; #{maxstr}"
      else
        "integer"
      end
    when "string"
      format = schema_hash["format"]
      pattern = schema_hash["pattern"]
      if format
        format
      elsif pattern
        "string matching #{pattern}"
      else
        "string"
      end
    when "boolean"
      "boolean"
    when "array"
      items = schema_hash["items"]
      min_items = schema_hash["minItems"]
      max_items = schema_hash["maxItems"]
      size_str = if min_items && max_items
        if min_items == max_items
            "#{min_items}-element "
        else
            "#{min_items}-element to #{max_items}-element "
        end
      elsif min_items
        "at least #{min_items}-element "
      elsif max_items
        "at most #{max_items}-element "
      else
        ""
      end

      array_str = if items.nil?
        size_str + "array"
      else
        if items.is_a?(Hash)
          "#{size_str}array of #{to_pretty_s(items)}"
        elsif items.is_a?(Array)
          str = size_str + "array where: +\n"
          items.each_with_index do |item,index|
            str = str + "&nbsp;&nbsp;[#{index}] is #{to_pretty_s(item)} +\n"
          end
          additional_items = schema_hash["additionalItems"]
          if additional_items
            str = str + "additional items are: +\n&nbsp;&nbsp;" +
              to_pretty_s(additional_items)
          end
          str
        else
          raise "to_pretty_s unknown array items #{items} in #{schema_hash}"
        end
      end

      if schema_hash.key?("contains")
        array_str = array_str + " Contains : [#{to_pretty_s(schema_hash["contains"])}]"
      end

      array_str
    else
      raise "to_pretty_s unknown type #{schema_hash["type"]} in #{schema_hash}"
    end
  else
    raise "Unsupported schema for #{schema_hash}"
  end
end

#type_prettyString

Returns Human-readable type of the schema (e.g., array, string, integer).

Returns:

  • (String)

    Human-readable type of the schema (e.g., array, string, integer)



53
54
55
56
57
58
59
60
61
62
# File 'lib/udb/schema.rb', line 53

def type_pretty
  if @schema_hash.key?("const")
    rb_obj_to_jsonschema_type(@schema_hash["const"])
  elsif @schema_hash.key?("enum") && !@schema_hash["enum"].empty? && @schema_hash["enum"].all? { |elem| elem.class == @schema_hash["enum"][0].class }
    rb_obj_to_jsonschema_type(@schema_hash["enum"][0])
  else
    raise "Missing type information for '#{@schema_hash}'" unless @schema_hash.key?("type")
    @schema_hash["type"]
  end
end

#validate(rb_value) ⇒ Boolean

Parameters:

  • rb_value (T.untyped)

Returns:

  • (Boolean)


26
27
28
29
# File 'lib/udb/schema.rb', line 26

def validate(rb_value)
  schemer = JSONSchemer.schema(@schema_hash)
  schemer.valid?(rb_value)
end

#valueObject



181
182
183
184
185
# File 'lib/udb/schema.rb', line 181

def value
  raise "Schema is not a single value" unless single_value?

  @schema_hash["const"]
end