Class: Pubid::Iec::Identifier

Inherits:
Pubid::Identifier show all
Defined in:
lib/pubid/iec/identifier.rb

Constant Summary collapse

IEC_TYPE_MAP =

Polymorphic type map for lutaml::Model key_value serialization. Maps polymorphic_name -> class name for from_hash dispatch. Includes the compound wrappers (Consolidated/Vap/Sheet) and the synthetic SingleIdentifier base, which appear as nested _type values even though they aren't identifier_types. Validated against build_type_map by spec.

{
  "pubid:iec:international-standard" => "Pubid::Iec::Identifiers::InternationalStandard",
  "pubid:iec:technical-specification" => "Pubid::Iec::Identifiers::TechnicalSpecification",
  "pubid:iec:technical-report" => "Pubid::Iec::Identifiers::TechnicalReport",
  "pubid:iec:publicly-available-specification" => "Pubid::Iec::Identifiers::PubliclyAvailableSpecification",
  "pubid:iec:guide" => "Pubid::Iec::Identifiers::Guide",
  "pubid:iec:operational-document" => "Pubid::Iec::Identifiers::OperationalDocument",
  "pubid:iec:component-specification" => "Pubid::Iec::Identifiers::ComponentSpecification",
  "pubid:iec:conformity-assessment" => "Pubid::Iec::Identifiers::ConformityAssessment",
  "pubid:iec:societal-technology-trend-report" => "Pubid::Iec::Identifiers::SocietalTechnologyTrendReport",
  "pubid:iec:systems-reference-document" => "Pubid::Iec::Identifiers::SystemsReferenceDocument",
  "pubid:iec:technology-report" => "Pubid::Iec::Identifiers::TechnologyReport",
  "pubid:iec:technical-group" => "Pubid::Iec::Identifiers::TechnicalGroup",
  "pubid:iec:test-report-form" => "Pubid::Iec::Identifiers::TestReportForm",
  "pubid:iec:white-paper" => "Pubid::Iec::Identifiers::WhitePaper",
  "pubid:iec:working-document" => "Pubid::Iec::Identifiers::WorkingDocument",
  "pubid:iec:amendment" => "Pubid::Iec::Identifiers::Amendment",
  "pubid:iec:corrigendum" => "Pubid::Iec::Identifiers::Corrigendum",
  "pubid:iec:interpretation-sheet" => "Pubid::Iec::Identifiers::InterpretationSheet",
  "pubid:iec:fragment-identifier" => "Pubid::Iec::Identifiers::FragmentIdentifier",
  "pubid:iec:consolidated-identifier" => "Pubid::Iec::Identifiers::ConsolidatedIdentifier",
  "pubid:iec:vap-identifier" => "Pubid::Iec::Identifiers::VapIdentifier",
  "pubid:iec:sheet-identifier" => "Pubid::Iec::Identifiers::SheetIdentifier",
  "pubid:iec:base" => "Pubid::Iec::Identifiers::Base",
  "pubid:iec:single-identifier" => "Pubid::Iec::SingleIdentifier",
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Pubid::Identifier

apply_mappings, #base, #base_document, concrete_class_for, #dated_version_of?, #draft_of?, #drop_supplements, #edition_of?, #eql?, #exclude, from_hash, #has_supplement?, #hash, #includes?, #initialize, #matches?, #mr_all_parts, #mr_edition, #mr_languages, #mr_number, #mr_number_with_part, #mr_part, #mr_publisher, #mr_subpart, #mr_supplement_suffix, #mr_type, #mr_year, #new_edition_of?, polymorphic_name, polymorphic_type_map, #related_to?, #render, #resolve_urn_generator, #root, #sibling_of?, #supplement_of?, #to_hash, #to_mr_string, #to_s, #to_slug, #to_supplement_s, #to_urn, #urn_supplement_type, #urn_type_code, #year

Constructor Details

This class inherits a constructor from Pubid::Identifier

Class Method Details

.build_type_mapObject

Build the type map from the live class list, for the validation spec.



111
112
113
114
115
116
# File 'lib/pubid/iec/identifier.rb', line 111

def self.build_type_map
  types = Pubid::Iec.identifier_types
  extra = [Identifiers::ConsolidatedIdentifier, Identifiers::VapIdentifier,
           Identifiers::SheetIdentifier, Identifiers::Base, SingleIdentifier]
  (types + extra).uniq.to_h { |klass| [klass.polymorphic_name, klass.name] }
end

.default_publisherObject

The publisher implied when none is serialized (IEC for every type).



36
37
38
# File 'lib/pubid/iec/identifier.rb', line 36

def self.default_publisher
  ::Pubid::Iec::Components::Publisher.new(body: "IEC")
end

.parse(string) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/pubid/iec/identifier.rb', line 314

def self.parse(string)
  if string.length > Pubid::MAX_INPUT_LENGTH
    raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
  end

  # Route URN strings to the URN parser (mirrors Iso::Identifier.parse)
  if Pubid::FormatDetector.detect(string) == :urn
    return Pubid::Iec::UrnParser.parse(string)
  end

  # Apply legacy update_codes normalization first, before any other preprocessing
  normalized = Core::UpdateCodes.apply(string, :iec)
  parsed = Pubid::Iec::Parser.new.parse(normalized)
  if parsed.nil? || parsed.empty?
    raise Pubid::Iec::Parser::ParseError,
          "Invalid identifier format"
  end

  Pubid::Iec::Builder.new.build(parsed)
end

.published_typed_stageObject

The class's published typed_stage (canonical surface form), or nil for types without a published stage.



48
49
50
51
52
53
54
55
56
57
# File 'lib/pubid/iec/identifier.rb', line 48

def self.published_typed_stage
  return nil unless const_defined?(:TYPED_STAGES)

  ts = self::TYPED_STAGES.find { |t| t.stage_code.to_s == "published" }
  return nil unless ts

  ts = ts.dup
  ts.original_abbr = ts.canonical_abbreviation
  ts
end

Instance Method Details

#all_parts_from_kv(model, value) ⇒ Object



284
285
286
# File 'lib/pubid/iec/identifier.rb', line 284

def all_parts_from_kv(model, value)
  model.all_parts = value
end

#all_parts_to_kv(model, doc) ⇒ Object

--- all_parts: omit the false default ---



278
279
280
281
282
# File 'lib/pubid/iec/identifier.rb', line 278

def all_parts_to_kv(model, doc)
  return unless model.all_parts

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("all_parts", true))
end

