lib/avromatic/model/raw_serialization.rb in avromatic-2.3.0 vs lib/avromatic/model/raw_serialization.rb in avromatic-2.4.0

- old
+ new

@@ -1,7 +1,9 @@ # frozen_string_literal: true +require 'active_support/deprecation' + module Avromatic module Model # This module provides serialization support for encoding directly to Avro # without dependency on a schema registry. @@ -9,58 +11,96 @@ extend ActiveSupport::Concern module Encode extend ActiveSupport::Concern + UNSPECIFIED = Object.new + delegate :datum_writer, :datum_reader, to: :class private :datum_writer, :datum_reader - def avro_raw_value(validate: true) - if self.class.config.mutable - avro_raw_encode(value_attributes_for_avro(validate: validate), :value) + def avro_raw_value(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + + if self.class.recursively_immutable? + @avro_raw_value ||= avro_raw_encode(value_attributes_for_avro, :value) else - @avro_raw_value ||= avro_raw_encode(value_attributes_for_avro(validate: validate), :value) + avro_raw_encode(value_attributes_for_avro, :value) end end - def avro_raw_key(validate: true) + def avro_raw_key(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + raise 'Model has no key schema' unless key_avro_schema - avro_raw_encode(key_attributes_for_avro(validate: validate), :key) + avro_raw_encode(key_attributes_for_avro, :key) end - def value_attributes_for_avro(validate: true) - if self.class.config.mutable - avro_hash(value_avro_field_references, validate: validate) + def value_attributes_for_avro(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + + if self.class.recursively_immutable? + @value_attributes_for_avro ||= avro_hash(value_avro_field_references) else - @value_attributes_for_avro ||= avro_hash(value_avro_field_references, validate: validate) + avro_hash(value_avro_field_references) end end - def key_attributes_for_avro(validate: true) - avro_hash(key_avro_field_references, validate: validate) + def key_attributes_for_avro(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + + avro_hash(key_avro_field_references) end - def avro_value_datum(validate: true) - if self.class.config.mutable - avro_hash(value_avro_field_references, strict: true, validate: validate) + def avro_value_datum(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + + if self.class.recursively_immutable? + @avro_value_datum ||= avro_hash(value_avro_field_references, strict: true) else - @avro_datum ||= avro_hash(value_avro_field_references, strict: true, validate: validate) + avro_hash(value_avro_field_references, strict: true) end end - def avro_key_datum(validate: true) - avro_hash(key_avro_field_references, strict: true, validate: validate) + def avro_key_datum(validate: UNSPECIFIED) + unless validate == UNSPECIFIED + ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.") + end + + avro_hash(key_avro_field_references, strict: true) end private - def avro_hash(field_references, strict: false, validate:) - avro_validate! if validate + def avro_hash(field_references, strict: false) field_references.each_with_object(Hash.new) do |field_reference, result| - next unless _attributes.include?(field_reference.name_sym) - + attribute_definition = self.class.attribute_definitions[field_reference.name_sym] value = _attributes[field_reference.name_sym] - result[field_reference.name] = attribute_definitions[field_reference.name_sym].serialize(value, strict) + + if value.nil? && !attribute_definition.nullable? + # We're missing a required attribute so perform an explicit validation to generate + # a more complete error message + avro_validate! + elsif _attributes.include?(field_reference.name_sym) + begin + result[field_reference.name] = attribute_definition.serialize(value, strict) + rescue Avromatic::Model::ValidationError + # Perform an explicit validation to generate a more complete error message + avro_validate! + # We should never get here but just in case... + raise + end + end end end def avro_raw_encode(data, key_or_value = :value) stream = StringIO.new