lutaml-model 0.8.99 → 0.8.101

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41d8d37a85f86f8d8f30d632c36526fe311ba0156f01a096a15717627f29ec72
4
- data.tar.gz: f15221cd4017756a1045502f77b588df6ae8f3e62ff39b38ac10c8d6f4a68115
3
+ metadata.gz: 70de43228d2b233faab386c9016139160f2b75e9f76c27386de22104df2820f5
4
+ data.tar.gz: 78b4591ba8eec19bbc7fde9a1fd2d298c58094b1198352f2323067406d39b5aa
5
5
  SHA512:
6
- metadata.gz: 509fc9f6462f37013113fdcb7a582ca70e9ce0ff021b51c780f9afdd66c03ec2c62213bd0c76a680dc993db138182b7260ed821757b37946b2b61941e2b9b066
7
- data.tar.gz: e01bb47f5085c77f6ce840f31ac4f9f243271846267f1083c2c099cfae7f2ced2979f73a61a3a44ea0b0d609b9176a6e8d64e8841994c794382fd0a16c0880f2
6
+ metadata.gz: f1d54790ba8f6d44834134ef283b3d146002e3ca4f2e25f0fb99e84bd442878d6470d50f6da81f36a8e4165e93c07e2e3a6de2cffeb981f45b40d849a6be1037
7
+ data.tar.gz: 4d358cd375296cdb737fa12300076a4154f38aa22ce940cbcb7483453691152d4cbfd25fef88131fe1150105868eb9a1d56fa193028f3bd51eff7eb853d43c09
@@ -901,3 +901,28 @@ The generated schema will include validation constraints:
901
901
  </define>
902
902
  </grammar>
903
903
  ----
904
+
905
+ == Documentation metadata (desc)
906
+
907
+ Models and attributes carry documentation strings through `desc` —
908
+ set on the model class or on any `attribute` declaration, read back
909
+ by documentation and schema tooling. Serialization is never affected
910
+ by it.
911
+
912
+ [source,ruby]
913
+ ----
914
+ class Title < Lutaml::Model::Serializable
915
+ desc "This is a title."
916
+
917
+ attribute :type, :string, desc: "This attribute is used for..."
918
+ end
919
+
920
+ Title.desc # => "This is a title."
921
+ Title.attributes[:type].desc # => "This attribute is used for..."
922
+ ----
923
+
924
+ Subclasses inherit the nearest ancestor's class description; an
925
+ explicit `desc` overrides it. A consumer override-free `desc` value
926
+ does not change any generated schema today — wiring `desc` into the
927
+ generated `description` fields is deliberate product scope, not a
928
+ free rider on this option.
@@ -46,6 +46,7 @@ module Lutaml
46
46
  signed
47
47
  min_length
48
48
  max_length
49
+ desc
49
50
  ].freeze
50
51
 
51
52
  # Per-type-class memo of the custom from_xml/from_json probe used by #cast.
@@ -641,6 +642,12 @@ instance_object = nil)
641
642
  options[:pattern]
642
643
  end
643
644
 
645
+ # Documentation metadata (#356): the `:desc` attribute option,
646
+ # consumed by documentation and schema tooling.
647
+ def desc
648
+ options[:desc]
649
+ end
650
+
644
651
  # Performance: Frozen empty array to reduce allocations
645
652
  EMPTY_VALUES_ARRAY = [].freeze
646
653
 
@@ -505,6 +505,22 @@ module Lutaml
505
505
  end
506
506
  end
507
507
 
508
+ # Class-level documentation metadata (#356): `desc "text"` on
509
+ # the model class; a zero-argument call reads it back.
510
+ # Subclasses inherit the nearest ancestor's description — an
511
+ # explicit `desc` overrides. Consumed by documentation and
512
+ # schema tooling; the serialization paths never read it.
513
+ def desc(text = nil)
514
+ return @lutaml_desc = text if text
515
+
516
+ return @lutaml_desc if defined?(@lutaml_desc)
517
+
518
+ if superclass.is_a?(::Class) &&
519
+ superclass < ::Lutaml::Model::Serializable
520
+ superclass.desc
521
+ end
522
+ end
523
+
508
524
  # Define an attribute for the model
509
525
  #
510
526
  # @param name [Symbol] The attribute name
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.99"
5
+ VERSION = "0.8.101"
6
6
  end
7
7
  end
@@ -240,7 +240,7 @@ module Lutaml
240
240
  when :raw
241
241
  Array(value).each { |raw| element.add_child(raw.to_s) }
242
242
  when :content, :content_deferred
243
- Array(value).each { |run| element.add_child(doc.create_text_node(run.to_s)) }
243
+ Array(value).each { |run| append_text(element, run.to_s, doc) }
244
244
  end
245
245
  end
246
246
  end
@@ -426,10 +426,33 @@ module Lutaml
426
426
  def add_leaf(element, name, value, doc, attrs: nil)
427
427
  child = element.create_child(name)
428
428
  attrs&.each { |k, v| child[k.to_s] = v.to_s }
429
- child.add_child(doc.create_text_node(value.to_s)) unless value.nil?
429
+ append_text(child, value.to_s, doc) unless value.nil?
430
430
  child
431
431
  end
432
432
 
