Class: Plaster::ModelDeconstructor

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/plaster/model_deconstructor.rb

Overview

Deconstructs a hierarchical data structure comprised of struct-like and array-like objects into a homologous structure of hashes (HashWithIndifferentAccess) and arrays (Array).

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_instanceObject



14
15
16
# File 'lib/plaster/model_deconstructor.rb', line 14

def default_instance
  @default_instance ||= new
end

Instance Method Details

#bag_like?(obj) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/plaster/model_deconstructor.rb', line 39

def bag_like?(obj)
  return true if \
    obj.respond_to?( :to_ary )

  return false if \
    obj.respond_to?( :to_hash )

  obj.respond_to?( :to_a   ) &&
  obj.respond_to?( :each   ) &&
  obj.respond_to?( :map    ) &&
  obj.respond_to?( :&      ) &&
  obj.respond_to?( :|      ) &&
  obj.respond_to?( :+      ) &&
  obj.respond_to?( :-      )
end

#call(obj) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/plaster/model_deconstructor.rb', line 23

def call(obj)
  if obj.respond_to?( :model_deconstruct )
    obj.model_deconstruct
  elsif obj.respond_to?( :to_hash )
    deconstruct_from_hash( obj )
  elsif bag_like?( obj )
    deconstruct_from_bag_like( obj )
  elsif hash_like?( obj )
    deconstruct_from_hash_like( obj )
  elsif map_like?( obj )
    deconstruct_from_map_like( obj )
  else
    obj
  end
end

#deconstruct_from_bag_like(obj) ⇒ Object



71
72
73
74
75
# File 'lib/plaster/model_deconstructor.rb', line 71

def deconstruct_from_bag_like(obj)
  obj.map { |entry|
    call( entry )
  }
end

#deconstruct_from_hash(hash) ⇒ Object



66
67
68
69
# File 'lib/plaster/model_deconstructor.rb', line 66

def deconstruct_from_hash(hash)
  hash = HashWIA.new( hash.to_hash )
  deconstruct_hash_values!( hash )
end

#deconstruct_from_hash_like(obj) ⇒ Object



77
78
79
80
# File 'lib/plaster/model_deconstructor.rb', line 77

def deconstruct_from_hash_like(obj)
  hash = HashWithIndifferentAccess.new(obj.to_h)
  deconstruct_hash_values!( hash )
end

#deconstruct_from_map_like(obj) ⇒ Object



82
83
84
85
86
87
# File 'lib/plaster/model_deconstructor.rb', line 82

def deconstruct_from_map_like(obj)
  hash = HashWIA.new.tap do |h|
    obj.each_pair do |k,v| ; h[k] = v ; end
  end
  deconstruct_hash_values!( hash )
end

#deconstruct_hash_values!(hash) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/plaster/model_deconstructor.rb', line 89

def deconstruct_hash_values!(hash)
  hash.each_pair do |k,v|
    dv = call( v )
    hash[k] = dv unless dv.equal?( v )
  end
  hash
end

#hash_like?(obj) ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
58
# File 'lib/plaster/model_deconstructor.rb', line 55

def hash_like?(obj)
  obj.respond_to?( :to_h      ) &&
  obj.respond_to?( :each_pair )
end

#map_like?(obj) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
63
64
# File 'lib/plaster/model_deconstructor.rb', line 60

def map_like?(obj)
  obj.respond_to?( :each_pair ) &&
  obj.respond_to?( :values    ) &&
  obj.respond_to?( :[]        )
end