Module: GovCodes::DataLoader

Defined in:
lib/gov_codes/data_loader.rb

Overview

DataLoader module provides shared functionality for loading YAML data from multiple paths in the lookup array

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



7
8
9
10
# File 'lib/gov_codes/data_loader.rb', line 7

def self.extended(base)
  base.const_set(:CODES, {})
  base.private_constant(:CODES)
end

Instance Method Details

#data(lookup: $LOAD_PATH) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/gov_codes/data_loader.rb', line 12

def data(lookup: $LOAD_PATH)
  data = {}
  lookup_array = Array(lookup)
  return data if lookup_array.empty?

  # Add the gem's lib directory to the lookup path
  gem_lib_dir = File.expand_path("..", __dir__)
  lookup_paths = [gem_lib_dir] + lookup_array

  # Convert namespace to file path parts (e.g., "GovCodes::AFSC::Enlisted" -> ["gov_codes", "afsc", "enlisted.yml"])
  namespace_parts = name.split("::")
    .map { |part| part.gsub(/([A-Z])([a-z])/, '_\1\2').downcase.sub(/^_/, "") }
  namespace_parts[-1] = "#{namespace_parts[-1]}.yml"

  # Find all existing YAML files in lookup paths
  lookup_paths.filter_map do |dir|
    yaml_path = File.join(dir, *namespace_parts)
    yaml_path if File.exist?(yaml_path)
  end.uniq.each do |path|
    yaml_data = YAML.load_file(path, symbolize_names: true)
    data.merge!(yaml_data) if yaml_data.is_a?(Hash)
  rescue Psych::SyntaxError, TypeError
    # Handle invalid YAML gracefully
    next
  end

  data
end

#find_name_recursive(result) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/gov_codes/data_loader.rb', line 67

def find_name_recursive(result)
  base_code = result[:career_field].to_sym
  base_data = self::DATA[base_code]
  return "Unknown" unless base_data

  # Try subcategory lookup if present
  if result[:subcategory]
    subdivision = base_data.dig(:subcategories, result[:subcategory])
    if subdivision
      # Try shredout lookup if present
      if result[:shredout]
        shredout_name = subdivision.dig(:subcategories, result[:shredout], :name)
        return shredout_name if shredout_name
      end
      return subdivision[:name] if subdivision[:name]
    end
  end

  base_data[:name] || "Unknown"
end

#flat_overlay(basename, lookup: $LOAD_PATH) ⇒ Object

Load and merge a flat overlay YAML map (e.g. a consumer acronyms overlay) named basename under gov_codes/afsc across the load path. Files loaded later win, so a consumer file merges over any shipped one. Returns {} when none exist; malformed files are skipped (graceful degradation).



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/gov_codes/data_loader.rb', line 52

def flat_overlay(basename, lookup: $LOAD_PATH)
  merged = {}
  gem_lib_dir = File.expand_path("..", __dir__)
  ([gem_lib_dir] + Array(lookup)).uniq.each do |dir|
    path = File.join(dir, "gov_codes", "afsc", basename)
    next unless File.exist?(path)

    overlay = YAML.load_file(path, symbolize_names: true)
    merged.merge!(overlay) if overlay.is_a?(Hash)
  rescue Psych::SyntaxError, TypeError
    next
  end
  merged
end

#reset_data(lookup: $LOAD_PATH) ⇒ Object



41
42
43
44
45
46
# File 'lib/gov_codes/data_loader.rb', line 41

def reset_data(lookup: $LOAD_PATH)
  remove_const(:DATA) if const_defined?(:DATA, false)
  const_set(:DATA, data(lookup:).freeze)
  remove_const(:CODES) if const_defined?(:CODES, false)
  const_set(:CODES, {})
end