
gems.virtus-1.0.5.lib.virtus.attribute.collection.rb Maven / Gradle / Ivy
The newest version!
module Virtus
class Attribute
# Collection attribute handles enumerable-like types
#
# Handles coercing members to the designated member type.
#
class Collection < Attribute
default Proc.new { |_, attribute| attribute.primitive.new }
# @api private
attr_reader :member_type
# FIXME: temporary hack, remove when Axiom::Type works with EV as member_type
Type = Struct.new(:primitive, :member_type) do
def self.infer(type, primitive)
return type if axiom_type?(type)
klass = Axiom::Types.infer(type)
member = infer_member_type(type) || Object
if EmbeddedValue.handles?(member) || pending?(member)
Type.new(primitive, member)
else
klass.new {
primitive primitive
member_type Axiom::Types.infer(member)
}
end
end
def self.pending?(primitive)
primitive.is_a?(String) || primitive.is_a?(Symbol)
end
def self.axiom_type?(type)
type.is_a?(Class) && type < Axiom::Types::Type
end
def self.infer_member_type(type)
return unless type.respond_to?(:count)
member_type =
if type.count > 1
raise NotImplementedError, "build SumType from list of types (#{type})"
else
type.first
end
if member_type.is_a?(Class) && member_type < Attribute && member_type.primitive
member_type.primitive
else
member_type
end
end
def coercion_method
:to_array
end
end
# @api private
def self.build_type(definition)
Type.infer(definition.type, definition.primitive)
end
# @api private
def self.merge_options!(type, options)
options[:member_type] ||= Attribute.build(type.member_type, strict: options[:strict])
end
# @api public
def coerce(value)
coerced = super
return coerced unless coerced.respond_to?(:each_with_object)
coerced.each_with_object(primitive.new) do |entry, collection|
collection << member_type.coerce(entry)
end
end
# @api private
def finalize
return self if finalized?
@member_type = @options[:member_type].finalize
super
end
# @api private
def finalized?
super && member_type.finalized?
end
end # class Collection
end # class Attribute
end # module Virtus
© 2015 - 2025 Weber Informatics LLC | Privacy Policy