Class: SchemaCondition

Inherits:
Object
  • Object
show all
Defined in:
lib/arch_obj_models/obj.rb

Overview

represents a JSON Schema compoisition, e.g.:

anyOf:

- oneOf:
  - A
  - B
- C

Constant Summary collapse

VERSION_REQ_REGEX =
/^((>=)|(>)|(~>)|(<)|(<=)|(=))?\s*[0-9]+(\.[0-9]+(\.[0-9]+(-[a-fA-F0-9]+)?)?)?$/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(composition_hash) ⇒ SchemaCondition

Returns a new instance of SchemaCondition.

Parameters:

  • composition_hash (Hash)

    A possibly recursive hash of “allOf”, “anyOf”, “oneOf”

Raises:

  • (ArgumentError)


267
268
269
270
271
272
273
274
275
# File 'lib/arch_obj_models/obj.rb', line 267

def initialize(composition_hash)
  raise ArgumentError, "composition_hash is nil" if composition_hash.nil?

  unless is_a_condition?(composition_hash)
    raise ArgumentError, "Expecting a JSON schema comdition (got #{composition_hash})"
  end

  @hsh = composition_hash
end

Class Method Details

.all_of(*conds) ⇒ Object

combine all conds into one using AND



364
365
366
367
368
369
370
# File 'lib/arch_obj_models/obj.rb', line 364

def self.all_of(*conds)
  cond = SchemaCondition.new({
    "allOf" => conds
  })

  SchemaCondition.new(cond.minimize)
end

Instance Method Details

#empty?Boolean

Returns:

  • (Boolean)


279
# File 'lib/arch_obj_models/obj.rb', line 279

def empty? = false

#first_requirement(req = @hsh) ⇒ ExtensionRequirement

Returns First requirement found, without considering any boolean operators.

Returns:



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/arch_obj_models/obj.rb', line 346

def first_requirement(req = @hsh)
  case req
  when String
    ExtensionRequirement.new(req, ">= 0")
  when Hash
    if req.key?("name")
      ExtensionRequirement.new(req["name"], req["version"] || ">= 0")
    else
      first_requirement(req[req.keys[0]])
    end
  when Array
    first_requirement(req[0])
  else
    raise "unexpected"
  end
end

#is_a_version_requirement(ver) ⇒ Object



282
283
284
285
286
287
288
289
290
291
# File 'lib/arch_obj_models/obj.rb', line 282

def is_a_version_requirement(ver)
  case ver
  when String
    ver =~ VERSION_REQ_REGEX
  when Array
    ver.all? { |v| v =~ VERSION_REQ_REGEX }
  else
    false
  end
end

#minimize(hsh = @hsh) ⇒ Object

Returns Schema for this condition, with basic logic minimization.

Returns:

  • (Object)

    Schema for this condition, with basic logic minimization



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/arch_obj_models/obj.rb', line 373

def minimize(hsh = @hsh)
  case hsh
  when Hash
    if hsh.key?("name")
      hsh
    else
      min_ary = key = nil
      if hsh.key?("allOf")
        min_ary = hsh["allOf"].map { |element| minimize(element) }
        key = "allOf"
      elsif hsh.key?("anyOf")
        min_ary = hsh["anyOf"].map { |element| minimize(element) }
        key = "anyOf"
      elsif hsh.key?("oneOf")
        min_ary = hsh["oneOf"].map { |element| minimize(element) }
        key = "oneOf"
      end
      min_ary = min_ary.uniq!
      if min_ary.size == 1
        min_ary.first
      else
        { key => min_ary }
      end
    end
  else
    hsh
  end
end

#satisfied_by? {|obj| ... } ⇒ Boolean

Returns Whether or not the entire condition is satisfied.

Examples:

See if a string satisfies

cond = { "anyOf" => ["A", "B", "C"] }
string = "A"
cond.satisfied_by? { |endpoint| endpoint == string } #=> true
string = "D"
cond.satisfied_by? { |endpoint| endpoint == string } #=> false

See if an array satisfies

cond = { "allOf" => ["A", "B", "C"] }
ary = ["A", "B", "C", "D"]
cond.satisfied_by? { |endpoint| ary.include?(endpoint) } #=> true
ary = ["A", "B"]
cond.satisfied_by? { |endpoint| ary.include?(endpoint) } #=> false

Yield Parameters:

  • obj (Object)

    An endpoint in the condition

Yield Returns:

  • (Boolean)

    Whether or not obj is what you are looking for

Returns:

  • (Boolean)

    Whether or not the entire condition is satisfied

Raises:

  • (ArgumentError)


466
467
468
469
470
471
472
# File 'lib/arch_obj_models/obj.rb', line 466

def satisfied_by?(&block)
  raise ArgumentError, "Missing required block" unless block_given?

  raise ArgumentError, "Expecting one argument to block" unless block.arity == 1

  eval to_rb
end

#to_asciidoc(cond = @hsh, indent = 0) ⇒ Object



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/arch_obj_models/obj.rb', line 293

def to_asciidoc(cond = @hsh, indent = 0)
  case cond
  when String
    "#{'*' * indent}* #{cond}, version >= 0"
  when Hash
    if cond.key?("name")
      if cond.key?("version")
        "#{'*' * indent}* #{cond['name']}, version #{cond['version']}\n"
      else
        "#{'*' * indent}* #{cond['name']}, version >= 0\n"
      end
    else
      "#{'*' * indent}* #{cond.keys[0]}:\n" + to_asciidoc(cond[cond.keys[0]], indent + 2)
    end
  when Array
    cond.map { |e| to_asciidoc(e, indent) }.join("\n")
  else
    raise "Unknown condition type: #{cond}"
  end
end

#to_hObject



277
# File 'lib/arch_obj_models/obj.rb', line 277

def to_h = @hsh

#to_rbBoolean

Given the name of a ruby array ary_name containing the available objects to test, return a string that can be eval’d to determine if the objects in ary_name meet the Condition

Parameters:

  • ary_name (String)

    Name of a ruby string in the eval binding

Returns:

  • (Boolean)

    If the condition is met



445
446
447
# File 'lib/arch_obj_models/obj.rb', line 445

def to_rb
  to_rb_helper(@hsh)
end

#to_rb_helper(hsh) ⇒ Object



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/arch_obj_models/obj.rb', line 402

def to_rb_helper(hsh)
  if hsh.is_a?(Hash)
    if hsh.key?("name")
      if hsh.key?("version")
        if hsh["version"].is_a?(String)
          "(yield ExtensionRequirement.new('#{hsh["name"]}', '#{hsh["version"]}'))"
        elsif hsh["version"].is_a?(Array)
          "(yield ExtensionRequirement.new('#{hsh["name"]}', #{hsh["version"].map { |v| "'#{v}'" }.join(', ')}))"
        else
          raise "unexpected"
        end
      else
        "(yield ExtensionRequirement.new('#{hsh["name"]}'))"
      end
    else
      key = hsh.keys[0]

      case key
      when "allOf"
        rb_str = hsh[key].map { |element| to_rb_helper(element) }.join(' && ')
        "(#{rb_str})"
      when "anyOf"
        rb_str = hsh[key].map { |element| to_rb_helper(element) }.join(' || ')
        "(#{rb_str})"
      when "oneOf"
        rb_str = hsh[key].map { |element| to_rb_helper(element) }.join(', ')
        "([#{rb_str}].count(true) == 1)"
      else
        raise "Unexpected"
        "(yield #{hsh})"
      end
    end
  else
    "(yield ExtensionRequirement.new('#{hsh}'))"
  end
end