class Avromatic::Model::Types::UnionType

Attributes

input_classes[R]
member_types[R]
value_classes[R]

Public Class Methods

new(member_types:) click to toggle source
Calls superclass method
# File lib/avromatic/model/types/union_type.rb, line 12
def initialize(member_types:)
  super()
  @member_types = member_types
  @value_classes = member_types.flat_map(&:value_classes)
  @input_classes = member_types.flat_map(&:input_classes).uniq
end

Public Instance Methods

coerce(input) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 23
def coerce(input)
  return input if coerced?(input)

  result = nil
  if input.is_a?(Avromatic::IO::UnionDatum)
    result = member_types[input.member_index].coerce(input.datum)
  else
    member_types.find do |member_type|
      result = safe_coerce(member_type, input)
    end
  end

  raise ArgumentError.new("Could not coerce '#{input.inspect}' to #{name}") if result.nil?

  result
end
coerced?(value) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 40
def coerced?(value)
  return false if value.is_a?(Avromatic::IO::UnionDatum)

  value.nil? || member_types.any? do |member_type|
    member_type.coerced?(value)
  end
end
coercible?(input) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 48
def coercible?(input)
  return true if value.is_a?(Avromatic::IO::UnionDatum)

  coerced?(input) || member_types.any? do |member_type|
    member_type.coercible?(input)
  end
end
name() click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 19
def name
  "union[#{member_types.map(&:name).join(', ')}]"
end
referenced_model_classes() click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 72
def referenced_model_classes
  member_types.flat_map(&:referenced_model_classes).tap(&:uniq!).freeze
end
serialize(value, strict) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 56
def serialize(value, strict)
  # Avromatic does not treat the null of an optional field as part of the union
  return nil if value.nil?

  member_index = find_index(value)
  if member_index.nil?
    raise ArgumentError.new("Expected #{value.inspect} to be one of #{value_classes.map(&:name)}")
  end

  serialized_value = member_types[member_index].serialize(value, strict)
  if !strict && Avromatic.use_custom_datum_writer
    serialized_value = Avromatic::IO::UnionDatum.new(member_index, serialized_value)
  end
  serialized_value
end

Private Instance Methods

find_index(value) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 78
def find_index(value)
  # TODO: Cache this?
  member_types.find_index do |member_type|
    member_type.value_classes.any? { |value_class| value.is_a?(value_class) }
  end
end
safe_coerce(member_type, input) click to toggle source
# File lib/avromatic/model/types/union_type.rb, line 85
def safe_coerce(member_type, input)
  member_type.coerce(input) if member_type.coercible?(input)
rescue StandardError
  nil
end