Class: Props::Base

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

Direct Known Subclasses

BaseWithExtensions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(encoder = nil) ⇒ Base

Returns a new instance of Base.



14
15
16
17
18
# File 'lib/props_template/base.rb', line 14

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

Instance Attribute Details

#item_contextObject

Returns the value of attribute item_context.



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

def item_context
  @item_context
end

Instance Method Details

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



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/props_template/base.rb', line 83

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 block_given?
    if collection.nil?
      @child_index = nil
      yield
    else
      handle_collection(collection, options) do |item, index|
        yield item, index
      end
    end
  elsif options.is_a?(Props::Options)
    options.valid_for_set!
    handle_collection(collection, options) {}
  else
    raise ArgumentError.new("array! requires a block when no Props::Options object is given")
  end

  @scope = :array

  nil
end

#child!(options = {}) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/props_template/base.rb', line 134

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_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]



119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/props_template/base.rb', line 119

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



38
39
40
# File 'lib/props_template/base.rb', line 38

def format_key(key)
  key.to_s
end

#handle_collection(collection, options) ⇒ Object



74
75
76
77
78
79
80
81
# File 'lib/props_template/base.rb', line 74

def handle_collection(collection, options)
  collection.each_with_index do |item, index|
    handle_collection_item(collection, item, index, options) do
      # todo: remove index?
      yield item, index
    end
  end
end

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



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

def handle_collection_item(collection, item, index, options)
  @item_context = item

  set_content!(options) do
    yield
  end
end

#handle_set_block(key, options) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/props_template/base.rb', line 30

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

#result!Object



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/props_template/base.rb', line 156

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



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/props_template/base.rb', line 42

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_content!(options = {}) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/props_template/base.rb', line 20

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