433
+ # Text attach: the address face (leptris#408 adoption,
434
+ # leptris 1.9.334) passes raw node addresses — the pointer
435
+ # face mints an FFI::Pointer wrapper per fresh node, the
436
+ # last per-row Ruby-side allocation on the DOM build. Same
437
+ # semantics and status contract; probe-gated because a
438
+ # numerically newer lockstep can publish without the face.
439
+ def append_text(parent, text, doc)
440
+ node = doc.create_text_node(text)
441
+ if Leptris.text_attach_addr_compatible?
442
+ status = ::Leptris::XML::FFI.leptris_element_add_child_addr(
443
+ parent.c_address, node.c_address
444
+ )
445
+ unless status.zero?
446
+ raise ::Leptris::XML::Error,
447
+ "text attach failed (status=#{status})"
448
+ end
449
+
450
+ node
451
+ else
452
+ parent.add_child(node)
453
+ end
454
+ end
455
+
433
456
  def value_of(instance, attr, delegate)
434
457
  if delegate
435
458
  target = instance.public_send(delegate)
@@ -97,6 +97,19 @@ module Lutaml
97
97
  spec && spec.version >= Gem::Version.new(MIN_LEPTRIS_NS_UNQUALIFIED_VERSION)
98
98
  end
99
99
 
100
+ # The address-based text attach (leptris#408, binding 1.9.334):
101
+ # leptris_element_add_child_addr skips the per-node FFI pointer
102
+ # mint. Capability-probed, not version-gated — the FFI face is
103
+ # attached or it is not, and a lockstep can publish without it.
104
+ @text_attach_addr = nil
105
+ def self.text_attach_addr_compatible?
106
+ return @text_attach_addr unless @text_attach_addr.nil?
107
+
108
+ @text_attach_addr =
109
+ !!(defined?(::Leptris::XML::FFI) &&
110
+ ::Leptris::XML::FFI.respond_to?(:leptris_element_add_child_addr))
111
+ end
112
+
100
113
  autoload :PlanCompiler, "lutaml/xml/leptris/plan_compiler"
101
114
  autoload :PlanHydrator, "lutaml/xml/leptris/plan_hydrator"
102
115
  autoload :PlanOrder, "lutaml/xml/leptris/plan_order"
data/lutaml-model.gemspec CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
34
 
35
35
  # required for liquid
36
- spec.add_dependency "base64"
36
+ spec.add_dependency "base64", ">= 0.1.1"
37
37
  spec.add_dependency "bigdecimal"
38
38
  spec.add_dependency "canon"
39
39
  spec.add_dependency "concurrent-ruby"
@@ -44,7 +44,7 @@ Gem::Specification.new do |spec|
44
44
  spec.add_dependency "moxml", "~> 0.5.84"
45
45
  spec.add_dependency "ostruct"
46
46
  spec.add_dependency "rubyzip", "~> 3.7"
47
- spec.add_dependency "thor"
47
+ spec.add_dependency "thor", "~> 1.4"
48
48
 
49
49
  spec.metadata["rubygems_mfa_required"] = "true"
50
50
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../spec_helper"
4
+
5
+ RSpec.describe "Documentation metadata (desc)" do
6
+ let(:widget_class) do
7
+ Class.new(Lutaml::Model::Serializable) do
8
+ desc "A widget."
9
+
10
+ attribute :name, :string, desc: "The widget name."
11
+ attribute :size, :integer
12
+ end
13
+ end
14
+
15
+ it "stores and reads the class-level description" do
16
+ expect(widget_class.desc).to eq("A widget.")
17
+ end
18
+
19
+ it "returns nil when no description is set" do
20
+ plain = Class.new(Lutaml::Model::Serializable)
21
+ expect(plain.desc).to be_nil
22
+ end
23
+
24
+ it "inherits the description on subclasses" do
25
+ child = Class.new(widget_class)
26
+ expect(child.desc).to eq("A widget.")
27
+ end
28
+
29
+ it "lets a subclass override the description" do
30
+ child = Class.new(widget_class) do
31
+ desc "A special widget."
32
+ end
33
+ expect(child.desc).to eq("A special widget.")
34
+ end
35
+
36
+ it "does not leak an override back to the superclass" do
37
+ Class.new(widget_class) { desc "Child only." }
38
+ expect(widget_class.desc).to eq("A widget.")
39
+ end
40
+
41
+ it "stores the attribute-level description" do
42
+ expect(widget_class.attributes[:name].desc).to eq("The widget name.")
43
+ expect(widget_class.attributes[:size].desc).to be_nil
44
+ end
45
+
46
+ it "keeps serialization untouched" do
47
+ widget = widget_class.new(name: "w", size: 3)
48
+ expect(widget.to_hash).to eq("name" => "w", "size" => 3)
49
+ end
50
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.99
4
+ version: 0.8.101
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.1.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.1.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bigdecimal
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -132,16 +132,16 @@ dependencies:
132
132
  name: thor
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
- - - ">="
135
+ - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '0'
137
+ version: '1.4'
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - ">="
142
+ - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '0'
144
+ version: '1.4'
145
145
  description: 'LutaML creating data models in Ruby
146
146
 
147
147
  '
@@ -1742,6 +1742,7 @@ files:
1742
1742
  - spec/lutaml/model/deferred_type_no_materialize_spec.rb
1743
1743
  - spec/lutaml/model/delegation_spec.rb
1744
1744
  - spec/lutaml/model/derived_attribute_serialization_spec.rb
1745
+ - spec/lutaml/model/desc_spec.rb
1745
1746
  - spec/lutaml/model/dynamic_attribute_spec.rb
1746
1747
  - spec/lutaml/model/encoding_spec.rb
1747
1748
  - spec/lutaml/model/enum_spec.rb