pubid 2.0.0.pre.alpha.3 → 2.0.0.pre.alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pubid/amca/identifier.rb +4 -23
  3. data/lib/pubid/amca/identifiers/base.rb +67 -30
  4. data/lib/pubid/amca/identifiers/interpretation.rb +0 -4
  5. data/lib/pubid/amca/identifiers/publication.rb +0 -4
  6. data/lib/pubid/amca/identifiers/standard.rb +0 -4
  7. data/lib/pubid/amca/renderer.rb +1 -1
  8. data/lib/pubid/amca/urn_generator.rb +2 -1
  9. data/lib/pubid/api/builder.rb +4 -0
  10. data/lib/pubid/api/identifier.rb +5 -1
  11. data/lib/pubid/api/identifiers/base.rb +2 -12
  12. data/lib/pubid/api/identifiers/mpms.rb +0 -4
  13. data/lib/pubid/api/identifiers/typeless_standard.rb +0 -3
  14. data/lib/pubid/api/single_identifier.rb +5 -8
  15. data/lib/pubid/ashrae/identifier.rb +7 -22
  16. data/lib/pubid/ashrae/identifiers/base.rb +28 -17
  17. data/lib/pubid/ashrae/parser.rb +4 -0
  18. data/lib/pubid/ashrae.rb +4 -0
  19. data/lib/pubid/asme/single_identifier.rb +3 -1
  20. data/lib/pubid/astm/single_identifier.rb +3 -1
  21. data/lib/pubid/bsi/identifier.rb +5 -31
  22. data/lib/pubid/bsi/identifiers/addendum_document.rb +0 -4
  23. data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +0 -4
  24. data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +0 -4
  25. data/lib/pubid/bsi/identifiers/aerospace_standard.rb +0 -3
  26. data/lib/pubid/bsi/identifiers/amendment.rb +0 -4
  27. data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -3
  28. data/lib/pubid/bsi/identifiers/bundled_identifier.rb +2 -5
  29. data/lib/pubid/bsi/identifiers/committee_document.rb +0 -3
  30. data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +2 -5
  31. data/lib/pubid/bsi/identifiers/corrigendum.rb +0 -4
  32. data/lib/pubid/bsi/identifiers/detailed_specification.rb +0 -3
  33. data/lib/pubid/bsi/identifiers/disc.rb +0 -3
  34. data/lib/pubid/bsi/identifiers/draft_document.rb +0 -3
  35. data/lib/pubid/bsi/identifiers/electronic_book.rb +0 -3
  36. data/lib/pubid/bsi/identifiers/expert_commentary.rb +0 -4
  37. data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +0 -3
  38. data/lib/pubid/bsi/identifiers/flex.rb +0 -3
  39. data/lib/pubid/bsi/identifiers/handbook.rb +0 -3
  40. data/lib/pubid/bsi/identifiers/index.rb +0 -3
  41. data/lib/pubid/bsi/identifiers/method.rb +0 -3
  42. data/lib/pubid/bsi/identifiers/national_annex.rb +0 -3
  43. data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -3
  44. data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +0 -3
  45. data/lib/pubid/bsi/identifiers/published_document.rb +0 -3
  46. data/lib/pubid/bsi/identifiers/section.rb +0 -3
  47. data/lib/pubid/bsi/identifiers/set.rb +2 -5
  48. data/lib/pubid/bsi/identifiers/standalone_amendment.rb +0 -3
  49. data/lib/pubid/bsi/identifiers/supplement_document.rb +0 -4
  50. data/lib/pubid/bsi/identifiers/supplementary_index.rb +0 -3
  51. data/lib/pubid/bsi/identifiers/technical_specification.rb +0 -3
  52. data/lib/pubid/bsi/identifiers/test_method.rb +0 -3
  53. data/lib/pubid/bsi/identifiers/value_added_publication.rb +0 -4
  54. data/lib/pubid/bsi/single_identifier.rb +32 -13
  55. data/lib/pubid/bsi.rb +8 -1
  56. data/lib/pubid/ccsds/identifier.rb +2 -14
  57. data/lib/pubid/cen_cenelec/identifier.rb +10 -8
  58. data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +0 -4
  59. data/lib/pubid/cen_cenelec/identifiers/amendment.rb +0 -4
  60. data/lib/pubid/cen_cenelec/identifiers/base.rb +2 -9
  61. data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +0 -4
  62. data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +0 -4
  63. data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +0 -3
  64. data/lib/pubid/cen_cenelec/identifiers/fragment.rb +0 -4
  65. data/lib/pubid/cen_cenelec/single_identifier.rb +4 -7
  66. data/lib/pubid/cen_cenelec.rb +4 -0
  67. data/lib/pubid/cie/identifier.rb +4 -0
  68. data/lib/pubid/cie/single_identifier.rb +4 -4
  69. data/lib/pubid/cie.rb +4 -0
  70. data/lib/pubid/csa/identifier.rb +10 -1
  71. data/lib/pubid/csa/identifiers/base.rb +0 -3
  72. data/lib/pubid/csa/identifiers/cec.rb +0 -4
  73. data/lib/pubid/csa/identifiers/series.rb +0 -4
  74. data/lib/pubid/csa/single_identifier.rb +1 -1
  75. data/lib/pubid/csa.rb +4 -0
  76. data/lib/pubid/etsi/components/code.rb +1 -7
  77. data/lib/pubid/etsi/components/version.rb +0 -5
  78. data/lib/pubid/etsi/identifier.rb +4 -12
  79. data/lib/pubid/etsi/identifiers/base.rb +31 -24
  80. data/lib/pubid/etsi/identifiers/supplement_identifier.rb +0 -3
  81. data/lib/pubid/etsi.rb +3 -1
  82. data/lib/pubid/identifier.rb +90 -1
  83. data/lib/pubid/idf/identifier.rb +4 -0
  84. data/lib/pubid/idf.rb +4 -0
  85. data/lib/pubid/iec/identifier.rb +14 -14
  86. data/lib/pubid/iec/identifiers/base.rb +0 -4
  87. data/lib/pubid/iec/identifiers/consolidated_identifier.rb +0 -4
  88. data/lib/pubid/iec/identifiers/fragment_identifier.rb +1 -5
  89. data/lib/pubid/iec/identifiers/sheet_identifier.rb +1 -5
  90. data/lib/pubid/iec/identifiers/test_report_form.rb +0 -3
  91. data/lib/pubid/iec/identifiers/vap_identifier.rb +1 -5
  92. data/lib/pubid/iec/identifiers/working_document.rb +0 -4
  93. data/lib/pubid/iec.rb +4 -0
  94. data/lib/pubid/ieee/identifier.rb +5 -17
  95. data/lib/pubid/ieee/identifiers/adopted_standard.rb +0 -4
  96. data/lib/pubid/ieee/identifiers/base.rb +223 -201
  97. data/lib/pubid/ieee/identifiers/conformance_identifier.rb +0 -4
  98. data/lib/pubid/ieee/identifiers/corrigendum.rb +0 -4
  99. data/lib/pubid/ieee/identifiers/csa_dual_published.rb +0 -4
  100. data/lib/pubid/ieee/identifiers/dual_identifier.rb +0 -4
  101. data/lib/pubid/ieee/identifiers/dual_published.rb +0 -4
  102. data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +0 -4
  103. data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +0 -4
  104. data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +0 -4
  105. data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +0 -4
  106. data/lib/pubid/ieee/identifiers/redlined_standard.rb +0 -4
  107. data/lib/pubid/ieee/identifiers/si_standard.rb +0 -4
  108. data/lib/pubid/ieee.rb +4 -0
  109. data/lib/pubid/iho/identifier.rb +7 -25
  110. data/lib/pubid/iho/identifiers/base.rb +62 -68
  111. data/lib/pubid/iho.rb +3 -1
  112. data/lib/pubid/iso/identifier.rb +15 -14
  113. data/lib/pubid/iso/single_identifier.rb +0 -4
  114. data/lib/pubid/iso.rb +4 -0
  115. data/lib/pubid/itu/components/code.rb +1 -7
  116. data/lib/pubid/itu/components/sector.rb +15 -4
  117. data/lib/pubid/itu/components/series.rb +0 -4
  118. data/lib/pubid/itu/identifier.rb +4 -18
  119. data/lib/pubid/itu/identifiers/base.rb +124 -122
  120. data/lib/pubid/itu.rb +3 -1
  121. data/lib/pubid/jcgm/identifiers/amendment.rb +0 -4
  122. data/lib/pubid/jcgm/identifiers/gum_guide.rb +0 -4
  123. data/lib/pubid/jcgm/single_identifier.rb +0 -4
  124. data/lib/pubid/jis/identifier.rb +2 -14
  125. data/lib/pubid/nist/identifier.rb +8 -23
  126. data/lib/pubid/nist/identifiers/base.rb +553 -544
  127. data/lib/pubid/nist/preprocessor.rb +12 -0
  128. data/lib/pubid/nist.rb +4 -0
  129. data/lib/pubid/oiml/builder.rb +21 -3
  130. data/lib/pubid/oiml/components/code.rb +7 -0
  131. data/lib/pubid/oiml/identifier.rb +44 -0
  132. data/lib/pubid/oiml/identifiers/annex.rb +10 -1
  133. data/lib/pubid/oiml/identifiers/errata.rb +15 -0
  134. data/lib/pubid/oiml/identifiers.rb +1 -1
  135. data/lib/pubid/oiml/parser.rb +59 -12
  136. data/lib/pubid/oiml/renderer.rb +27 -17
  137. data/lib/pubid/oiml/single_identifier.rb +58 -0
  138. data/lib/pubid/oiml/supplement_identifier.rb +30 -1
  139. data/lib/pubid/plateau/identifier.rb +4 -21
  140. data/lib/pubid/plateau/identifiers/base.rb +45 -36
  141. data/lib/pubid/plateau/identifiers/handbook.rb +0 -4
  142. data/lib/pubid/plateau/identifiers/technical_report.rb +0 -4
  143. data/lib/pubid/plateau/supplement_identifier.rb +0 -4
  144. data/lib/pubid/sae/identifier.rb +4 -12
  145. data/lib/pubid/sae/identifiers/base.rb +26 -17
  146. data/lib/pubid/version.rb +1 -1
  147. data/lib/pubid.rb +18 -2
  148. data/lib/tasks/export.rake +6 -5
  149. metadata +3 -4
  150. data/lib/pubid/identifier_facade.rb +0 -114
  151. data/lib/pubid/oiml/identifiers/base.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 296a51f39ef14271b7b66a8403042c4a35b214eb3e858c2a926ab9104e74acfa
