Class: Moxml::StructPlan
- Inherits:
-
Object
- Object
- Moxml::StructPlan
- Defined in:
- lib/moxml/struct_plan.rb
Overview
Struct-compiled materialization — the fully compiled grammar: declare the document shape once as STRUCTS; adapters with a C executor (leptris 1.9.201.1+, the varargs-mint fix) mint the typed with zero Ruby frames per element; everything else falls back to an equivalent Moxml::Plan over the row stream (spec-pinned equal).
plan = Moxml::StructPlan.new do
element "record", Record, attrs: { "id" => :id, "kind" => :kind },
children: :fields
element "field", Field, attrs: { "name" => :name, "unit" => :unit },
text: :value
end
records = plan.parse(xml, ctx) # Array of Record
Slot symbols must be the Struct's member names. Semantics equal Moxml::Plan: unmatched elements are barriers — their matched descendants surface at top level.
Defined Under Namespace
Classes: Element
Instance Method Summary collapse
-
#compile ⇒ Object
The compiled spec the C executor consumes: => [klass, attrs, text slot, children slot].
-
#element(name, klass, attrs: {}, text: nil, children: nil) ⇒ Object
Registers a struct element.
-
#initialize(&block) ⇒ StructPlan
constructor
A new instance of StructPlan.
- #materialize(node) ⇒ Object
- #parse(xml, context) ⇒ Object
Constructor Details
#initialize(&block) ⇒ StructPlan
Returns a new instance of StructPlan.
25 26 27 28 |
# File 'lib/moxml/struct_plan.rb', line 25 def initialize(&block) @elements = {} instance_eval(&block) if block end |
Instance Method Details
#compile ⇒ Object
The compiled spec the C executor consumes: => [klass, attrs, text slot, children slot]. Slots resolve to member INDICES once — the C executor's Integer key path then writes by index, skipping the per-write member name scan.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/moxml/struct_plan.rb', line 44 def compile @elements.each_with_object({}) do |(name, el), spec| members = el.klass.members spec[name] = [ el.klass, el.attrs.each_with_object({}) { |(a, slot), h| h[a] = members.index(slot) || slot }, members.index(el.text) || el.text, members.index(el.children) || el.children, ] end end |
#element(name, klass, attrs: {}, text: nil, children: nil) ⇒ Object
Registers a struct element. attrs maps attribute names to
member slots; text and children name the member slots
receiving the first text child and the matched children array.
Returns self so registrations chain.
34 35 36 37 |
# File 'lib/moxml/struct_plan.rb', line 34 def element(name, klass, attrs: {}, text: nil, children: nil) @elements[name] = Element.new(klass, attrs, text, children) self end |
#materialize(node) ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/moxml/struct_plan.rb', line 60 def materialize(node) adapter = node.context.config.adapter roots = adapter.plan_structs(node.native, compile) return roots if roots plan.materialize(node) end |
#parse(xml, context) ⇒ Object
56 57 58 |
# File 'lib/moxml/struct_plan.rb', line 56 def parse(xml, context) materialize(context.parse(xml)) end |