Class: Lutaml::Model::Choice
- Inherits:
-
Object
- Object
- Lutaml::Model::Choice
- Defined in:
- lib/lutaml/model/choice.rb
Constant Summary collapse
- INTERNAL_ATTRIBUTES =
%i[@flat_attributes].freeze
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
-
#format ⇒ Object
Returns the value of attribute format.
-
#max ⇒ Object
readonly
Returns the value of attribute max.
-
#min ⇒ Object
readonly
Returns the value of attribute min.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #attribute(name, type, options = {}) ⇒ Object
- #can_render_empty?(_object) ⇒ Boolean
- #choice(min: 1, max: 1, &block) ⇒ Object
- #deep_duplicate(new_model, register = nil) ⇒ Object
- #flat_attributes ⇒ Object
- #import_model_attributes(model, register_id = nil) ⇒ Object
-
#initialize(model, min, max, format: nil) ⇒ Choice
constructor
A new instance of Choice.
- #optional_empty_choice?(count) ⇒ Boolean
- #pretty_print_instance_variables ⇒ Object
- #validate_content!(object, register = nil) ⇒ Object
- #validate_count_errors!(count, attributes) ⇒ Object
- #validate_sequence_content!(elements, appearance_count = 0, register = nil) ⇒ Object
Constructor Details
#initialize(model, min, max, format: nil) ⇒ Choice
Returns a new instance of Choice.
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/lutaml/model/choice.rb', line 14 def initialize(model, min, max, format: nil) @attributes = [] @model = model @min = min @max = max @format = format if @min.negative? || @max.negative? raise Lutaml::Model::InvalidChoiceRangeError.new(@min, @max) end end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
6 7 8 |
# File 'lib/lutaml/model/choice.rb', line 6 def attributes @attributes end |
#format ⇒ Object
Returns the value of attribute format.
10 11 12 |
# File 'lib/lutaml/model/choice.rb', line 10 def format @format end |
#max ⇒ Object (readonly)
Returns the value of attribute max.
6 7 8 |
# File 'lib/lutaml/model/choice.rb', line 6 def max @max end |
#min ⇒ Object (readonly)
Returns the value of attribute min.
6 7 8 |
# File 'lib/lutaml/model/choice.rb', line 6 def min @min end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
6 7 8 |
# File 'lib/lutaml/model/choice.rb', line 6 def model @model end |
Instance Method Details
#==(other) ⇒ Object
27 28 29 30 31 32 |
# File 'lib/lutaml/model/choice.rb', line 27 def ==(other) @attributes == other.attributes && @min == other.min && @max == other.max && @model == other.model end |
#attribute(name, type, options = {}) ⇒ Object
34 35 36 37 |
# File 'lib/lutaml/model/choice.rb', line 34 def attribute(name, type, = {}) [:choice] = self @attributes << @model.attribute(name, type, ) end |
#can_render_empty?(_object) ⇒ Boolean
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/lutaml/model/choice.rb', line 72 def can_render_empty?(_object) # Check if ALL attributes in the choice have render_empty: true # This allows empty instances of required elements to pass validation return false unless @format mapping = @model.mappings_for(@format) return false unless mapping&.elements @attributes.all? do |attribute| next true if attribute.is_a?(Choice) # Nested choices handled separately rule = mapping.elements.find { |r| r.to == attribute.name } rule&.render_empty? end rescue StandardError false end |
#choice(min: 1, max: 1, &block) ⇒ Object
39 40 41 42 43 |
# File 'lib/lutaml/model/choice.rb', line 39 def choice(min: 1, max: 1, &block) @attributes << Choice.new(@model, min, max, format: @format).tap do |c| c.instance_eval(&block) end end |
#deep_duplicate(new_model, register = nil) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/lutaml/model/choice.rb', line 122 def deep_duplicate(new_model, register = nil) choice = self.class.new(new_model, @min, @max, format: @format) attrs = @attributes.map do |attr| next attr.deep_duplicate(new_model, register) if attr.is_a?(Choice) choice_attr = new_model.attributes(register)[attr.name] next if choice_attr.nil? choice_attr.[:choice] = choice choice_attr end choice.attributes.concat(attrs.compact) choice end |
#flat_attributes ⇒ Object
45 46 47 48 49 |
# File 'lib/lutaml/model/choice.rb', line 45 def flat_attributes @flat_attributes ||= @attributes.flat_map do |attribute| attribute.is_a?(Choice) ? attribute.flat_attributes : attribute end end |
#import_model_attributes(model, register_id = nil) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/lutaml/model/choice.rb', line 90 def import_model_attributes(model, register_id = nil) if later_importable?(model) return import_model_later(model, :import_model_attributes) end root_model_error(model) register_id ||= Lutaml::Model::Config.default_register if register_id != :default # Non-default register: store in register-specific storage only current_record = @model.register_records[register_id] ||= { attributes: {}, choice_attributes: [] } imported_attributes = Utils.deep_dup(model.attributes(register_id)) imported_attributes.each_value do |attr| attr.[:choice] = self end current_record[:attributes].merge!(imported_attributes) return end # Default register: store in class-level storage imported_attributes = Utils.deep_dup(model.attributes.values) imported_attributes.each do |attr| attr.[:choice] = self @model.define_attribute_methods(attr) end @attributes.concat(imported_attributes) attrs_hash = imported_attributes.to_h { |attr| [attr.name, attr] } @model.attributes.merge!(attrs_hash) end |
#optional_empty_choice?(count) ⇒ Boolean
152 153 154 155 156 157 158 |
# File 'lib/lutaml/model/choice.rb', line 152 def optional_empty_choice?(count) count.zero? && @attributes.any? do |attr| next attr.optional_empty_choice?(count) if attr.is_a?(self.class) optional_attribute?(attr) end end |
#pretty_print_instance_variables ⇒ Object
160 161 162 |
# File 'lib/lutaml/model/choice.rb', line 160 def pretty_print_instance_variables (instance_variables - INTERNAL_ATTRIBUTES).sort end |
#validate_content!(object, register = nil) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/lutaml/model/choice.rb', line 60 def validate_content!(object, register = nil) validated_attributes = [] valid = valid_attributes(object, validated_attributes, register) # Allow empty choice if it can render empty elements if valid.none? && can_render_empty?(object) return end validate_count_errors!(valid.count, validated_attributes) end |
#validate_count_errors!(count, attributes) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/lutaml/model/choice.rb', line 138 def validate_count_errors!(count, attributes) return if count.between?(@min, @max) return if optional_empty_choice?(count) if count < @min raise Lutaml::Model::ChoiceLowerBoundError.new(attributes, @min) end if count > @max raise Lutaml::Model::ChoiceUpperBoundError.new(attributes, @max) end end |
#validate_sequence_content!(elements, appearance_count = 0, register = nil) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/lutaml/model/choice.rb', line 51 def validate_sequence_content!(elements, appearance_count = 0, register = nil) choices_hash = ::Hash.new { |h, k| h[k] = 0 } choices_hash[self] = appearance_count current_index = validate_choices(elements, choices_hash, register) raise_errors(choices_hash) current_index end |