Class: Lutaml::Model::Sequence

Inherits:
Object
  • Object
show all
Includes:
DeepDupable
Defined in:
lib/lutaml/model/sequence.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, format: nil) ⇒ Sequence

Returns a new instance of Sequence.



11
12
13
14
15
16
# File 'lib/lutaml/model/sequence.rb', line 11

def initialize(model, format: nil)
  @attributes = []
  @compositors = []
  @model = model
  @format = format
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



8
9
10
# File 'lib/lutaml/model/sequence.rb', line 8

def attributes
  @attributes
end

#compositorsObject

Returns the value of attribute compositors.



8
9
10
# File 'lib/lutaml/model/sequence.rb', line 8

def compositors
  @compositors
end

#formatObject (readonly)

Returns the value of attribute format.



9
10
11
# File 'lib/lutaml/model/sequence.rb', line 9

def format
  @format
end

#modelObject

Returns the value of attribute model.



8
9
10
# File 'lib/lutaml/model/sequence.rb', line 8

def model
  @model
end

Instance Method Details

#attribute(name, type, options = {}) ⇒ Object



27
28
29
30
# File 'lib/lutaml/model/sequence.rb', line 27

def attribute(name, type, options = {})
  options[:sequence] = self
  @model.attribute(name, type, options)
end

#bind_choice_compositors!(mapper_class) ⇒ Object

Bind nested choice compositors to the mapper's model attributes (options), so validation applies order and exclusivity the same way a model-level choice does. Runs at mapping finalize, when the mapper class is known — the DSL block runs earlier.



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/lutaml/model/sequence.rb', line 69

def bind_choice_compositors!(mapper_class)
  @compositors.each do |choice|
    choice.model = mapper_class
    # The choice's contents become the model attributes its rules
    # target — the same shape a model-level choice carries — so
    # validation machinery works unchanged.
    bound = choice.attributes.filter_map do |rule|
      mapper_class.attributes[rule.to]
    end.uniq
    choice.attributes.replace(bound)
    bound.each { |target| target.options[:choice] = choice }
  end
end

#choice(min: 1, max: 1, &block) ⇒ Object

An xs:choice compositor nested inside an xs:sequence (lutaml-model#687). Element rules mapped in the block take their positional place in this sequence AND carry the choice on their model attributes, so validation applies order and exclusivity exactly as a model-level choice does. The choice itself is remembered in #compositors — the compositor shape stays queryable next to the flat rule order.



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/lutaml/model/sequence.rb', line 52

def choice(min: 1, max: 1, &block)
  nested = Choice.new(@model, min, max, format: @format)
  previous = @choice_in_progress
  @choice_in_progress = nested
  begin
    instance_eval(&block)
  ensure
    @choice_in_progress = previous
  end
  @compositors << nested
  nested
end

#deep_dup(new_model = nil) ⇒ Object

Deep copy a sequence, creating independent copies of attributes The model reference is updated to point to the new parent mapping



20
21
22
23
24
25
# File 'lib/lutaml/model/sequence.rb', line 20

def deep_dup(new_model = nil)
  dup_seq = Sequence.new(new_model || @model, format: @format)
  dup_seq.attributes = Utils.deep_dup(@attributes)
  dup_seq.compositors = Utils.deep_dup(@compositors)
  dup_seq
end

#import_model_mappings(model, register = nil) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/lutaml/model/sequence.rb', line 83

def import_model_mappings(model, register = nil)
  if later_importable?(model)
    return import_mappings_later(model,
                                 register)
  end
  raise Lutaml::Model::ImportModelWithRootError.new(model) if model.root?(register)

  register ||= Lutaml::Model::Config.default_register

  # When importing a model into a sequence, we need BOTH:
  # 1. Object model (attributes/structure) - what data exists
  # 2. Serialization mappings (how to serialize) - how data maps to XML
  # This mimics XSD where using a complexType in a sequence means
  # adopting both its structure and its serialization rules

  # Import serialization mappings first (element names → model attributes)
  @model.import_model_mappings(model, register)
  if @format
    @attributes.concat(Utils.deep_dup(model.mappings_for(@format,
                                                         register).elements(register)))
  end
end

#map_allObject



114
115
116
# File 'lib/lutaml/model/sequence.rb', line 114

def map_all(*)
  raise Lutaml::Model::UnknownSequenceMappingError.new("map_all")
end

#map_attributeObject



106
107
108
# File 'lib/lutaml/model/sequence.rb', line 106

def map_attribute(*)
  raise Lutaml::Model::UnknownSequenceMappingError.new("map_attribute")
end

#map_contentObject



110
111
112
# File 'lib/lutaml/model/sequence.rb', line 110

def map_content(*)
  raise Lutaml::Model::UnknownSequenceMappingError.new("map_content")
end

#map_element(name, **options) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/lutaml/model/sequence.rb', line 36

def map_element(name, **options)
  rule = @model.map_element(name, **options)
  @attributes << rule
  if (nested = @choice_in_progress)
    nested.attributes << rule
  end
  rule
end

#sequence(&block) ⇒ Object



32
33
34
# File 'lib/lutaml/model/sequence.rb', line 32

def sequence(&block)
  instance_eval(&block)
end

#validate_content!(element_order, instance, register = nil) ⇒ Object



118
119
120
121
122
123
124
125
# File 'lib/lutaml/model/sequence.rb', line 118

def validate_content!(element_order, instance, register = nil)
  validate_sequence!(
    extract_defined_order(instance.class.attributes(register).transform_keys(&:to_s)),
    element_order,
    register,
  )
  validate_child_content(instance, register)
end