Class: Lutaml::KeyValue::Transformation::ValueSerializer

Inherits:
Object
  • Object
show all
Includes:
Model::RenderPolicy
Defined in:
lib/lutaml/key_value/transformation/value_serializer.rb

Overview

Serializes values (primitives and nested models) for key-value formats.

This is an independent class with explicit dependencies that can be tested in isolation from Transformation.

Examples:

Basic usage

serializer = ValueSerializer.new(
  format: :json,
  register_id: :default,
  transformation_factory: ->(type) { Transformation.new(type, ...) }
)
result = serializer.serialize_item(value, rule, options)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Model::RenderPolicy

derived_attribute_for?, #should_skip_delegated_value?, #should_skip_value?

Constructor Details

#initialize(format:, register_id:, transformation_factory:, model_class: nil) ⇒ ValueSerializer

Initialize the ValueSerializer with explicit dependencies.

Parameters:

  • format (Symbol)

    The serialization format

  • register_id (Symbol, nil)

    The register ID

  • transformation_factory (Proc)

    Factory lambda ->(type_class) { Transformation }

  • model_class (Class, nil) (defaults to: nil)

    The model class for attribute lookup



40
41
42
43
44
45
46
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 40

def initialize(format:, register_id:, transformation_factory:,
model_class: nil)
  @format = format
  @register_id = register_id
  @transformation_factory = transformation_factory
  @model_class = model_class
end

Instance Attribute Details

#formatSymbol (readonly)

Returns The serialization format (:json, :yaml, :toml).

Returns:

  • (Symbol)

    The serialization format (:json, :yaml, :toml)



23
24
25
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 23

def format
  @format
end

#model_classClass? (readonly)

Returns The model class for attribute lookup.

Returns:

  • (Class, nil)

    The model class for attribute lookup



32
33
34
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 32

def model_class
  @model_class
end

#register_idSymbol? (readonly)

Returns The register ID for attribute lookup.

Returns:

  • (Symbol, nil)

    The register ID for attribute lookup



26
27
28
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 26

def register_id
  @register_id
end

#transformation_factoryProc (readonly)

Returns Factory lambda for creating child transformations.

Returns:

  • (Proc)

    Factory lambda for creating child transformations



29
30
31
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 29

def transformation_factory
  @transformation_factory
end

Instance Method Details

#nested_model?(rule) ⇒ Boolean

Check if a value is a nested model based on the rule.

Parameters:

  • rule (CompiledRule)

    The compiled rule

Returns:

  • (Boolean)

    true if the rule defines a nested model



77
78
79
80
81
82
83
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 77

def nested_model?(rule)
  # rubocop:disable Style/IncludeOrExtend
  # Use include? instead of < because < returns nil (not false) for non-subclasses
  rule.attribute_type.is_a?(Class) &&
    rule.attribute_type.include?(Lutaml::Model::Serialize)
  # rubocop:enable Style/IncludeOrExtend
end

#serialize_item(value, rule, options = {}) ⇒ Object?

Serialize a value for an item (handles nested models and primitives).

This is the main entry point for value serialization.

Parameters:

  • value (Object)

    The value to serialize

  • rule (CompiledRule)

    The compiled rule

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

    Serialization options

Returns:

  • (Object, nil)

    The serialized value (Hash, primitive, or nil)



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 56

def serialize_item(value, rule, options = {})
  return nil if value.nil?
  return nil if Lutaml::Model::Utils.uninitialized?(value)

  # Check for Reference type first - even if value is a Serializable,
  # it should be serialized as a key, not as a nested model
  if reference_type?(rule)
    return serialize_reference(value, rule)
  end

  if nested_model?(rule)
    serialize_nested_model(value, rule, options)
  else
    serialize_primitive(value, rule)
  end
end

#serialize_nested_model(value, rule, options = {}) ⇒ Hash?

Serialize a nested model to a hash representation.

Parameters:

  • value (Object)

    The model instance to serialize

  • rule (CompiledRule)

    The compiled rule

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

    Serialization options

Returns:

  • (Hash, nil)

    The serialized hash or nil if empty



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 91

def serialize_nested_model(value, rule, options = {})
  validate_nested_model_type!(value, rule)

  # Determine the actual type for polymorphism support
  actual_type = determine_actual_type(value, rule)
  uses_polymorphism = actual_type != rule.attribute_type

  # Get or create child transformation
  child_transformation = if uses_polymorphism
                           create_transformation(actual_type)
                         else
                           rule.child_transformation ||
                             create_transformation(rule.attribute_type)
                         end

  if child_transformation
    transform_nested_model(value, child_transformation, options)
  else
    serialize_primitive(value, rule)
  end
end

#serialize_primitive(value, rule) ⇒ Object

Serialize a primitive value to the appropriate representation.

Parameters:

  • value (Object)

    The primitive value

  • rule (CompiledRule)

    The compiled rule

Returns:

  • (Object)

    The serialized value



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/lutaml/key_value/transformation/value_serializer.rb', line 118

def serialize_primitive(value, rule)
  return nil if value.nil?
  return nil if Lutaml::Model::Utils.uninitialized?(value)

  # For Reference types, use attribute's serialize method
  if reference_type?(rule)
    return serialize_reference(value, rule)
  end

  # For Serializable types, use to_#{format} method
  if rule.attribute_type.is_a?(Class) &&
      rule.attribute_type < Lutaml::Model::Serialize
    validate_serializable_type!(value, rule)
    return value.send(:"to_#{format}")
  end

  # Wrap value in type and call to_#{format}
  if rule.attribute_type.respond_to?(:new)
    wrapped_value = rule.attribute_type.new(value)
    wrapped_value.send(:"to_#{format}")
  else
    value
  end
end