moxml 0.5.72 → 0.5.74

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: dfe72fe97dab1ded102fe66f946b293e82ace5e8003408a0183bef72150cda92
4
- data.tar.gz: 8ce6a685287f317d41c7996f5957e24edb13f2d2a0bb7a8184d02a47506136fc
3
+ metadata.gz: 9502f77654d0b09a3a8ab3b926702ee07e07009076fbeb4fd7013eb5b2b39499
4
+ data.tar.gz: 21d7b7dc2742200d83ac2d89c1610857cb0bf90590ef260052ad287bcb427170
5
5
  SHA512:
6
- metadata.gz: e6b9a1e718b4d39e2169c2f414e5b8aedd030142ca3af8836bee80e64b5e1f9605d53f828f2135d9776b78c7b2f6662ae5054b47c171d8b2883a1e17a74140b5
7
- data.tar.gz: 055def54b030a3d0e065b3f6c1ddde92af5f0e0c83a0e02882ebb80f63d5633baf6c69280fbffef8dddac76db95a9ff91c0019bde796a13a28998d87fccf9242
6
+ metadata.gz: ae16970a10ade16adfb8f186a6269db7c6e5f94374737eb82bee0e5fb3609719171fcb731db2f52b86948848c938cca984255f55dfaf4cfc854e384602c8e32a
7
+ data.tar.gz: 3f2f44d095a8d0fc6ceb0e506e930a16ef2afaa82f817114fe3dafd609a917e8eac7dd4f2b247caa74a7da9b0642b035432cb2cdfd3f6359ac2d0b56b8e19a59
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ gemspec
9
9
  gem "benchmark"
10
10
  gem "benchmark-ips"
11
11
  gem "get_process_mem"
12
- gem "leptris", "~> 1.9.216"
12
+ gem "leptris", "~> 1.9.222"
13
13
  gem "libxml-ruby", ">= 5.0"
14
14
  gem "nokogiri", "~> 1.18"
15
15
  gem "openssl", "~> 3.0"
@@ -525,6 +525,14 @@ module Moxml
525
525
  # remove_doctype complete the set-only creation entries.
526
526
  # Attached DOCTYPEs materialize as native nodes, document-PI
527
527
  # removal works, and declaration state mirrors through.
528
+ # The typed executor face (leptris-ruby: typed plan scalars —
529
+ # [slot, tag] spec entries cast in C, no Ruby String for
530
+ # numeric/boolean slots). Capability-probed, not
531
+ # version-gated.
532
+ NATIVE_PLAN_TYPED =
533
+ !defined?(::Leptris::XML::Native) ||
534
+ ::Leptris::XML::Native.respond_to?(:plan_structs_typed?)
535
+
528
536
  NATIVE_DOC_PARTS =
529
537
  Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.204.0") &&
530
538
  ::Leptris::XML::Document.method_defined?(:remove_doctype) &&
@@ -31,6 +31,13 @@ module Moxml
31
31
  # member slots; +text+ and +children+ name the member slots
32
32
  # receiving the first text child and the matched children array.
33
33
  # Returns self so registrations chain.
34
+ #
35
+ # Typed scalars (binding with the typed executor — probe
36
+ # Moxml::Adapter::Leptris::NATIVE_PLAN_TYPED): slot values may
37
+ # be [slot, type] pairs — type one of :integer, :float,
38
+ # :boolean (attrs and text). The executor casts in C with no
39
+ # Ruby String materialized; unparseable input degrades to the
40
+ # raw String (lenient). :boolean accepts t/1/y/Y as true.
34
41
  def element(name, klass, attrs: {}, text: nil, children: nil)
35
42
  @elements[name] = Element.new(klass, attrs, text, children)
36
43
  self
@@ -41,18 +48,39 @@ module Moxml
41
48
  # resolve to member INDICES once — the C executor's Integer
42
49
  # key path then writes by index, skipping the per-write member
43
50
  # name scan.
51
+ TYPE_TAGS = { integer: 1, float: 2, boolean: 3 }.freeze
52
+
44
53
  def compile
54
+ typed = Moxml::Adapter::Leptris::NATIVE_PLAN_TYPED
45
55
  @elements.each_with_object({}) do |(name, el), spec|
46
56
  members = el.klass.members
47
57
  spec[name] = [
48
58
  el.klass,
49
- el.attrs.each_with_object({}) { |(a, slot), h| h[a] = members.index(slot) || slot },
50
- members.index(el.text) || el.text,
59
+ el.attrs.each_with_object({}) do |(a, slot), h|
60
+ h[a] = compile_slot(slot, members, typed)
61
+ end,
62
+ compile_slot(el.text, members, typed),
51
63
  members.index(el.children) || el.children,
52
64
  ]
