class VRT::Map

Constants

DEPTH_MAP

Attributes

structure[R]
version[R]

Public Class Methods

new(version = nil) click to toggle source
# File lib/vrt/map.rb, line 11
def initialize(version = nil)
  @version = version || VRT.current_version
  @structure = build_structure
  @_found_nodes = {}
  @_lineages = {}
  @_valid_vrt_ids = {}
  @_valid_identifiers = {}
end

Public Instance Methods

categories() click to toggle source

Returns list of top level categories in the shape:

{ value: category_id, label: category_name }
# File lib/vrt/map.rb, line 34
def categories
  structure.keys.map do |key|
    node = find_node(key.to_s, max_depth: 'category')
    { value: node.id, label: node.name }
  end
end
find_node(string, max_depth: 'variant') click to toggle source
# File lib/vrt/map.rb, line 20
def find_node(string, max_depth: 'variant')
  @_found_nodes[string + max_depth] ||= walk_node_tree(string, max_depth: max_depth)
end
get_lineage(string, max_depth: 'variant') click to toggle source
# File lib/vrt/map.rb, line 28
def get_lineage(string, max_depth: 'variant')
  @_lineages[string + max_depth] ||= construct_lineage(string, max_depth)
end
valid?(vrt_id) click to toggle source
# File lib/vrt/map.rb, line 24
def valid?(vrt_id)
  @_valid_vrt_ids[vrt_id] ||= valid_identifier?(vrt_id) && !find_node(vrt_id).nil?
end

Private Instance Methods

build_node(memo, vrt, parent = nil) click to toggle source
# File lib/vrt/map.rb, line 85
def build_node(memo, vrt, parent = nil)
  node = Node.new(vrt.merge('version' => @version, 'parent' => parent))
  node.children = vrt['children'].reduce({}) { |m, v| build_node(m, v, node) } if node.children?
  memo[node.id] = node
  memo
end
build_structure() click to toggle source
# File lib/vrt/map.rb, line 81
def build_structure
  VRT.get_json(version: @version).reduce({}, &method(:build_node))
end
construct_lineage(string, max_depth) click to toggle source
# File lib/vrt/map.rb, line 51
def construct_lineage(string, max_depth)
  return unless valid_identifier?(string)

  lineage = ''
  walk_node_tree(string, max_depth: max_depth) do |ids, node, level|
    return unless node

    lineage += node.name
    lineage += ' > ' unless level == ids.length
  end
  lineage
end
valid_identifier?(vrt_id) click to toggle source
# File lib/vrt/map.rb, line 43
def valid_identifier?(vrt_id)
  # The upstream json schema in the VRT has changed so we need to support both:
  # Current: At least one string of lowercase letters or _, plus up to 2 more with stops (no digits)
  # and Old: At least one string of lowercase letters, numbers, or _,
  #          plus up to 2 more with stops and no leading numbers
  @_valid_identifiers[vrt_id] ||= vrt_id =~ /other|\A[a-z][a-z_\d]*(\.[a-z][a-z_\d]*){0,2}\z/
end
walk_node_tree(string, max_depth: 'variant') { |ids, node, level| ... } click to toggle source
# File lib/vrt/map.rb, line 64
def walk_node_tree(string, max_depth: 'variant')
  id_tokens = string.split('.').map(&:to_sym)
  ids = id_tokens.take(DEPTH_MAP[max_depth])
  node = @structure[ids[0]]
  ids.each_index do |idx|
    level = idx + 1
    yield(ids, node, level) if block_given?
    node = search(ids, node, level)
  end
  node
end