4
- data.tar.gz: 9dcdd6b5082ea2cc6b866078f7c749e687fd4f76ad767b94ed77347700f2a6c2
3
+ metadata.gz: fd077b48356a46dfb52d7b95e932c29e91e5fe1a7859c1128ddda22d768b4a96
4
+ data.tar.gz: 4e8059d20bed9297393f54bb894958a6c0ab8d92bef895fcb7528c291b3ff349
5
5
  SHA512:
6
- metadata.gz: 974c5db378c9461c7636b47525054a7351fd136de2493710767abbb198e40fdadf7e21a9c9273d3bbe79707c301509e21aaea30eeae3d09931b11029e5cf69ae
7
- data.tar.gz: 16d304dcd9a960da1386e46d692425e3c9a7153be96130187def4c02c9fc22e192bd4374956ee526678bbfe04add13ab50c71d625b860e0d6c65cd157ef12248
6
+ metadata.gz: 329f3776c53f4021bfd2d25bd8698fb9c01309a66f56e9334d815aee3fde8ce25b509637f97ffc4ef91f0dfb67d10768a33505a939109a305d34b2e917af8f6c
7
+ data.tar.gz: 79c43b4e3ca83fe379a588f20490850e6a88757e382f0f9b9fc88d9f31923aff8fd8a5d48670c33a0d0705747820c6b3548260334ebf4e63a09b60dab82ad4ec
@@ -1,25 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Pubid
4
- module Amca
5
- # NOTE: this flavor intentionally does NOT `extend Pubid::IdentifierFacade`
6
- # (nor include it in Identifiers::Base). The facade's identity check makes
7
- # `is_a?(<Flavor>::Identifier)` true, which routes the object through a
8
- # consumer's `to_hash` (e.g. relaton-index#save) — but AMCA's `to_hash`
9
- # currently raises (publisher is stored as a String, not a Publisher
10
- # component). Enabling the facade here would turn a non-crashing path into a
11
- # crash. Re-enable once AMCA serialization round-trips cleanly.
12
- module Identifier
13
- # Parse an ACMA identifier string into an identifier object
14
- # @param identifier [String] The ACMA identifier string to parse
15
- # @return [Pubid::Amca::Identifier] The appropriate identifier object
16
- # @raise [Parslet::ParseFailed] If parsing fails
17
- def self.parse(identifier)
18
- parsed = Parser.parse(identifier)
19
- Builder.build(parsed)
20
- rescue Parslet::ParseFailed => e
21
- raise "Failed to parse ACMA identifier '#{identifier}': #{e.message}"
22
- end
23
- end
24
- end
25
- end
3
+ # Pubid::Amca::Identifier is the AMCA base class (a real Pubid::Identifier
4
+ # subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
5
+ # live in identifiers/base.rb. This file just ensures it is loaded.
6
+ require_relative "identifiers/base"
@@ -2,37 +2,74 @@
2
2
 
