module Surrealist::ValueAssigner
A class that determines the correct value to return for serialization. May descend recursively.
Public Class Methods
Assigns value returned from a method to a corresponding key in the schema hash.
@param [Object] instance the instance of the object which methods from the schema are called on. @param [Struct] schema containing a single schema key and value
@return [Hash] schema
# File lib/surrealist/value_assigner.rb, line 13 def assign(schema, instance) value = raw_value(instance, schema) # set to track and prevent infinite self references in surrealization @skip_set ||= Set.new if value.respond_to?(:build_schema) yield assign_nested_record(instance, value) elsif Helper.collection?(value) && !value.empty? && value.all? { |v| Helper.surrealist?(v.class) } yield assign_nested_collection(instance, value) else yield value end end
Private Class Methods
Assists in recursively generating schema for records while preventing infinite self-referencing
@param [Object] instance the instance of the object which methods from the schema are called on. @param [Object] value a value that has to be type-checked.
@return [Array] of schemas
# File lib/surrealist/value_assigner.rb, line 78 def assign_nested_collection(instance, value) return if @skip_set.include?(value.first.class) with_skip_set(instance.class) { Surrealist.surrealize_collection(value, raw: true) } end
Assists in recursively generating schema for a record while preventing infinite self-referencing
@param [Object] instance the instance of the object which methods from the schema are called on. @param [Object] value a value that has to be type-checked.
@return [Hash] schema
# File lib/surrealist/value_assigner.rb, line 90 def assign_nested_record(instance, value) return if @skip_set.include?(value.class) with_skip_set(instance.class) { value.build_schema } end
Coerces value if type check is passed
@param [Object] value the value to be checked and coerced @param [Struct] schema containing a single schema key and value
@raise Surrealist::InvalidTypeError
if type-check failed at some point.
@return [Object] value to be further processed
# File lib/surrealist/value_assigner.rb, line 64 def coerce_value(value, schema) unless TypeHelper.valid_type?(value, schema.value) raise Surrealist::InvalidTypeError, "Wrong type for key `#{schema.key}`. Expected #{schema.value}, got #{value.class}." end TypeHelper.coerce(value, schema.value) end
Checks if there is a custom serializer defined for the object and invokes the method
on it first only if the serializer has not defined the same method.
@param [Object] instance an instance of a model or a serializer @param [Symbol] method the schema key that represents the method to be invoked
@return [Object] the return value of the method
# File lib/surrealist/value_assigner.rb, line 48 def invoke_method(instance, method) object = instance.instance_variable_get(:@object) instance_method = instance.class.method_defined?(method) || instance.class.private_method_defined?(method) invoke_object = !instance_method && object && object.respond_to?(method, true) invoke_object ? object.send(method) : instance.send(method) end
Generates first pass of serializing value, doing type check and coercion
@param [Object] instance the instance of the object which methods from the schema are called on. @param [Struct] schema containing a single schema key and value
@return [Object] value to be further processed
# File lib/surrealist/value_assigner.rb, line 36 def raw_value(instance, schema) value = instance.is_a?(Hash) ? instance[schema.key] : invoke_method(instance, schema.key) coerce_value(value, schema) end
Run block with klass in skip set
@param [Class] klass of current instance.
@return [Object] block result
# File lib/surrealist/value_assigner.rb, line 101 def with_skip_set(klass) return yield if @skip_set.include?(klass) @skip_set.add(klass) result = yield @skip_set.delete(klass) result end