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



16
17
18
# File 'lib/plaster/model_deconstructor.rb', line 16

def default_instance
  @default_instance ||= new
end

Instance Method Details

#bag_like?(obj) ⇒ Boolean

Returns:

  • (Boolean)


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

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



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

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



73
74
75
76
77
# File 'lib/plaster/model_deconstructor.rb', line 73

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

#deconstruct_from_hash(hash) ⇒ Object



68
69
70
71
# File 'lib/plaster/model_deconstructor.rb', line 68

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

#deconstruct_from_hash_like(obj) ⇒ Object



79
80
81
82
# File 'lib/plaster/model_deconstructor.rb', line 79

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

#deconstruct_from_map_like(obj) ⇒ Object



84
85
86
87
88
89
# File 'lib/plaster/model_deconstructor.rb', line 84

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



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

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)


57
58
59
60
# File 'lib/plaster/model_deconstructor.rb', line 57

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

#map_like?(obj) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
# File 'lib/plaster/model_deconstructor.rb', line 62

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