class Attributor::Polymorphic

Attributes

discriminator[R]
types[R]

Public Class Methods

construct(constructor_block, **_options) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 45
def self.construct(constructor_block, **_options)
  return self if constructor_block.nil?

  self.instance_eval(&constructor_block)
  self
end
constructable?() click to toggle source
# File lib/attributor/types/polymorphic.rb, line 37
def self.constructable?
  true
end
describe(shallow = false, example: nil) click to toggle source
Calls superclass method
# File lib/attributor/types/polymorphic.rb, line 106
def self.describe(shallow = false, example: nil)
  super.merge(
    discriminator: self.discriminator,
    types: self.describe_types
  )
end
describe_types() click to toggle source
# File lib/attributor/types/polymorphic.rb, line 113
def self.describe_types
  self.types.each_with_object({}) do |(key, value), description|
    description[key] = { type: value.describe(true) }
  end
end
discriminator_value_for(parsed_value) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 67
def self.discriminator_value_for(parsed_value)
  return parsed_value[self.discriminator] if parsed_value.key?(self.discriminator)

  value = case self.discriminator
          when ::String
            parsed_value[self.discriminator.to_sym]
          when ::Symbol
            parsed_value[self.discriminator.to_s]
          end

  return value if value

  raise LoadError, "can't find key #{self.discriminator.inspect} in #{parsed_value.inspect}"
end
dump(value, **opts) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 82
def self.dump(value, **opts)
  if (loaded = load(value))
    loaded.dump(**opts)
  end
end
example(context = nil, **values) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 29
def self.example(context = nil, **values)
  types.values.sample.example(context, **values)
end
given(value, type) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 19
def self.given(value, type)
  @types[value] = type
end
inherited(klass) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 23
def self.inherited(klass)
  klass.instance_eval do
    @types = {}
  end
end
load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 52
def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
  return nil if value.nil?

  return value if self.types.values.include?(value.class)

  parsed_value = self.parse(value, context)

  discriminator_value = discriminator_value_for(parsed_value)

  type = self.types.fetch(discriminator_value) do
    raise LoadError, "invalid value for discriminator: #{discriminator_value}"
  end
  type.load(parsed_value)
end
native_type() click to toggle source
# File lib/attributor/types/polymorphic.rb, line 41
def self.native_type
  self
end
on(discriminator) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 13
def self.on(discriminator)
  ::Class.new(self) do
    @discriminator = discriminator
  end
end
parse(value, context) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 88
def self.parse(value, context)
  if value.nil?
    {}
  elsif value.is_a?(Attributor::Hash)
    value.contents
  elsif value.is_a?(::Hash)
    value
  elsif value.is_a?(::String)
    decode_json(value, context)
  elsif value.respond_to?(:to_h)
    value.to_h
  elsif value.respond_to?(:to_hash) # Deprecate this in lieu of to_h only?
    value.to_hash
  else
    raise Attributor::IncompatibleTypeError, context: context, value_type: value.class, type: self
  end
end
valid_type?(value) click to toggle source
# File lib/attributor/types/polymorphic.rb, line 33
def self.valid_type?(value)
  self.types.values.include?(value.class)
end