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: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

#base_identifier, #eql?, #exclude, #hash, #initialize, #mr_number, #mr_number_with_part, #mr_part, #mr_publisher, #mr_type, #mr_year, #new_edition_of?, polymorphic_name, #render, #resolve_urn_generator, #root, #to_mr_string, #to_s, #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.



102
103
104
105
106
107
# File 'lib/pubid/iec/identifier.rb', line 102

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

.from_hash(data, options = {}) ⇒ Object

lutaml’s polymorphic key_value mapping reads ‘_type` only to validate; it does not re-instantiate the concrete subclass on root deserialization. So `Identifier.from_hash(amendment_hash)` would return a bare Identifier and drop base_identifier. Route by `_type` to the right subclass and let its (inherited) from_hash do the real work, mirroring ISO/JIS.



283
284
285
286
287
288
289
290
291
# File 'lib/pubid/iec/identifier.rb', line 283

def self.from_hash(data, options = {})
  type = data["_type"] || data[:_type]
  klass_name = IEC_TYPE_MAP[type]
  if klass_name
    klass = Object.const_get(klass_name)
    return klass.from_hash(data, options) unless klass == self
  end
  super
end

.parse(string) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/pubid/iec/identifier.rb', line 261

def self.parse(string)
  # 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



231
232
233
# File 'lib/pubid/iec/identifier.rb', line 231

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 —



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

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



156
157
158
159
160
# File 'lib/pubid/iec/identifier.rb', line 156

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



215
216
217
218
219
220
221
222
# File 'lib/pubid/iec/identifier.rb', line 215

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



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

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

#emit_code(doc, key, code) ⇒ Object



149
150
151
152
153
154
# File 'lib/pubid/iec/identifier.rb', line 149

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

#number_from_kv(model, value) ⇒ Object



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

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

#number_to_kv(model, doc) ⇒ Object

— Code components <-> plain string —



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

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

#part_from_kv(model, value) ⇒ Object



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

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

#part_to_kv(model, doc) ⇒ Object



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

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

#publisher_from_kv(model, value) ⇒ Object



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

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 —



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

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.



248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/pubid/iec/identifier.rb', line 248

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



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

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



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

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).



237
238
239
240
241
242
243
244
245
# File 'lib/pubid/iec/identifier.rb', line 237

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



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

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

#subpart_to_kv(model, doc) ⇒ Object



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

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

#year_from_kv(model, value) ⇒ Object



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

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 <-> scalar year (IEC dates are year-only) —



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

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