3
3
  module Pubid
4
4
  module Amca
5
- module Identifiers
6
- # Base identifier class for ACMA identifiers
7
- # Single Responsibility: Common functionality for all ACMA identifier types
8
- class Base < Pubid::Identifier
9
- # Override base_hash to handle AMCA-specific copublisher format (string, not array)
10
- def base_hash
11
- hash = super
12
- # AMCA's copublisher is a string, not an array, so remove it from copublishers
13
- hash.delete(:copublishers) if hash[:copublishers]
14
- hash
15
- end
16
-
17
- attribute :copublisher, :string
18
- attribute :code, Components::Code
19
- attribute :year, Components::Date
20
- attribute :suffix, :string
21
- attribute :reaffirmed, :string
22
-
23
- # AMCA uses a fixed publisher string
24
- def publisher
25
- "AMCA"
26
- end
27
-
28
- def self.parse(string)
29
- Amca::Identifier.parse(string)
30
- end
31
-
32
- def to_urn
33
- UrnGenerator.new(self).generate
34
- end
5
+ # Base identifier class for AMCA identifiers. Canonical name
6
+ # Pubid::Amca::Identifier (Identifiers::Base is a back-compat alias); common
7
+ # functionality for all AMCA identifier types.
8
+ class Identifier < ::Pubid::Identifier
9
+ # @raise [Parslet::ParseFailed] If parsing fails
10
+ def self.parse(identifier)
11
+ parsed = Parser.parse(identifier)
12
+ Builder.build(parsed)
13
+ rescue Parslet::ParseFailed => e
14
+ raise "Failed to parse ACMA identifier '#{identifier}': #{e.message}"
15
+ end
16
+
17
+ # Stored as a plain string (always "AMCA") so it round-trips through
18
+ # to_hash/from_hash. Was a `def publisher` method, which made lutaml
19
+ # serialize a String against the Components::Publisher attribute and raise.
20
+ attribute :publisher, :string, default: -> { "AMCA" }
21
+ attribute :copublisher, :string
22
+ attribute :code, Components::Code
23
+ attribute :year, Components::Date
24
+ attribute :suffix, :string
25
+ attribute :reaffirmed, :string
26
+
27
+ # Explicit key_value mapping: only these keys serialize (the inherited
28
+ # Pubid::Identifier attributes — including :type, which subclasses expose
29
+ # as a class-metadata Hash via `self.type` — are intentionally dropped).
30
+ # code/year are flattened to their scalar value and rebuilt on load, since
31
+ # the Builder may store them as either a String or a component.
32
+ key_value do
33
+ map "_type", to: :_type
34
+ map "publisher", to: :publisher
35
+ map "copublisher", to: :copublisher
36
+ map "code", with: { to: :code_to_kv, from: :code_from_kv }
37
+ map "year", with: { to: :year_to_kv, from: :year_from_kv }
38
+ map "suffix", to: :suffix
39
+ map "reaffirmed", to: :reaffirmed
40
+ end
41
+
42
+ def to_urn
43
+ UrnGenerator.new(self).generate
35
44
  end
