class ValueSemantics::ValueObjectCoercer

A coercer for converting hashes into instances of value classes

The coercer will coerce hash-like values into an instance of the value class, using the hash for attribute values. It will return non-hash-like values unchanged. It will also return hash-like values unchanged if they do not contain all required attributes of the value class.

Constants

NOT_FOUND

Attributes

value_class[R]

Public Class Methods

new(value_class) click to toggle source
# File lib/value_semantics/value_object_coercer.rb, line 13
def initialize(value_class)
  @value_class = value_class
end

Public Instance Methods

call(obj) click to toggle source
# File lib/value_semantics/value_object_coercer.rb, line 17
def call(obj)
  attrs = coerce_to_attr_hash(obj)
  if attrs
    value_class.new(attrs)
  else
    obj
  end
end

Private Instance Methods

coerce_to_attr_hash(obj) click to toggle source
# File lib/value_semantics/value_object_coercer.rb, line 29
def coerce_to_attr_hash(obj)
  # TODO: this coerces nil to an empty hash, which is probably not ideal.
  # It should not coerce nil so that Either(X, nil) validator works as
  # expected. This is a backwards-incomptible change, so save it for a
  # major version bump
  return nil unless obj.respond_to?(:to_h)
  obj_hash = obj.to_h

  {}.tap do |attrs|
    value_class.value_semantics.attributes.each do |attr_def|
      name = attr_def.name
      value = obj_hash.fetch(name) do
        obj_hash.fetch(name.to_s, NOT_FOUND)
      end
      attrs[name] = value unless value.equal?(NOT_FOUND)
    end
  end
end