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 +4 -4
- data/docs/_guides/schema-generation.adoc +25 -0
- data/lib/lutaml/model/attribute.rb +7 -0
- data/lib/lutaml/model/serialize/attribute_definition.rb +16 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/xml/leptris/plan_serializer.rb +25 -2
- data/lib/lutaml/xml/leptris.rb +13 -0
- data/lutaml-model.gemspec +2 -2
- data/spec/lutaml/model/desc_spec.rb +50 -0
- metadata +8 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70de43228d2b233faab386c9016139160f2b75e9f76c27386de22104df2820f5
|
|
4
|
+
data.tar.gz: 78b4591ba8eec19bbc7fde9a1fd2d298c58094b1198352f2323067406d39b5aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -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
|
|
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
|
|
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)
|
data/lib/lutaml/xml/leptris.rb
CHANGED
|
@@ -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.
|
|
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:
|
|
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:
|
|
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: '
|
|
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: '
|
|
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
|