class HashCast::AttributesCaster

Attributes

attributes[R]
options[R]

Public Class Methods

new(attributes, options) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 4
def initialize(attributes, options)
  @attributes = attributes
  @options    = options
end

Public Instance Methods

cast(input_hash) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 9
def cast(input_hash)
  casted_hash = {}

  hash_keys = get_keys(input_hash)
  attributes.each do |attribute|
    if hash_keys.include?(attribute.name)
      begin
        casted_value = cast_attribute(attribute, input_hash)
        casted_hash[cast_key(attribute.name, options)] = casted_value
      rescue HashCast::Errors::AttributeError => e
        e.add_namespace(attribute.name)
        raise e
      end
    else
      raise HashCast::Errors::MissingAttributeError.new("should be given", attribute.name) if attribute.required?
    end
  end

  if !options[:skip_unexpected_attributes]
    check_unexpected_attributes_not_given!(hash_keys, casted_hash.keys)
  end

  casted_hash
end

Private Instance Methods

cast_attribute(attribute, hash) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 36
def cast_attribute(attribute, hash)
  value = get_value(hash, attribute.name)
  return nil if value.nil? && attribute.allow_nil?

  casted_value = attribute.caster.cast(value, attribute.name, attribute.options)

  if attribute.has_children?
    return cast_children(casted_value, attribute)
  end
  if caster = attribute.options[:caster]
    return cast_children_with_caster(casted_value, attribute, caster)
  end

  casted_value
end
cast_children(value, attribute) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 52
def cast_children(value, attribute)
  caster = self.class.new(attribute.children, options)
  cast_children_with_caster(value, attribute, caster)
end
cast_children_with_caster(value, attribute, caster) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 57
def cast_children_with_caster(value, attribute, caster)
  return caster.cast(value) if attribute.caster != HashCast::Casters::ArrayCaster

  value.map do |val|
    caster.cast(val)
  end
end
cast_key(value, options) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 65
def cast_key(value, options)
  return value      if options[:output_keys] == :symbol
  return value.to_s if options[:output_keys] == :string
end
check_unexpected_attributes_not_given!(input_hash_keys, casted_hash_keys) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 81
def check_unexpected_attributes_not_given!(input_hash_keys, casted_hash_keys)
  unexpected_keys = keys_diff(input_hash_keys, casted_hash_keys)
  unless unexpected_keys.empty?
    raise HashCast::Errors::UnexpectedAttributeError.new("is not valid attribute name", unexpected_keys.first)
  end
end
get_keys(hash) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 70
def get_keys(hash)
  return hash.keys if same_in_out_key_format?
  hash.keys.map(&:to_sym)
end
get_value(hash, key) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 75
def get_value(hash, key)
  return hash[key]        if same_in_out_key_format?
  return hash[key.to_sym] if options[:input_keys] == :symbol
  hash[key.to_s]
end
keys_diff(input_hash_keys, casted_hash_keys) click to toggle source
# File lib/hashcast/attributes_caster.rb, line 92
def keys_diff(input_hash_keys, casted_hash_keys)
  return (input_hash_keys - casted_hash_keys) if same_in_out_key_format?
  return (input_hash_keys - casted_hash_keys) if options[:output_keys] == :symbol # same for symbol
  return (input_hash_keys - casted_hash_keys.map(&:to_sym)) if options[:output_keys] == :string
end
same_in_out_key_format?() click to toggle source
# File lib/hashcast/attributes_caster.rb, line 88
def same_in_out_key_format?
  options[:input_keys] == options[:output_keys]
end