Class: Pubid::Bsi::Identifier

Inherits:
Identifier
  • Object
show all
Defined in:
lib/pubid/bsi/model.rb,
lib/pubid/bsi/single_identifier.rb

Overview

BSI base class. Canonical name Pubid::Bsi::Identifier; SingleIdentifier is a back-compat alias (BSI's common ancestor — there is no Identifiers::Base). Every concrete BSI identifier descends from it, so they are all is_a?(Pubid::Bsi::Identifier) natively and get the shared polymorphic from_hash (no facade needed).

Constant Summary collapse

SERIES_CATEGORIES =

Annex F series groupings per "Rules for the structure and drafting of UK standards" (BSI, 2017), F.1.3-F.1.5. Each maps a prefix token to the broader series category.

{
  # F.1.3 Automobile
  "AU" => :automotive,
  # F.1.4 Aerospace
  "A" => :aerospace, "B" => :aerospace, "C" => :aerospace,
  "F" => :aerospace, "G" => :aerospace, "HC" => :aerospace,
  "L" => :aerospace, "S" => :aerospace, "SP" => :aerospace,
  "X" => :aerospace, "M" => :aerospace, "TA" => :aerospace,
  "2A" => :aerospace, "2B" => :aerospace, "2C" => :aerospace,
  "2F" => :aerospace, "2G" => :aerospace, "2HC" => :aerospace,
  "2HR" => :aerospace, "2L" => :aerospace, "2M" => :aerospace,
  "2S" => :aerospace, "2SP" => :aerospace, "2TA" => :aerospace,
  "2X" => :aerospace, "3A" => :aerospace, "3B" => :aerospace,
  "3F" => :aerospace, "3G" => :aerospace, "3HR" => :aerospace,
  "3J" => :aerospace, "3L" => :aerospace, "3S" => :aerospace,
  "3TA" => :aerospace, "4F" => :aerospace, "4L" => :aerospace,
  "4S" => :aerospace, "5S" => :aerospace, "7S" => :aerospace,
  # F.1.5 Marine
  "MA" => :marine, "PL" => :marine, "QC" => :marine,
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from 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_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

.parse(string) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/pubid/bsi/single_identifier.rb', line 11

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

  # Delegate to IEC for bare IEC identifiers. This handles IEC-specific
  # features like VAP suffixes (CSV, RLV, etc.) and consolidated
  # supplements (+AMD1:2001).
  if string.match?(/\bIEC\b/) &&
      (string.match?(/\s+(CSV|CMV|RLV|SER|EXV|PAC|PRV)\b/) ||
       string.match?(/\+AMD\d+:/) ||
       string.match?(/\+COR\d+:/))
    return Pubid::Iec.parse(string)
  end

  parser = Parser.new

  parsed = parser.parse(string)
  Builder.build(parsed)
rescue Parslet::ParseFailed => e
  raise StandardError, "Failed to parse '#{string}': #{e.message}"
end

Instance Method Details

#<=>(other) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/pubid/bsi/single_identifier.rb', line 56

def <=>(other)
  return nil unless other.is_a?(Pubid::Bsi::Identifier)

  # Compare by number first
  num_cmp = number.to_s <=> other.number.to_s
  return num_cmp unless num_cmp.zero?

  # Then by part
  part_cmp = (part || Components::Code.new(value: "0")).to_s <=> (other.part || Components::Code.new(value: "0")).to_s
  return part_cmp unless part_cmp.zero?

  # Then by date
  if date && other.date
    date.to_s <=> other.date.to_s
  elsif date
    1
  elsif other.date
    -1
  else
    0
  end
end

#aerospace?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/pubid/bsi/single_identifier.rb', line 119

def aerospace?
  series_category == :aerospace
end

#automotive?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/pubid/bsi/single_identifier.rb', line 115

def automotive?
  series_category == :automotive
end

#marine?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/pubid/bsi/single_identifier.rb', line 123

def marine?
  series_category == :marine
end

#seriesObject

Series accessor — semantically named alias for prefix per issue #252. Returns the prefix token (e.g., "AU", "MA", "2A").



105
106
107
# File 'lib/pubid/bsi/single_identifier.rb', line 105

def series
  prefix
end

#series_categoryObject

Series category — one of :automotive, :aerospace, :marine, or nil when the identifier doesn't carry a recognized Annex F prefix.



111
112
113
# File 'lib/pubid/bsi/single_identifier.rb', line 111

def series_category
  SERIES_CATEGORIES[prefix.to_s] if prefix
end

#to_sObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/pubid/bsi/model.rb', line 76

def to_s
  # Handle national annex
  if national_annex
    return render_national_annex
  end

  # Handle expert commentary
  if expert_commentary
    base_id = self.class.new(
      type: type,
      number: number,
      part: part,
      year: year,
      month: month,
      supplements: supplements,
      adopted: adopted,
    )
    return "#{base_id} ExComm"
  end

  # Handle collection (combined documents)
  if second_number
    return render_collection
  end

  # Regular identifier
  render_identifier
end