45
+
46
+ def code_to_kv(model, doc)
47
+ v = model.code.is_a?(::Pubid::Components::Code) ? model.code.value : model.code
48
+ return if v.nil? || v.to_s.empty?
49
+
50
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("code", v.to_s))
51
+ end
52
+
53
+ def code_from_kv(model, value)
54
+ model.code = ::Pubid::Components::Code.new(value: value.to_s)
55
+ end
56
+
57
+ def year_to_kv(model, doc)
58
+ y = model.year.is_a?(::Pubid::Components::Date) ? model.year.year : model.year
59
+ return if y.nil? || y.to_s.empty?
60
+
61
+ doc.add_child(Lutaml::KeyValue::DataModel::Element.new("year", y.to_s))
62
+ end
63
+
64
+ def year_from_kv(model, value)
65
+ model.year = ::Pubid::Components::Date.new(year: value.to_s)
66
+ end
67
+ end
68
+
69
+ module Identifiers
70
+ # Backward-compatible alias: AMCA's base class used to be
71
+ # Pubid::Amca::Identifiers::Base. It is now Pubid::Amca::Identifier.
72
+ Base = Pubid::Amca::Identifier
36
73
  end
37
74
  end
38
75
  end
@@ -24,10 +24,6 @@ reaffirmed: nil, interpretation_code: nil)
24
24
  def self.type
