Module: Lutaml::Xml::TransformationSupport::RuleCompiler
- Included in:
- Lutaml::Xml::Transformation
- Defined in:
- lib/lutaml/xml/transformation/rule_compiler.rb
Overview
Module for compiling XML mapping DSL into pre-compiled rules.
Transforms mapping DSL definitions into CompiledRule objects that can be used during serialization without triggering type resolution.
Instance Method Summary collapse
-
#build_child_transformation(type_class, register) ⇒ Transformation?
Build child transformation for nested model.
-
#build_value_transformer(mapping_rule, attr) ⇒ Proc, ...
Build value transformer from mapping rule and attribute.
-
#compile_attribute_rule(mapping_rule, model_class, register_id, _register) ⇒ CompiledRule?
Compile an attribute mapping rule.
-
#compile_content_rule(mapping_rule, model_class, register_id) ⇒ CompiledRule?
Compile a content mapping rule.
-
#compile_element_rule(mapping_rule, model_class, register_id, register) ⇒ CompiledRule?
Compile an element mapping rule.
-
#compile_raw_rule(mapping_rule, model_class, register_id) ⇒ CompiledRule?
Compile a raw mapping rule (map_all directive).
-
#compile_rules(mapping_dsl, model_class, register_id, register) ⇒ Array<CompiledRule>
Compile XML mapping DSL into pre-compiled rules.
Instance Method Details
#build_child_transformation(type_class, register) ⇒ Transformation?
Build child transformation for nested model
223 224 225 226 227 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 223 def build_child_transformation(type_class, register) return nil unless type_class.is_a?(Class) && type_class.include?(Lutaml::Model::Serialize) type_class.transformation_for(:xml, register) end |
#build_value_transformer(mapping_rule, attr) ⇒ Proc, ...
Build value transformer from mapping rule and attribute
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 234 def build_value_transformer(mapping_rule, attr) mapping_transform = mapping_rule.transform attr_transform = if attr.nil? nil else attr.transform end if mapping_transform && !mapping_transform.empty? return mapping_transform end if attr_transform && !attr_transform.empty? return attr_transform end nil end |
#compile_attribute_rule(mapping_rule, model_class, register_id, _register) ⇒ CompiledRule?
Compile an attribute mapping rule
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 125 def compile_attribute_rule(mapping_rule, model_class, register_id, _register) # Access custom_methods early to check if we need to infer attribute name custom_methods_value = mapping_rule.custom_methods # Get attribute name from mapping rule, or infer from custom methods attr_name = infer_attribute_name(mapping_rule, custom_methods_value, model_class, register_id) return nil unless attr_name # Handle delegated attributes if mapping_rule.delegate return compile_delegated_attribute_rule( mapping_rule, model_class, register_id, attr_name, custom_methods_value ) end # Get attribute definition from model class (non-delegated) attr = model_class.attributes(register_id)&.[](attr_name) # For custom methods without a real attribute, create the rule anyway if attr.nil? && !custom_methods_value.empty? return compile_custom_method_attribute_rule( mapping_rule, attr_name, custom_methods_value ) end return nil unless attr compile_standard_attribute_rule(mapping_rule, attr, attr_name, register_id, custom_methods_value) end |
#compile_content_rule(mapping_rule, model_class, register_id) ⇒ CompiledRule?
Compile a content mapping rule
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 165 def compile_content_rule(mapping_rule, model_class, register_id) custom_methods_value = mapping_rule.custom_methods # Get attribute name from mapping rule, or use placeholder for custom methods attr_name = mapping_rule.to if (attr_name.nil? || attr_name.empty?) && !custom_methods_value.empty? attr_name = :__content__ end return nil unless attr_name attr = model_class.attributes(register_id)&.[](attr_name) # For custom methods without a real attribute if attr.nil? && !custom_methods_value.empty? return build_content_rule(mapping_rule, attr_name, nil, custom_methods_value) end return nil unless attr build_content_rule(mapping_rule, attr_name, attr.type(register_id), nil) end |
#compile_element_rule(mapping_rule, model_class, register_id, register) ⇒ CompiledRule?
Compile an element mapping rule
84 85 86 87 88 89 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 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 84 def compile_element_rule(mapping_rule, model_class, register_id, register) # Access custom_methods early to check if we need to infer attribute name custom_methods_value = mapping_rule.custom_methods # Get attribute name from mapping rule, or infer from custom methods attr_name = infer_attribute_name(mapping_rule, custom_methods_value, model_class, register_id) return nil unless attr_name # Handle delegated attributes if mapping_rule.delegate return compile_delegated_element_rule( mapping_rule, model_class, register_id, register, attr_name, custom_methods_value ) end # Get attribute definition from model class (non-delegated) attr = model_class.attributes(register_id)&.[](attr_name) # For custom methods without a real attribute, create the rule anyway if attr.nil? && !custom_methods_value.empty? return compile_custom_method_element_rule( mapping_rule, attr_name, custom_methods_value ) end return nil unless attr compile_standard_element_rule(mapping_rule, attr, attr_name, register_id, register, custom_methods_value) end |
#compile_raw_rule(mapping_rule, model_class, register_id) ⇒ CompiledRule?
Compile a raw mapping rule (map_all directive)
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 196 def compile_raw_rule(mapping_rule, model_class, register_id) attr_name = mapping_rule.to return nil unless attr_name attr = model_class.attributes(register_id)&.[](attr_name) return nil unless attr value_transformer = build_value_transformer(mapping_rule, attr) value_map = mapping_rule.raw_value_map ::Lutaml::Model::CompiledRule.new( attribute_name: attr_name, serialized_name: nil, attribute_type: attr.type(register_id), value_transformer: value_transformer, mapping_type: :raw, render_default: mapping_rule.render_default, value_map: value_map, custom_methods: mapping_rule.custom_methods, ) end |
#compile_rules(mapping_dsl, model_class, register_id, register) ⇒ Array<CompiledRule>
Compile XML mapping DSL into pre-compiled rules
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/lutaml/xml/transformation/rule_compiler.rb', line 18 def compile_rules(mapping_dsl, model_class, register_id, register) return [] unless mapping_dsl rules = [] # Compile element mappings elements_to_compile = if register_id && register_id != :default && mapping_dsl.elements(register_id).any? mapping_dsl.elements(register_id) else mapping_dsl.elements end elements_to_compile.each do |mapping_rule| rule = compile_element_rule(mapping_rule, model_class, register_id, register) rules << rule if rule end # Compile attribute mappings attributes_to_compile = if register_id && register_id != :default && mapping_dsl.attributes(register_id).any? mapping_dsl.attributes(register_id) else mapping_dsl.attributes end attributes_to_compile.each do |mapping_rule| rule = compile_attribute_rule(mapping_rule, model_class, register_id, register) rules << rule if rule end # Compile content mapping if present if mapping_dsl.content_mapping rule = compile_content_rule(mapping_dsl.content_mapping, model_class, register_id) rules << rule if rule end # Compile raw mapping (map_all directive) if present if mapping_dsl.raw_mapping rule = compile_raw_rule(mapping_dsl.raw_mapping, model_class, register_id) rules << rule if rule end # Add a pseudo-rule for root namespace if present # This ensures root namespace is included in all_namespaces if mapping_dsl.namespace_class rules << ::Lutaml::Model::CompiledRule.new( attribute_name: :__root_namespace__, serialized_name: "__root__", namespace_class: mapping_dsl.namespace_class, mapping_type: :root_namespace, ) end rules.compact end |