Class: Ecfr::AttributeCaster

Inherits:
Object
  • Object
show all
Defined in:
lib/ecfr/attribute_caster.rb

Class Method Summary collapse

Class Method Details

.cast_attr(val, type, options = {}) ⇒ Object

Note:

some API endpoints do not return a key for values that are false (such as processing_in_progress). Because the attribute is not include in the response it can not be typecast as boolean false (it will return nil however which is still falsey)

Given a value and a type return the value cast to the type. Some types do not actually modify the value but exist in order to support automated documentation via YARD.

Parameters:

  • val (<Integer, Float, String>)

    the value as parsed from a JSON response

  • type (<Symbol, Class>)

    a type to cast the value to, classes will be instantiated with the value

  • options (<Hash>) (defaults to: {})

    options are passed to classes when they are instantiated. false is merged into these options to indicate that metadata attributes (among other things) should not be populated. See Base#initialize

Returns:

  • a typecast value



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
# File 'lib/ecfr/attribute_caster.rb', line 24

def self.cast_attr(val, type, options = {})
  return val if val.nil?

  case type
  when :integer
    val # JSON parse was sufficient
  when :float
    val # JSON parse was sufficient
  when :boolean
    ActiveModel::Type::Boolean.new.cast(val)
  when :date
    return val if val.is_a?(Date)
    Date.parse(val.to_s)
  when :datetime
    return val if val.is_a?(DateTime)
    DateTime.parse(val.to_s)
  when :symbol
    val.to_sym
  when ->(type) { type.respond_to?(:new) }
    instantiate(type, val, options.merge(base: false))
    # type.new(val, options.merge(base: false))
  when ->(type) { type.is_a?(Array) && type.first.respond_to?(:new) }
    val.map { |v| instantiate(type.first, v, options.merge(base: false)) } # type.first.new(v, options.merge(base: false)) }
  when ->(type) { type.is_a?(Array) && type.first == :symbol }
    val.map(&:to_sym)
  when ->(type) { type.is_a?(Array) && [:integer, :string].include?(type.first) }
    val # JSON parse was sufficient
  when nil
    val # JSON parse was sufficient
  else
    raise "Undefined type '#{type}' provided to 'attribute'/'metadata'!"
  end
end