Class: Deimos::AvroSchemaCoercer

Inherits:
Object
  • Object
show all
Defined in:
lib/deimos/schema_backends/avro_schema_coercer.rb

Overview

Class to coerce values in a payload to match a schema.

Instance Method Summary collapse

Constructor Details

#initialize(schema) ⇒ AvroSchemaCoercer

Returns a new instance of AvroSchemaCoercer.

Parameters:

  • schema (Avro::Schema)


9
10
11
# File 'lib/deimos/schema_backends/avro_schema_coercer.rb', line 9

def initialize(schema)
  @schema = schema
end

Instance Method Details

#coerce_record(type, val) ⇒ Object

Coerce sub-records in a payload to match the schema.

Parameters:

  • type (Avro::Schema::RecordSchema)
  • val (Object)

Returns:

  • (Object)


29
30
31
32
33
34
35
# File 'lib/deimos/schema_backends/avro_schema_coercer.rb', line 29

def coerce_record(type, val)
  record = val.map do |name, value|
    field = type.fields.find { |f| f.name == name }
    coerce_type(field.type, value)
  end
  val.keys.zip(record).to_h
end

#coerce_type(type, val) ⇒ Object

Coerce values in a payload to match the schema.

Parameters:

  • type (Avro::Schema)
  • val (Object)

Returns:

  • (Object)


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
76
77
78
79
80
81
82
83
# File 'lib/deimos/schema_backends/avro_schema_coercer.rb', line 41

def coerce_type(type, val)
  int_classes = [Time, ActiveSupport::TimeWithZone]
  field_type = type.type.to_sym

  case field_type
  when :int, :long
    if %w(timestamp-millis timestamp-micros).include?(type.logical_type)
      val
    elsif val.is_a?(Integer) ||
          _is_integer_string?(val) ||
          int_classes.any? { |klass| val.is_a?(klass) }
      val.to_i
    else
      val # this will fail
    end
  when :float, :double
    if val.is_a?(Numeric) || _is_float_string?(val)
      val.to_f
    else
      val # this will fail
    end
  when :string
    if val.respond_to?(:to_str)
      val.to_s
    elsif _is_to_s_defined?(val)
      val.to_s
    else
      val # this will fail
    end
  when :boolean
    if val.nil? || val == false
      false
    else
      true
    end
  when :union
    coerce_union(type, val)
  when :record
    coerce_record(type, val)
  else
    val
  end
end

#coerce_union(type, val) ⇒ Object

Coerce sub-records in a payload to match the schema.

Parameters:

  • type (Avro::Schema::UnionSchema)
  • val (Object)

Returns:

  • (Object)


17
18
19
20
21
22
23
# File 'lib/deimos/schema_backends/avro_schema_coercer.rb', line 17

def coerce_union(type, val)
  union_types = type.schemas.map { |s| s.type.to_sym }
  return nil if val.nil? && union_types.include?(:null)

  schema_type = type.schemas.find { |s| s.type.to_sym != :null }
  coerce_type(schema_type, val)
end