25
25
  { key: :interpretation, title: "Interpretation", short: "Interp" }
26
26
  end
27
-
28
- def type
29
- Interpretation.type
30
- end
31
27
  end
32
28
  end
33
29
  end
@@ -24,10 +24,6 @@ reaffirmed: nil, revision: nil)
24
24
  def self.type
25
25
  { key: :publication, title: "Publication", short: nil }
26
26
  end
27
-
28
- def type
29
- Publication.type
30
- end
31
27
  end
32
28
  end
33
29
  end
@@ -12,10 +12,6 @@ module Pubid
12
12
  def self.type
13
13
  { key: :standard, title: "Standard", short: nil }
14
14
  end
15
-
16
- def type
17
- Standard.type
18
- end
19
15
  end
20
16
  end
21
17
  end
@@ -31,7 +31,7 @@ module Pubid
31
31
  def render_base(id)
32
32
  parts = []
33
33
  parts << id.copublisher if id.copublisher
34
- t = id.class.attributes.key?(:type) ? id.type : nil
34
+ t = id.class.respond_to?(:type) ? id.class.type : nil
35
35
  if t.is_a?(Hash) && t[:title]
36
36
  parts << t[:title].to_s
37
37
  end
@@ -28,7 +28,8 @@ module Pubid
28
28
  end
29
29
 
30
30
  def urn_type
31
- identifier.type&.to_s&.downcase
31
+ (identifier.class.respond_to?(:type) ? identifier.class.type : nil)
32
+ &.to_s&.downcase
32
33
  end
33
34
 
34
35
  def generate
@@ -26,6 +26,10 @@ module Pubid
26
26
 
27
27
  def cast(key, value)
28
28
  case key
29
+ # `:type` is consumed only by select_class for dispatch; it is not an
30
+ # identifier attribute (the concrete class is pinned by `_type`). Drop it
31
+ # so the raw Parslet::Slice never lands in the inherited :type attribute.
32
+ when :type then nil
29
33
  when :number then Components::Code.new(value: value.to_s)
30
34
  when :reaffirmation
31
35
  value.is_a?(Hash) ? (value[:year] || value).to_s : value.to_s
@@ -2,7 +2,11 @@
2
2
 
3
3
  module Pubid
4
4
  module Api
5
- class Identifier
5
+ # Common base class for all API identifiers. SingleIdentifier and the
6
+ # concrete Identifiers::* types descend from it, so every API identifier is
7
+ # `is_a?(Pubid::Api::Identifier)` natively and gets the shared polymorphic
8
+ # `from_hash` (no facade needed).
9
+ class Identifier < ::Pubid::Identifier
6
10
  def self.parse(input)
7
11
  # Filter out comments
8
12
  return nil if input.start_with?("#")
@@ -3,19 +3,9 @@
3
3
  module Pubid
4
4
  module Api
5
5
  module Identifiers
6
+ # Base class for all API identifiers.
7
+ # Inherits common attributes from SingleIdentifier.
6
8
  class Base < SingleIdentifier
7
- # Base class for all API identifiers
8
- # Inherits common attributes from SingleIdentifier
9
-
10
- # Include type_string in serialization for round-trip compatibility
11
- def base_hash
12
- hash = super
13
- if self.class.attributes.key?(:type_string) && type_string
14
- hash[:type] =
15
- type_string
16
- end
17
- hash
18
- end
19
9
  end
20
10
  end
21
11
  end
@@ -12,10 +12,6 @@ module Pubid
12
12
  "MPMS"
13
13
  end
14
14
 
15
- def to_s
16
- render(format: :human)
17
- end
18
-
19
15
  private
20
16
 
21
17
  def code_portion
@@ -5,9 +5,6 @@ module Pubid
5
5
  module Identifiers
6
6
  class TypelessStandard < Base
7
7
  # No type_string method - renders without type
8
- def to_s
9
- render(format: :human)
10
- end
11
8
  end
12
9
  end
13
10
  end
@@ -2,24 +2,21 @@
2
2
 
3
3
  module Pubid
4
4
  module Api
5
- class SingleIdentifier < Pubid::Identifier
5
+ class SingleIdentifier < Identifier
6
6
  # Generate URN for this identifier
7
7
  #
8
8
  # @return [String] URN representation
9
9
 
