Class: Props::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/props_template/base.rb

Direct Known Subclasses

BaseWithExtensions

Instance Method Summary collapse

Constructor Details

#initialize(encoder = nil) ⇒ Base

Returns a new instance of Base.



12
13
14
15
# File 'lib/props_template/base.rb', line 12

def initialize(encoder = nil)
  @stream = Oj::StringWriter.new(mode: :rails)
  @scope = nil
end

Instance Method Details

#array!(collection = nil, options = {}) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/props_template/base.rb', line 92

def array!(collection = nil, options = {})
  if @scope.nil?
    @scope = :array
    @stream.push_array
  else
    raise InvalidScopeForArrayError.new("array! expects exclusive use of this block")
  end

  if collection.nil?
    @child_index = nil
    yield
  else
    handle_collection(collection, options) do |item, index|
      yield item, index
    end
  end

  @scope = :array

  nil
end

#child!(options = {}) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/props_template/base.rb', line 140

def child!(options = {})
  if @scope != :array
    raise InvalidScopeForChildError.new("child! can only be used in a `array!` with no arguments")
  end

  if !block_given?
    raise ArgumentError.new("child! requires a block")
  end

  inner_scope = @scope
  child_index = @child_index || -1
  child_index += 1

  # this changes the scope to nil so child in a child will break
  set_block_content!(options) do
    yield
  end

  @scope = inner_scope
  @child_index = child_index
end

#extract!(object, *values) ⇒ Object

json.id item.id json.value item.value

json.extract! item, :id, :value

with key transformation json.extract! item, :id, [:first_name, :firstName]



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/props_template/base.rb', line 125

def extract!(object, *values)
  values.each do |value|
    key, attribute = if value.is_a?(Array)
      [value[1], value[0]]
    else
      [value, value]
    end

    set!(
      key,
      object.is_a?(Hash) ? object.fetch(attribute) : object.public_send(attribute)
    )
  end
end

#format_key(key) ⇒ Object



34
35
36
# File 'lib/props_template/base.rb', line 34

def format_key(key)
  key.to_s
end

#handle_collection(collection, options) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/props_template/base.rb', line 76

def handle_collection(collection, options)
  all_opts = collection.map do |item|
    refine_item_options(item, options.clone)
  end

  all_opts = refine_all_item_options(all_opts)

  collection.each_with_index do |item, index|
    pass_opts = all_opts[index]
    handle_collection_item(collection, item, index, pass_opts) do
      # todo: remove index?
      yield item, index
    end
  end
end

#handle_collection_item(collection, item, index, options) ⇒ Object



66
67
68
69
70
# File 'lib/props_template/base.rb', line 66

def handle_collection_item(collection, item, index, options)
  set_block_content!(options) do
    yield
  end
end

#handle_set_block(key, options) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/props_template/base.rb', line 26

def handle_set_block(key, options)
  key = format_key(key)
  @stream.push_key(key)
  set_block_content!(options) do
    yield
  end
end

#partial!(**options) ⇒ Object



114
115
116
# File 'lib/props_template/base.rb', line 114

def partial!(**options)
  @context.render options
end

#refine_all_item_options(all_options) ⇒ Object



72
73
74
# File 'lib/props_template/base.rb', line 72

def refine_all_item_options(all_options)
  all_options
end

#refine_item_options(item, options) ⇒ Object



62
63
64
# File 'lib/props_template/base.rb', line 62

def refine_item_options(item, options)
  options
end

#result!Object



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/props_template/base.rb', line 162

def result!
  if @scope.nil?
    @stream.push_object
  end
  @stream.pop

  json = @stream.raw_json
  @stream.reset

  @scope = nil
  json
end

#set!(key, value = nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/props_template/base.rb', line 38

def set!(key, value = nil)
  if @scope == :array
    raise InvalidScopeForObjError.new("Attempted to set! on an array! scope")
  end

  if @scope.nil?
    @scope = :object
    @stream.push_object
  end

  if block_given?
    handle_set_block(key, value) do
      yield
    end
  else
    key = format_key(key)
    @stream.push_value(value, key)
  end

  @scope = :object

  nil
end

#set_block_content!(options = {}) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/props_template/base.rb', line 17

def set_block_content!(options = {})
  @scope = nil
  yield
  if @scope.nil?
    @stream.push_object
  end
  @stream.pop
end