1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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
|
module Virtus
class Attribute
# EmbeddedValue handles virtus-like objects, OpenStruct and Struct
#
class EmbeddedValue < Attribute
TYPES = [Struct, OpenStruct, Virtus, Model::Constructor].freeze
# Builds Struct-like instance with attributes passed to the constructor as
# a list of args rather than a hash
#
# @private
class FromStruct < Virtus::Coercer
# @api public
def call(input)
if input.kind_of?(primitive)
input
elsif not input.nil?
primitive.new(*input)
end
end
end # FromStruct
# Builds OpenStruct-like instance with attributes passed to the constructor
# as a hash
#
# @private
class FromOpenStruct < Virtus::Coercer
# @api public
def call(input)
if input.kind_of?(primitive)
input
elsif not input.nil?
primitive.new(input)
end
end
end # FromOpenStruct
# @api private
def self.handles?(klass)
klass.is_a?(Class) && TYPES.any? { |type| klass <= type }
end
# @api private
def self.build_type(definition)
Axiom::Types::Object.new { primitive definition.primitive }
end
# @api private
def self.build_coercer(type, _options)
primitive = type.primitive
if primitive < Virtus || primitive < Model::Constructor || primitive <= OpenStruct
FromOpenStruct.new(type)
elsif primitive < Struct
FromStruct.new(type)
end
end
end # class EmbeddedValue
end # class Attribute
end # module Virtus
|