Module: GovCodes::AFSC::RI
- Defined in:
- lib/gov_codes/afsc/ri.rb
Overview
Reporting Identifiers (RI) and Special Duty Identifiers (SDI), resolved against the versioned classification-directory release indexes. RI/SDI codes live in BOTH directories under two different code grammars:
Enlisted (DAFECD), 5-char: \d[A-Z]\d{3}[A-Z]? e.g. 9Z200, 8R300A
Officer (DAFOCD), 4-char: \d{2}[A-Z]\d[A-Z]? e.g. 90G0, 92T1
A single find entry point dispatches by shape to the matching
publication's ri.yml index (Releases.ri_index). Entries share the shape of
enlisted/officer specialty records (:name, :acronym, :shredouts,
:shredout_acronyms), so shredout suffixes and acronyms resolve exactly as
they do for Enlisted/Officer.
Defined Under Namespace
Class Method Summary collapse
-
.find(code, as_of: nil) ⇒ Object
Resolve an RI/SDI code against the release in effect on
as_of(default: today). -
.find_by_acronym(acronym, as_of: nil) ⇒ Object
Resolve the RI/SDI code whose acronym matches
acronym(case-insensitive) in the release in effect onas_of. -
.reset_data(lookup: $LOAD_PATH) ⇒ Object
Clears the memoized lookups and resets the versioned release loader.
-
.search(prefix, as_of: nil) ⇒ Object
Walk both publications' RI/SDI indexes for the release in effect on
as_of, emitting each base code and its shredout-suffixed combinations, and return the Codes whose code starts withprefix.
Class Method Details
.find(code, as_of: nil) ⇒ Object
Resolve an RI/SDI code against the release in effect on as_of (default:
today). Dispatches by code shape to the enlisted (DAFECD) or officer
(DAFOCD) ri.yml index. Returns nil when the code parses as neither shape,
when the resolved index lacks the code, or when as_of precedes the
earliest shipped release for the relevant publication.
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 |
# File 'lib/gov_codes/afsc/ri.rb', line 115 def self.find(code, as_of: nil) code = code.to_s parsed = Parser.new(code).parse publication = parsed[:publication] return nil unless publication # Key the memo on the RESOLVED release date so equivalent as_of values # (nil, the Date, its string form) share one slot. effective_date = Releases.effective_date_for(as_of: as_of, publication: publication) CODES[[code, effective_date]] ||= begin index = Releases.ri_index(as_of: as_of, publication: publication) entry = index[parsed[:specific_ri]] return nil unless entry suffix = parsed[:suffix] # Shredout suffix meaning, only when the directory documents it. shredout_name = suffix && entry.dig(:shredouts, suffix) name = shredout_name || entry[:name] return nil if name.nil? # A documented shredout acronym wins for a shredded code; otherwise the # entry's own acronym (which a consumer overlay may set). shredout_acronym = suffix && entry.dig(:shredout_acronyms, suffix) Code.new( career_group: parsed[:career_group], career_field: parsed[:career_field], identifier: parsed[:identifier], suffix: suffix, specific_ri: parsed[:specific_ri], name: name, acronym: shredout_acronym || entry[:acronym], effective_date: effective_date ) end end |
.find_by_acronym(acronym, as_of: nil) ⇒ Object
Resolve the RI/SDI code whose acronym matches acronym (case-insensitive)
in the release in effect on as_of. Scans the enlisted index first, then
the officer index; within an entry the entry's own acronym is tried before
its shredout acronyms (a shredout match returns the concrete shredded
code). First match wins. Returns nil when no acronym in the resolved
release(s) matches (no leakage across document dates).
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/gov_codes/afsc/ri.rb', line 158 def self.find_by_acronym(acronym, as_of: nil) acronym = acronym.to_s.upcase return nil if acronym.empty? [Releases::ENLISTED_PUBLICATION, Releases::OFFICER_PUBLICATION].each do |publication| index = Releases.ri_index(as_of: as_of, publication: publication) index.each do |code, entry| return find(code.to_s, as_of: as_of) if entry[:acronym].to_s.upcase == acronym (entry[:shredout_acronyms] || {}).each do |suffix, acr| return find("#{code}#{suffix}", as_of: as_of) if acr.to_s.upcase == acronym end end end nil end |
.reset_data(lookup: $LOAD_PATH) ⇒ Object
Clears the memoized lookups and resets the versioned release loader. The
lookup keyword is accepted for interface parity with Enlisted/Officer;
the versioned index is resolved from the load path at lookup time.
201 202 203 204 |
# File 'lib/gov_codes/afsc/ri.rb', line 201 def self.reset_data(lookup: $LOAD_PATH) Releases.reset! CODES.clear end |
.search(prefix, as_of: nil) ⇒ Object
Walk both publications' RI/SDI indexes for the release in effect on
as_of, emitting each base code and its shredout-suffixed combinations,
and return the Codes whose code starts with prefix.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/gov_codes/afsc/ri.rb', line 178 def self.search(prefix, as_of: nil) prefix = prefix.to_s.upcase codes = [] [Releases::ENLISTED_PUBLICATION, Releases::OFFICER_PUBLICATION].each do |publication| index = Releases.ri_index(as_of: as_of, publication: publication) index.each do |code, entry| code_str = code.to_s codes << code_str (entry[:shredouts] || {}).each_key do |suffix| codes << "#{code_str}#{suffix}" end end end codes.select { |code| code.start_with?(prefix) } .map { |code| find(code, as_of: as_of) } .compact end |