#build_code(value) ⇒ Object



170
171
172
173
174
# File 'lib/pubid/iec/identifier.rb', line 170

def build_code(value)
  return if value.nil? || value.to_s.empty?

  ::Pubid::Iec::Components::Code.new(value: value.to_s)
end

#copublishers_from_kv(model, value) ⇒ Object



268
269
270
271
272
273
274
275
# File 'lib/pubid/iec/identifier.rb', line 268

def copublishers_from_kv(model, value)
  list = Array(value).map(&:to_s)
  return unless list.any?

  model.copublishers = list.map do |cp|
    ::Pubid::Iec::Components::Publisher.new(body: cp)
  end
end

#copublishers_to_kv(model, doc) ⇒ Object



259
260
261
262
263
264
265
266
# File 'lib/pubid/iec/identifier.rb', line 259

def copublishers_to_kv(model, doc)
  cp = model.copublishers
  return unless cp&.any?

  doc.add_child(
    Lutaml::KeyValue::DataModel::Element.new("copublishers", cp.map(&:body)),
  )
end

#day_from_kv(model, value) ⇒ Object



226
227
228
229
230
# File 'lib/pubid/iec/identifier.rb', line 226

def day_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  (model.date ||= ::Pubid::Components::Date.new).day = value.to_s
end

#day_to_kv(model, doc) ⇒ Object



219
220
221
222
223
224
# File 'lib/pubid/iec/identifier.rb', line 219

def day_to_kv(model, doc)
  d = model.date&.day
  return if d.nil? || d.to_s.empty?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("day", d.to_s))
end

#emit_code(doc, key, code) ⇒ Object



163
164
165
166
167
168
# File 'lib/pubid/iec/identifier.rb', line 163

def emit_code(doc, key, code)
  v = code.is_a?(::Pubid::Components::Code) ? code.value : code
  return if v.nil? || v.to_s.empty?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new(key, v.to_s))
end

#month_from_kv(model, value) ⇒ Object



213
214
215
216
217
# File 'lib/pubid/iec/identifier.rb', line 213

def month_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  (model.date ||= ::Pubid::Components::Date.new).month = value.to_s
end

#month_to_kv(model, doc) ⇒ Object



206
207
208
209
210
211
# File 'lib/pubid/iec/identifier.rb', line 206

def month_to_kv(model, doc)
  m = model.date&.month
  return if m.nil? || m.to_s.empty?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("month", m.to_s))
end

#number_from_kv(model, value) ⇒ Object



157
# File 'lib/pubid/iec/identifier.rb', line 157

def number_from_kv(model, value) = model.number = build_code(value)

#number_to_kv(model, doc) ⇒ Object

--- Code components <-> plain string ---



156
# File 'lib/pubid/iec/identifier.rb', line 156

def number_to_kv(model, doc) = emit_code(doc, "number", model.number)

#part_from_kv(model, value) ⇒ Object



159
# File 'lib/pubid/iec/identifier.rb', line 159

def part_from_kv(model, value) = model.part = build_code(value)

#part_to_kv(model, doc) ⇒ Object



