Sha256: f13eb5441af9046eaf5c959c91f4cdc6a0618b56a50b6674ba9581213bff22c0

Contents?: true

Size: 1.72 KB

Versions: 18

Compression:

Stored size: 1.72 KB

Contents

require 'avromatic/model/attribute_type/union'
require 'avromatic/io/datum_reader'

module Avromatic
  module Model
    module Attribute

      # This subclass of Virtus::Attribute is used for any unions that are
      # defined as subclasses of the primitive Avromatic::Model::AttributeType::Union.
      # Values are coerced by first checking if they already match one of the
      # member types, and then by attempting to coerce to each member type in
      # order.
      class Union < Virtus::Attribute
        primitive Avromatic::Model::AttributeType::Union

        MEMBER_INDEX = ::Avromatic::IO::DatumReader::UNION_MEMBER_INDEX

        def initialize(*)
          super

          primitive.types.each do |type|
            member_attributes << Virtus::Attribute.build(type)
          end
        end

        def coerce(input)
          return input if value_coerced?(input)

          result = nil
          if input && input.key?(MEMBER_INDEX)
            result = safe_coerce(member_attributes[input.delete(MEMBER_INDEX)], input)
          else
            member_attributes.find do |union_attribute|
              result = safe_coerce(union_attribute, input)
            end
          end
          result
        end

        def value_coerced?(value)
          member_attributes.any? do |union_attribute|
            union_attribute.value_coerced?(value)
          end
        end

        private

        def safe_coerce(member_attribute, input)
          coerced = member_attribute.coerce(input)
          coerced unless coerced.is_a?(Avromatic::Model::Attributes) && coerced.invalid?
        rescue
          nil
        end

        def member_attributes
          @member_attributes ||= Array.new
        end
      end
    end
  end
end

Version data entries

18 entries across 18 versions & 1 rubygems

Version Path
avromatic-0.23.0 lib/avromatic/model/attribute/union.rb
avromatic-0.22.0 lib/avromatic/model/attribute/union.rb
avromatic-0.21.1 lib/avromatic/model/attribute/union.rb
avromatic-0.21.0 lib/avromatic/model/attribute/union.rb
avromatic-0.21.0.rc1 lib/avromatic/model/attribute/union.rb
avromatic-0.21.0.rc0 lib/avromatic/model/attribute/union.rb
avromatic-0.20.0 lib/avromatic/model/attribute/union.rb
avromatic-0.19.0 lib/avromatic/model/attribute/union.rb
avromatic-0.18.1 lib/avromatic/model/attribute/union.rb
avromatic-0.18.0 lib/avromatic/model/attribute/union.rb
avromatic-0.18.0.rc0 lib/avromatic/model/attribute/union.rb
avromatic-0.17.1 lib/avromatic/model/attribute/union.rb
avromatic-0.17.0 lib/avromatic/model/attribute/union.rb
avromatic-0.15.1 lib/avromatic/model/attribute/union.rb
avromatic-0.15.0 lib/avromatic/model/attribute/union.rb
avromatic-0.15.0.rc0 lib/avromatic/model/attribute/union.rb
avromatic-0.14.0 lib/avromatic/model/attribute/union.rb
avromatic-0.14.0.rc1 lib/avromatic/model/attribute/union.rb