10
- def publisher
11
- "API"
12
- end
10
+ # Stored as a plain string (always "API") so it round-trips through
11
+ # to_hash/from_hash. Was a `def publisher` method, which made lutaml
12
+ # serialize a String against the Components::Publisher attribute.
13
+ attribute :publisher, :string, default: -> { "API" }
13
14
 
14
15
  attribute :code, Components::Code
15
16
  attribute :part, :string
16
17
  attribute :year, :string
17
18
  attribute :reaffirmation, :string
18
19
 
19
- def to_s
20
- render(format: :human)
21
- end
22
-
23
20
  private
24
21
 
25
22
  def code_portion
@@ -1,24 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Pubid
4
- module Ashrae
5
- # `extend Pubid::IdentifierFacade` adds polymorphic `from_hash` and pairs
6
- # with `include Pubid::Ashrae::Identifier` in Identifiers::Base for identity
7
- # (`is_a?`/`===`), so a consumer handed this module can deserialize and
8
- # identity-check ASHRAE ids through it.
9
- module Identifier
10
- extend Pubid::IdentifierFacade
11
-
12
- # Parse an ASHRAE identifier string into an identifier object
13
- # @param identifier [String] The ASHRAE identifier string to parse
14
- # @return [Identifiers::Base] The appropriate identifier object
15
- # @raise [Parslet::ParseFailed] If parsing fails
16
- def self.parse(identifier)
17
- parsed = Parser.parse(identifier)
18
- Builder.build(parsed)
19
- rescue Parslet::ParseFailed => e
20
- raise "Failed to parse ASHRAE identifier '#{identifier}': #{e.message}"
21
- end
22
- end
23
- end
24
- end
3
+ # The ASHRAE flavor base class is Pubid::Ashrae::Identifier — a real
4
+ # Pubid::Identifier subclass that every concrete ASHRAE identifier descends
5
+ # from, so `is_a?` identity and the shared polymorphic `from_hash` work natively
6
+ # (no facade needed). Its body, `.parse`, and the Identifiers::Base back-compat
7
+ # alias live in identifiers/base.rb; this file just ensures it is loaded when a
8
+ # consumer references Pubid::Ashrae::Identifier directly.
9
+ require_relative "identifiers/base"
@@ -2,25 +2,36 @@
2
2
 
3
3
  module Pubid
4
4
  module Ashrae
5
- module Identifiers
6
- # Base class for all ASHRAE identifiers
7
- class Base < Pubid::Identifier
8
- # Identity for the Pubid::Ashrae::Identifier facade (see its comment).
9
- include Pubid::Ashrae::Identifier
5
+ # Base class for all ASHRAE identifiers. Canonical name
6
+ # Pubid::Ashrae::Identifier; every concrete ASHRAE identifier descends from
7
+ # it, and Identifiers::Base aliased at the foot of this file — points back
8
+ # to it.
9
+ class Identifier < ::Pubid::Identifier
10
+ # Parse an ASHRAE identifier string into an identifier object
11
+ # @param identifier [String] The ASHRAE identifier string to parse
12
+ # @return [Pubid::Ashrae::Identifier] The appropriate identifier object
13
+ # @raise [Parslet::ParseFailed] If parsing fails
14
+ def self.parse(identifier)
15
+ parsed = Parser.parse(identifier)
16
+ Builder.build(parsed)
17
+ rescue Parslet::ParseFailed => e
18
+ raise "Failed to parse ASHRAE identifier '#{identifier}': #{e.message}"
19
+ end
10
20
 
11
- attribute :publisher, :string, default: "ASHRAE"
12
- attribute :code, :string
13
- attribute :year, :string
14
- attribute :type, :string
15
- attribute :suffix, :string # R (revision), P (proposed), etc.
16
- attribute :amendment, :string
17
- attribute :reaffirmed, :string
18
- attribute :copublisher, :string
21
+ attribute :publisher, :string, default: "ASHRAE"
22
+ attribute :code, :string
23
+ attribute :year, :string
24
+ attribute :type, :string
25
+ attribute :suffix, :string # R (revision), P (proposed), etc.
26
+ attribute :amendment, :string
27
+ attribute :reaffirmed, :string
28
+ attribute :copublisher, :string
29
+ end
19
30
 
20
- def self.parse(string)
21
- Ashrae::Identifier.parse(string)
22
- end
23
- end
31
+ module Identifiers
32
+ # Backward-compatible alias: ASHRAE's base class used to be
33
+ # Pubid::Ashrae::Identifiers::Base. It is now Pubid::Ashrae::Identifier.
34
+ Base = Pubid::Ashrae::Identifier
24
35
  end