158
# File 'lib/pubid/iec/identifier.rb', line 158

def part_to_kv(model, doc) = emit_code(doc, "part", model.part)

#publisher_from_kv(model, value) ⇒ Object



253
254
255
256
257
# File 'lib/pubid/iec/identifier.rb', line 253

def publisher_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  model.publisher = ::Pubid::Iec::Components::Publisher.new(body: value.to_s)
end

#publisher_to_kv(model, doc) ⇒ Object

--- publisher: primary only when non-default; copublishers as a list ---



246
247
248
249
250
251
# File 'lib/pubid/iec/identifier.rb', line 246

def publisher_to_kv(model, doc)
  pub = model.publisher&.body
  return if pub.nil? || pub == model.class.default_publisher&.body

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("publisher", pub))
end

#stageObject



66
67
68
# File 'lib/pubid/iec/identifier.rb', line 66

def stage
  typed_stage&.to_stage
end

#stage_from_kv(model, value) ⇒ Object

Resolve the typed-stage code back within this identifier's class.



301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/pubid/iec/identifier.rb', line 301

def stage_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  ts = (model.class.const_defined?(:TYPED_STAGES) &&
        model.class::TYPED_STAGES.find { |t| t.code.to_s == value.to_s }) ||
       Pubid::Iec.all_typed_stages.find { |t| t.code.to_s == value.to_s }
  return unless ts

  ts = ts.dup
  ts.original_abbr = ts.canonical_abbreviation
  model.typed_stage = ts
end

#stage_iteration_from_kv(model, value) ⇒ Object



185
186
187
188
189
190
# File 'lib/pubid/iec/identifier.rb', line 185

def stage_iteration_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  model.stage_iteration =
    ::Pubid::Components::Iteration.new(number: value.to_s)
end

#stage_iteration_to_kv(model, doc) ⇒ Object



176
177
178
179
180
181
182
183
# File 'lib/pubid/iec/identifier.rb', line 176

def stage_iteration_to_kv(model, doc)
  iter = model.stage_iteration
  v = iter.is_a?(::Pubid::Components::Iteration) ? iter.number : iter
  return if v.nil? || v.to_s.empty?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("stage_iteration",
                                                        v.to_s))
end

#stage_to_kv(model, doc) ⇒ Object

Serialize typed_stage as just its unique code (e.g. "cd", "fdis"); the published default is omitted (recomputed from the class on load).



290
291
292
293
294
295
296
297
298
# File 'lib/pubid/iec/identifier.rb', line 290

def stage_to_kv(model, doc)
  ts = model.typed_stage
  return unless ts&.code
  return if ts.stage_code.to_s == "published"

  doc.add_child(
    Lutaml::KeyValue::DataModel::Element.new("stage", ts.code.to_s),
  )
end

#subpart_from_kv(model, value) ⇒ Object



161
# File 'lib/pubid/iec/identifier.rb', line 161

def subpart_from_kv(model, value) = model.subpart = build_code(value)

#subpart_to_kv(model, doc) ⇒ Object



160
# File 'lib/pubid/iec/identifier.rb', line 160

def subpart_to_kv(model, doc) = emit_code(doc, "subpart", model.subpart)

#typeObject

type and generic stage are derived from typed_stage, never stored — so the doctype (fixed by the class / _type) can't be lost when "stage" is omitted for the published default.



62
63
64
# File 'lib/pubid/iec/identifier.rb', line 62

def type
  typed_stage&.to_type
end

#undated_from_kv(model, value) ⇒ Object



241
242
243
# File 'lib/pubid/iec/identifier.rb', line 241

def undated_from_kv(model, value)
  (model.date ||= ::Pubid::Components::Date.new).undated = value.to_s == "true"
end

#undated_to_kv(model, doc) ⇒ Object

--- date undated flag (IEC undated reference, e.g. IEC 60050:--) --- The false default is omitted; only the meaningful true round-trips via to_hash / from_hash.



235
236
237
238
239
# File 'lib/pubid/iec/identifier.rb', line 235

def undated_to_kv(model, doc)
  return unless model.date&.undated?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("undated", true))
end

#year_from_kv(model, value) ⇒ Object



200
201
202
203
204
# File 'lib/pubid/iec/identifier.rb', line 200

def year_from_kv(model, value)
  return if value.nil? || value.to_s.empty?

  (model.date ||= ::Pubid::Components::Date.new).year = value.to_s
end

#year_to_kv(model, doc) ⇒ Object

--- date serialized flat as year/month/day ---



193
194
195
196
197
198
# File 'lib/pubid/iec/identifier.rb', line 193

def year_to_kv(model, doc)
  y = model.date&.year
  return if y.nil? || y.to_s.empty?

  doc.add_child(Lutaml::KeyValue::DataModel::Element.new("year", y.to_s))
end