53
65
  end
54
66
  end
55
67
 
68
+ # Resolve a slot to the executor's wire form: the member index
69
+ # (or the raw symbol for unknown slots), wrapped as
70
+ # [slot, tag] when a type is declared and the binding's
71
+ # executor is typed. Without the face, types degrade to
72
+ # strings.
73
+ def compile_slot(slot, members, typed)
74
+ if slot.is_a?(Array)
75
+ inner, type = slot
76
+ tag = TYPE_TAGS[type] || 0
77
+ resolved = members.index(inner) || inner
78
+ return typed && tag != 0 ? [resolved, tag] : resolved
79
+ end
80
+
81
+ members.index(slot) || slot
82
+ end
83
+
56
84
  def parse(xml, context)
57
85
  materialize(context.parse(xml))
58
86
  end
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.72"
4
+ VERSION = "0.5.74"
5
5
  end
data/moxml.gemspec CHANGED
@@ -12,7 +12,8 @@ Gem::Specification.new do |spec|
12
12
  spec.description = <<~DESCRIPTION
13
13
  Moxml is a unified XML manipulation library that provides a common API
14
14
  for XML node navigation, manipulation, building and XPath querying
15
- interface covering multiple parser implementations including Nokogiri, Oga, REXML, Ox, LibXML.
15
+ interface covering multiple parser implementations including Leptris,
16
+ Nokogiri, Oga, REXML, Ox, HeadedOx and LibXML.
16
17
  DESCRIPTION
17
18
 
18
19
  spec.homepage = "https://github.com/lutaml/moxml"
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ # Typed plan scalars (leptris plan ABI, #1269a consumer face):
6
+ # [slot, type] declarations cast in C — Integer/Float/TrueClass/
7
+ # FalseClass members with no Ruby String materialized; unparseable
8
+ # input degrades to the raw String. Skipped unless the binding's
9
+ # executor carries the typed face.
10
+ RSpec.describe "Moxml::StructPlan typed scalars" do
11
+ let(:ctx) { Moxml.new(:leptris) }
12
+ let(:xml) do
13
+ %(<r><item price="19.99" qty="3" ok="yes">42</item>) +
14
+ %(<item price="bad" qty="x" ok="0">7</item></r>)
15
+ end
16
+ let(:plan) do
17
+ Moxml::StructPlan.new do
18
+ element "item", TypedItem,
19
+ attrs: { "price" => %i[price float], "qty" => %i[qty integer],
20
+ "ok" => %i[ok boolean] },
21
+ text: %i[label integer]
22
+ end
23
+ end
24
+
25
+ before do
26
+ skip "leptris adapter unavailable" unless ctx.config.adapter.name.end_with?("Leptris")
27
+ Moxml::Adapter::Leptris # load
28
+ skip "binding lacks the typed executor" unless Moxml::Adapter::Leptris::NATIVE_PLAN_TYPED
29
+ end
30
+
31
+ it "casts typed slots and degrades unparseable input to String" do
32
+ items = plan.parse(xml, ctx)
33
+ expect(items[0].price).to eq(19.99)
34
+ expect(items[0].qty).to eq(3)
35
+ expect(items[0].ok).to be(true)
36
+ expect(items[0].label).to eq(42)
37
+
38
+ expect(items[1].price).to eq("bad")
39
+ expect(items[1].qty).to eq("x")
40
+ expect(items[1].ok).to be(false)
41
+ expect(items[1].label).to eq(7)
42
+ end
43
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.72
4
+ version: 0.5.74
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -13,7 +13,8 @@ dependencies: []
13
13
  description: |
14
14
  Moxml is a unified XML manipulation library that provides a common API
15
15
  for XML node navigation, manipulation, building and XPath querying
16
- interface covering multiple parser implementations including Nokogiri, Oga, REXML, Ox, LibXML.
16
+ interface covering multiple parser implementations including Leptris,
17
+ Nokogiri, Oga, REXML, Ox, HeadedOx and LibXML.
17
18
  email:
18
19
  - open.source@ribose.com
19
20
  executables: []
@@ -514,6 +515,7 @@ files:
514
515
  - spec/moxml/signature/model_spec.rb
515
516
  - spec/moxml/signature/round_trip_spec.rb
516
517
  - spec/moxml/struct_plan_spec.rb
518
+ - spec/moxml/struct_plan_typed_spec.rb
517
519
  - spec/moxml/text_spec.rb
518
520
  - spec/moxml/version_spec.rb
519
521
  - spec/moxml/xml_emitter_spec.rb