25
36
  end
26
37
  end
@@ -650,6 +650,10 @@ module Pubid
650
650
  root(:identifier)
651
651
 
652
652
  def self.parse(string)
653
+ if string.length > Pubid::MAX_INPUT_LENGTH
654
+ raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
655
+ end
656
+
653
657
  # Strip leading/trailing whitespace
654
658
  cleaned = string.strip
655
659
 
data/lib/pubid/ashrae.rb CHANGED
@@ -13,6 +13,10 @@ module Pubid
13
13
  autoload :UrnParser, "#{__dir__}/ashrae/urn_parser"
14
14
 
15
15
  def self.parse(identifier)
16
+ if identifier.length > Pubid::MAX_INPUT_LENGTH
17
+ raise ArgumentError, Pubid::INPUT_TOO_LONG_MESSAGE
18
+ end
19
+
16
20
  Identifier.parse(identifier)
17
21
  end
18
22
 
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Pubid
4
4
  module Asme
5
- class SingleIdentifier < Pubid::Identifier
5
+ # Descends from Pubid::Asme::Identifier (the flavor base) so every concrete
6
+ # ASME identifier is `is_a?(Pubid::Asme::Identifier)`.
7
+ class SingleIdentifier < Identifier
6
8
  # Generate URN for this identifier
7
9
  #
8
10
  # @return [String] URN representation
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Pubid
4
4
  module Astm
5
- class SingleIdentifier < Pubid::Identifier
5
+ # Descends from Pubid::Astm::Identifier (the flavor base) so every concrete
6
+ # ASTM identifier is `is_a?(Pubid::Astm::Identifier)`.
7
+ class SingleIdentifier < Identifier
6
8
  # Generate URN for this identifier
7
9
  #
8
10
  # @return [String] URN representation
@@ -1,33 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Pubid
4
- module Bsi
5
- # `extend Pubid::IdentifierFacade` adds polymorphic `from_hash` and pairs
6
- # with `include Pubid::Bsi::Identifier` in SingleIdentifier (BSI's common
7
- # ancestor — there is no Identifiers::Base) for identity (`is_a?`/`===`), so
8
- # a consumer handed this module can deserialize and identity-check BSI ids
9
- # through it.
10
- module Identifier
11
- extend Pubid::IdentifierFacade
12
-
13
- def self.parse(string)
14
- # Delegate to IEC for bare IEC identifiers
15
- # This handles IEC-specific features like VAP suffixes (CSV, RLV, etc.)
16
- # and consolidated supplements (+AMD1:2001)
17
- if string.match?(/\bIEC\b/) &&
18
- (string.match?(/\s+(CSV|CMV|RLV|SER|EXV|PAC|PRV)\b/) ||
19
- string.match?(/\+AMD\d+:/) ||
20
- string.match?(/\+COR\d+:/))
21
- return Pubid::Iec.parse(string)
22
- end
23
-
24
- parser = Parser.new
25
-
26
- parsed = parser.parse(string)
27
- Builder.build(parsed)
28
- rescue Parslet::ParseFailed => e
29
- raise StandardError, "Failed to parse '#{string}': #{e.message}"
30
- end
31
- end
32
- end
33
- end
3
+ # Pubid::Bsi::Identifier is the BSI base class (a real Pubid::Identifier
4
+ # subclass); its body, `.parse` (including the IEC-delegation logic), and the
5
+ # SingleIdentifier back-compat alias live in single_identifier.rb. This file
6
+ # just ensures it is loaded when a consumer references Pubid::Bsi::Identifier.
7
+ require_relative "single_identifier"
@@ -21,10 +21,6 @@ module Pubid
21
21
  ":"
22
22
  } # Separator before Addendum (":" or " ")
23
23
 
24
- def to_s(lang: :en, lang_single: false)
25
- render(format: :human, lang: lang, lang_single: lang_single)
26
- end
27
-
28
24
  def publisher
29
25
  base_identifier&.publisher
30
26
  end
@@ -25,10 +25,6 @@ module Pubid
25
25
  nil
26
26
  end
27
27
 
28
- def to_s(lang: :en, lang_single: false)
29
- render(format: :human, lang: lang, lang_single: lang_single)
30
- end
31
-
32
28
  # Delegate common methods to adopted identifier
33
29
  def number
34
30
  adopted_identifier&.number
@@ -25,10 +25,6 @@ module Pubid
25
25
  nil
26
26
  end
27
27
 
