Module: Lutaml::Model::Serialize::ValueMapping

Included in:
ClassMethods
Defined in:
lib/lutaml/model/serialize/value_mapping.rb

Overview

Handles value mapping methods for Serialize::ClassMethods

Extracted from serialize.rb to improve code organization. Provides methods for applying value maps and mappings.

Instance Method Summary collapse

Instance Method Details

#apply_mappings(doc, format, options = {}) ⇒ Object

Apply mappings from a document to create a model instance

Parameters:

  • doc (Hash, Object)

    The document to map from

  • format (Symbol)

    The format (:xml, :json, etc.)

  • options (Hash) (defaults to: {})

    Options including :register, :instance

Returns:

  • (Object)

    The model instance with mapped values



17
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
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 17

def apply_mappings(doc, format, options = {})
  register = options[:register] || Lutaml::Model::Config.default_register

  # Use child's own default register if it has one
  child_register = Lutaml::Model::Register.resolve_for_child(model,
                                                             register)

  # For blank documents, return a bare instance without going
  # through data_to_model (which would create a duplicate instance).
  if Utils.blank?(doc)
    if options.key?(:instance)
      return options[:instance]
    elsif model.include?(Lutaml::Model::Serialize)
      return model.new({ lutaml_register: child_register })
    else
      object = model.new
      register_accessor_methods_for(object, child_register)
      return object
    end
  end

  mappings = mappings_for(format, register)

  if mappings.polymorphic_mapping
    instance = if model.include?(Lutaml::Model::Serialize)
                 model.new({ lutaml_register: child_register })
               else
                 model.new
               end
    return resolve_polymorphic(doc, format, mappings, instance, options)
  end

  transformer = Lutaml::Model::Config.transformer_for(format)
  transformer.data_to_model(self, doc, format, options)
end

#apply_value_map(value, value_map, attr) ⇒ Object

Apply a value map to transform a value.

Delegates to Attribute#apply_value_map. See attribute.rb for the canonical implementation.

Parameters:

  • value (Object)

    The value to transform

  • value_map (Hash)

    The value map configuration

  • attr (Attribute)

    The attribute definition

Returns:

  • (Object)

    The transformed value



83
84
85
86
87
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 83

def apply_value_map(value, value_map, attr)
  return value unless attr

  attr.apply_value_map(value, value_map)
end

#ensure_utf8(value) ⇒ Object

Ensure a value is UTF-8 encoded

Parameters:

  • value (Object)

    The value to encode

Returns:

  • (Object)

    The UTF-8 encoded value



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 93

def ensure_utf8(value)
  case value
  when String
    # Opal strings are JS strings with no per-string encoding;
    # String#encode there doesn't accept MRI's keyword options.
    return value if Lutaml::Model.opal?

    value.encode("UTF-8", invalid: :replace, undef: :replace,
                          replace: "")
  when Array
    value.map { |v| ensure_utf8(v) }
  when ::Hash
    value.transform_keys do |k|
      ensure_utf8(k)
    end.transform_values do |v|
      ensure_utf8(v)
    end
  else
    value
  end
end

#extract_register_id(register) ⇒ Symbol?

Extract register ID from various formats

Resolution order:

  1. Explicit register parameter
  2. Class instance variable @register (set by set_register_context via registration)
  3. Class's lutaml_default_register (for versioned schemas)
  4. Global Config.default_register

Parameters:

  • register (Symbol, Register, nil)

    The register

Returns:

  • (Symbol, nil)

    The register ID



140
141
142
143
144
145
146
147
148
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 140

def extract_register_id(register)
  if register
    register.is_a?(Lutaml::Model::Register) ? register.id : register
  elsif instance_variable_defined?(:@register)
    instance_variable_get(:@register)
  else
    lutaml_default_register || Lutaml::Model::Config.default_register
  end
end

#register_accessor_methods_for(object, register) ⇒ Object

Register accessor methods on an object

Parameters:

  • object (Object)

    The object to add methods to

  • register (Symbol)

    The register ID



119
120
121
122
123
124
125
126
127
128
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 119

def register_accessor_methods_for(object, register)
  Utils.add_singleton_method_if_not_defined(object, :lutaml_register) do
    @lutaml_register
  end
  Utils.add_singleton_method_if_not_defined(object,
                                            :lutaml_register=) do |value|
    @lutaml_register = value
  end
  object.lutaml_register = register
end

#resolve_polymorphic(doc, format, mappings, instance, options = {}) ⇒ Object

Resolve a polymorphic type from a document

Parameters:

  • doc (Hash)

    The document to resolve from

  • format (Symbol)

    The format

  • mappings (Mapping)

    The mappings object

  • instance (Object)

    The base instance

  • options (Hash) (defaults to: {})

    Additional options

Returns:

  • (Object)

    The resolved model instance



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/lutaml/model/serialize/value_mapping.rb', line 61

def resolve_polymorphic(doc, format, mappings, instance, options = {})
  polymorphic_mapping = mappings.polymorphic_mapping
  return instance if polymorphic_mapping.polymorphic_map.empty?

  klass_key = doc[polymorphic_mapping.name]
  klass_name = polymorphic_mapping.polymorphic_map[klass_key]
  klass = Object.const_get(klass_name)

  propagated = options.slice(*Lutaml::Model::Attribute::CHILD_PROPAGATION_KEYS)
  klass.apply_mappings(doc, format,
                       propagated.merge(register: instance.lutaml_register))
end