28
- def to_s
29
- render(format: :human)
30
- end
31
-
32
28
  # Delegate common methods to adopted identifier
33
29
  def number
34
30
  adopted_identifier&.number
@@ -59,9 +59,6 @@ module Pubid
59
59
  short: "BS" }
60
60
  end
61
61
 
62
- def to_s(lang: :en, lang_single: false)
63
- render(format: :human, lang: lang, lang_single: lang_single)
64
- end
65
62
  end
66
63
  end
67
64
  end
@@ -11,10 +11,6 @@ module Pubid
11
11
  attribute :amendment_year, :integer
12
12
  attribute :separator, :string, default: -> { "+" }
13
13
 
14
- def to_s
15
- render(format: :human)
16
- end
17
-
18
14
  def publisher
19
15
  base_identifier&.publisher
20
16
  end
@@ -16,9 +16,6 @@ module Pubid
16
16
  }
17
17
  end
18
18
 
19
- def to_s(lang: :en, lang_single: false)
20
- render(format: :human, lang: lang, lang_single: lang_single)
21
- end
22
19
  end
23
20
  end
24
21
  end
@@ -12,15 +12,12 @@ module Pubid
12
12
  # BS SP 13; 14; 15 and 16:1949
13
13
  # BS 4048:Parts 1 and 2:1966
14
14
  class BundledIdentifier < SingleIdentifier
15
- attribute :identifiers, ::Pubid::Identifier, collection: true, polymorphic: true
15
+ attribute :identifiers, ::Pubid::Identifier, collection: true,
16
+ polymorphic: true
16
17
  attribute :separators, :string, collection: true # Separators between identifiers
17
18
  attribute :common_year, Bsi::Components::Date # Year applied to all if present
18
19
  attribute :bundle_type, :string # "Parts", "Sections", or nil for regular bundles
19
20
 
20
- def to_s(lang: :en, lang_single: false)
21
- render(format: :human, lang: lang, lang_single: lang_single)
22
- end
23
-
24
21
  def <=>(other)
25
22
  return nil unless other.is_a?(BundledIdentifier)
26
23
 
@@ -29,9 +29,6 @@ module Pubid
29
29
  { key: :committee_document, title: "Committee Document", short: "DC" }
30
30
  end
31
31
 
32
- def to_s(lang: :en, lang_single: false)
33
- render(format: :human, lang: lang, lang_single: lang_single)
34
- end
35
32
  end
36
33
  end
37
34
  end
@@ -6,11 +6,8 @@ module Pubid
6
6
  # Consolidated Identifier - contains base document plus supplements
7
7
  # Example: "BS 4592-0:2006+A1:2012" = [BS 4592-0:2006, Amendment 1:2012]
8
8
  class ConsolidatedIdentifier < SingleIdentifier
9
- attribute :identifiers, ::Pubid::Identifier, polymorphic: true, collection: true
10
-
11
- def to_s(lang: :en, lang_single: false)
12
- render(format: :human, lang: lang, lang_single: lang_single)
13
- end
9
+ attribute :identifiers, ::Pubid::Identifier, polymorphic: true,
10
+ collection: true
14
11
 
15
12
  def to_urn
16
13
  base = identifiers&.first
@@ -11,10 +11,6 @@ module Pubid
11
11
  attribute :corrigendum_year, :integer
12
12
  attribute :separator, :string, default: -> { "+" }
13
13
 
14
- def to_s
15
- render(format: :human)
16
- end
17
-
18
14
  def publisher
19
15
  base_identifier&.publisher
20
16
  end
@@ -27,9 +27,6 @@ module Pubid
27
27
  }
28
28
  end
29
29
 
30
- def to_s(lang: :en, lang_single: false)
31
- render(format: :human, lang: lang, lang_single: lang_single)
32
- end
33
30
  end
34
31
  end
35
32
  end
@@ -21,9 +21,6 @@ module Pubid
21
21
  { key: :disc, title: "DISC", short: "DISC" }
22
22
  end
23
23
 
24
- def to_s(lang: :en, lang_single: false)
25
- render(format: :human, lang: lang, lang_single: lang_single)
26
- end
27
24
  end
28
25
  end
29
26
  end
@@ -21,9 +21,6 @@ module Pubid
21
21
  web: :draft_document, title: "Draft Document", short: "DD" }
22
22
  end
23
23
 
24
- def to_s(lang: :en, lang_single: false)
25
- render(format: :human, lang: lang, lang_single: lang_single)
26
- end
27
24
  end
28
25
  end
29
26
  end