babl-json 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5116d890ae716b94f6fcb09fd90591313beb68d
4
- data.tar.gz: 4bba953360594c5f46ad6160870a2ab469a932af
3
+ metadata.gz: 14b097a0829fb4d3a127ec290a6768576c9d20ed
4
+ data.tar.gz: 4753dead38682900489fff11c25abd23e72d1515
5
5
  SHA512:
6
- metadata.gz: 4467e3975a1f2f3130f68dc8fed5327b608838f2bcf8eebe61fae29fd5608ecc9de328192a2a2c5797ad54cce7ea68b6e9dc684c7c11ccf1c4a479f0147c54b9
7
- data.tar.gz: effc3f204316f2d67f0e74a8f6704fedae840b03ff41129697316c06f169d3a7363a2ccd3f0bfa9042f9398e5fe450b209290d7a1b7c38b1620aff426d086634
6
+ metadata.gz: '0809d686259d83c42c7053e049427767216ca3be7282f3a427a45125a7fc5f8e848b6b20771a700cea70a9684663eb9cf209c22128b9e33744d27e00f9944928'
7
+ data.tar.gz: 5f5eff014fd6ea456a1518c6a9dbf3681be309b414ad5f306ea5005cf011c2b001177b836c6b3bbcc18658bbbf5581b7bbb85abf9336fb6dc96b802c35facd3a
@@ -18,14 +18,14 @@ module Babl
18
18
  nodes.map(&:schema).reduce(Schema::FixedArray::EMPTY) { |a, b| merge_doc(a, b) }
19
19
  end
20
20
 
21
- def render(ctx)
21
+ def render(context, frame)
22
22
  out = []
23
23
  nodes.each { |node|
24
- values = node.render(ctx)
24
+ values = node.render(context, frame)
25
25
  case values
26
26
  when ::NilClass then nil
27
27
  when ::Array then out.concat(values)
28
- else raise Errors::RenderingError, "Only arrays can be concatenated\n" + ctx.formatted_stack
28
+ else raise Errors::RenderingError, "Only arrays can be concatenated\n" + context.formatted_stack(frame)
29
29
  end
30
30
  }
31
31
  out
@@ -5,7 +5,7 @@ require 'babl/utils'
5
5
  module Babl
6
6
  module Nodes
7
7
  class Constant < Utils::Value.new(:value, :schema)
8
- def render(_ctx)
8
+ def render(_context, _frame)
9
9
  value
10
10
  end
11
11
 
@@ -4,8 +4,10 @@ require 'babl/utils'
4
4
  module Babl
5
5
  module Nodes
6
6
  class CreatePin < Utils::Value.new(:node, :ref)
7
- def render(ctx)
8
- node.render(ctx.create_pin(ref))
7
+ def render(context, frame)
8
+ context.create_pin(frame, ref) do |new_frame|
9
+ node.render(context, new_frame)
10
+ end
9
11
  end
10
12
 
11
13
  def schema
@@ -4,8 +4,8 @@ require 'babl/utils'
4
4
  module Babl
5
5
  module Nodes
6
6
  class Dep < Utils::Value.new(:node, :path)
7
- def render(ctx)
8
- node.render(ctx)
7
+ def render(context, frame)
8
+ node.render(context, frame)
9
9
  end
10
10
 
11
11
  def schema
@@ -24,12 +24,17 @@ module Babl
24
24
  node.pinned_dependencies
25
25
  end
26
26
 
27
- def render(ctx)
28
- collection = ctx.object
27
+ def render(context, frame)
28
+ collection = frame.object
29
29
  unless Enumerable === collection
30
- raise Errors::RenderingError, "Not enumerable : #{collection}\n#{ctx.formatted_stack}"
30
+ raise Errors::RenderingError, "Not enumerable : #{collection.inspect}\n#{context.formatted_stack(frame)}"
31
+ end
32
+
33
+ collection.each_with_index.map do |value, idx|
34
+ context.move_forward(frame, value, idx) do |new_frame|
35
+ node.render(context, new_frame)
36
+ end
31
37
  end
32
- collection.each_with_index.map { |value, idx| node.render(ctx.move_forward(value, idx)) }
33
38
  end
34
39
 
35
40
  def optimize
@@ -20,8 +20,8 @@ module Babl
20
20
  nodes.map(&:pinned_dependencies).reduce(Utils::Hash::EMPTY) { |a, b| Babl::Utils::Hash.deep_merge(a, b) }
21
21
  end
22
22
 
23
- def render(ctx)
24
- nodes.map { |node| node.render(ctx) }
23
+ def render(context, frame)
24
+ nodes.map { |node| node.render(context, frame) }
25
25
  end
26
26
 
27
27
  def optimize
@@ -17,8 +17,10 @@ module Babl
17
17
  node.schema
18
18
  end
19
19
 
20
- def render(ctx)
21
- node.render(ctx.goto_pin(ref))
20
+ def render(context, frame)
21
+ context.goto_pin(frame, ref) do |new_frame|
22
+ node.render(context, new_frame)
23
+ end
22
24
  end
23
25
 
24
26
  def optimize
@@ -27,8 +27,8 @@ module Babl
27
27
  Utils::Hash::EMPTY
28
28
  end
29
29
 
30
- def render(ctx)
31
- ctx.object
30
+ def render(_context, frame)
31
+ frame.object
32
32
  end
33
33
 
34
34
  def optimize
@@ -20,8 +20,8 @@ module Babl
20
20
  Utils::Hash::EMPTY
21
21
  end
22
22
 
23
- def render(ctx)
24
- ::NilClass === ctx.object
23
+ def render(_context, frame)
24
+ ::NilClass === frame.object
25
25
  end
26
26
 
27
27
  def optimize
@@ -19,9 +19,10 @@ module Babl
19
19
  nodes.map(&:schema).reduce(Schema::Object::EMPTY) { |a, b| merge_doc(a, b) }
20
20
  end
21
21
 
22
- def render(ctx)
23
- nodes.map { |node| node.render(ctx) }.compact.reduce({}) { |acc, val|
24
- raise Errors::RenderingError, "Only objects can be merged\n" + ctx.formatted_stack unless ::Hash === val
22
+ def render(context, frame)
23
+ nodes.map { |node| node.render(context, frame) }.compact.reduce({}) { |acc, val|
24
+ raise Errors::RenderingError, "Only objects can be merged\n" +
25
+ context.formatted_stack(frame) unless ::Hash === val
25
26
  acc.merge!(val)
26
27
  }
27
28
  end
@@ -24,13 +24,17 @@ module Babl
24
24
  node.pinned_dependencies
25
25
  end
26
26
 
27
- def render(ctx)
27
+ def render(context, frame)
28
28
  value = begin
29
- ::Hash === ctx.object ? ctx.object.fetch(property) : ctx.object.send(property)
29
+ object = frame.object
30
+ ::Hash === object ? object.fetch(property) : object.send(property)
30
31
  rescue StandardError => e
31
- raise Errors::RenderingError, "#{e.message}\n" + ctx.formatted_stack(property), e.backtrace
32
+ raise Errors::RenderingError, "#{e.message}\n" + context.formatted_stack(frame, property), e.backtrace
33
+ end
34
+
35
+ context.move_forward(frame, value, property) do |new_frame|
36
+ node.render(context, new_frame)
32
37
  end
33
- node.render(ctx.move_forward(value, property))
34
38
  end
35
39
 
36
40
  def optimize
@@ -22,9 +22,9 @@ module Babl
22
22
  Schema::Object.new(properties, false)
23
23
  end
24
24
 
25
- def render(ctx)
25
+ def render(context, frame)
26
26
  out = {}
27
- nodes.each { |k, v| out[k] = v.render(ctx) }
27
+ nodes.each { |k, v| out[k] = v.render(context, frame) }
28
28
  out
29
29
  end
30
30
 
@@ -22,8 +22,8 @@ module Babl
22
22
  node.pinned_dependencies
23
23
  end
24
24
 
25
- def render(ctx)
26
- node.render(ctx)
25
+ def render(context, frame)
26
+ node.render(context, frame)
27
27
  end
28
28
 
29
29
  def optimize
@@ -43,8 +43,10 @@ module Babl
43
43
  { PARENT_MARKER => node.dependencies }
44
44
  end
45
45
 
46
- def render(ctx)
47
- node.render(ctx.move_backward)
46
+ def render(context, frame)
47
+ context.move_backward(frame) do |new_frame|
48
+ node.render(context, new_frame)
49
+ end
48
50
  end
49
51
 
50
52
  def optimize
@@ -27,8 +27,8 @@ module Babl
27
27
  Schema::AnyOf.canonicalized(nodes.map(&:last).map(&:schema))
28
28
  end
29
29
 
30
- def render(ctx)
31
- nodes.each { |cond, value| return value.render(ctx) if cond.render(ctx) }
30
+ def render(context, frame)
31
+ nodes.each { |cond, value| return value.render(context, frame) if cond.render(context, frame) }
32
32
  raise Errors::RenderingError, 'A least one switch() condition must be taken'
33
33
  end
34
34
 
@@ -24,10 +24,10 @@ module Babl
24
24
  Utils::Hash::EMPTY
25
25
  end
26
26
 
27
- def render(ctx)
28
- render_object(ctx.object)
27
+ def render(context, frame)
28
+ render_object(frame.object)
29
29
  rescue TerminalValueError => e
30
- raise Errors::RenderingError, "#{e.message}\n" + ctx.formatted_stack(e.babl_stack), e.backtrace
30
+ raise Errors::RenderingError, "#{e.message}\n" + context.formatted_stack(frame, e.babl_stack), e.backtrace
31
31
  end
32
32
 
33
33
  def render_object(obj, stack = nil)
@@ -37,7 +37,7 @@ module Babl
37
37
  when ::Symbol then obj.to_s
38
38
  when ::Hash then render_hash(obj, stack || [])
39
39
  when ::Array then render_array(obj, stack || [])
40
- else raise TerminalValueError.new("Only primitives can be serialized: #{obj}", stack || [])
40
+ else raise TerminalValueError.new("Only primitives can be serialized: #{obj.inspect}", stack || [])
41
41
  end
42
42
  end
43
43
 
@@ -76,7 +76,7 @@ module Babl
76
76
  when ::FalseClass then :false
77
77
  # rubocop:enable Lint/BooleanSymbol
78
78
  when ::Numeric, ::NilClass then :"#{key}"
79
- else raise TerminalValueError.new("Invalid key for JSON object: #{key}", stack)
79
+ else raise TerminalValueError.new("Invalid key for JSON object: #{key.inspect}", stack)
80
80
  end
81
81
  end
82
82
 
@@ -28,13 +28,13 @@ module Babl
28
28
  Schema::Typed::STRING
29
29
  end
30
30
 
31
- def render(ctx)
32
- value = ctx.object
31
+ def render(context, frame)
32
+ value = frame.object
33
33
  return value if ::String === value
34
34
  return value.to_s if ::Symbol === value
35
35
 
36
36
  raise Errors::RenderingError,
37
- "Expected a string, got #{value}\n#{ctx.formatted_stack}"
37
+ "Expected a string, got #{value.inspect}\n#{context.formatted_stack(frame)}"
38
38
  end
39
39
  end
40
40
 
@@ -43,12 +43,12 @@ module Babl
43
43
  Schema::Typed::INTEGER
44
44
  end
45
45
 
46
- def render(ctx)
47
- value = ctx.object
46
+ def render(context, frame)
47
+ value = frame.object
48
48
  return value if ::Integer === value
49
49
 
50
50
  raise Errors::RenderingError,
51
- "Expected an integer, got #{value}\n#{ctx.formatted_stack}"
51
+ "Expected an integer, got #{value.inspect}\n#{context.formatted_stack(frame)}"
52
52
  end
53
53
  end
54
54
 
@@ -57,13 +57,13 @@ module Babl
57
57
  Schema::Typed::NUMBER
58
58
  end
59
59
 
60
- def render(ctx)
61
- value = ctx.object
60
+ def render(context, frame)
61
+ value = frame.object
62
62
  return value if ::Integer === value
63
63
  return value.to_f if ::Numeric === value
64
64
 
65
65
  raise Errors::RenderingError,
66
- "Expected a number, got #{value}\n#{ctx.formatted_stack}"
66
+ "Expected a number, got #{value.inspect}\n#{context.formatted_stack(frame)}"
67
67
  end
68
68
  end
69
69
 
@@ -72,12 +72,12 @@ module Babl
72
72
  Schema::Typed::BOOLEAN
73
73
  end
74
74
 
75
- def render(ctx)
76
- value = ctx.object
75
+ def render(context, frame)
76
+ value = frame.object
77
77
  return value if true == value || false == value
78
78
 
79
79
  raise Errors::RenderingError,
80
- "Expected a boolean, got #{value}\n#{ctx.formatted_stack}"
80
+ "Expected a boolean, got #{value.inspect}\n#{context.formatted_stack(frame)}"
81
81
  end
82
82
  end
83
83
  end
@@ -23,14 +23,17 @@ module Babl
23
23
  .reduce(Utils::Hash::EMPTY) { |a, b| Babl::Utils::Hash.deep_merge(a, b) }
24
24
  end
25
25
 
26
- def render(ctx)
27
- values = nodes.map { |n| n.render(ctx) }
26
+ def render(context, frame)
27
+ values = nodes.map { |n| n.render(context, frame) }
28
28
  value = begin
29
- block.arity.zero? ? ctx.object.instance_exec(&block) : block.call(*values)
29
+ block.arity.zero? ? frame.object.instance_exec(&block) : block.call(*values)
30
30
  rescue StandardError => e
31
- raise Errors::RenderingError, "#{e.message}\n" + ctx.formatted_stack(:__block__), e.backtrace
31
+ raise Errors::RenderingError, "#{e.message}\n" + context.formatted_stack(frame, :__block__), e.backtrace
32
+ end
33
+
34
+ context.move_forward(frame, value, :__block__) do |new_frame|
35
+ node.render(context, new_frame)
32
36
  end
33
- node.render(ctx.move_forward(value, :__block__))
34
37
  end
35
38
 
36
39
  def optimize
@@ -13,8 +13,9 @@ module Babl
13
13
 
14
14
  def render(root)
15
15
  preloaded_data = preloader.preload([root], dependencies).first
16
- ctx = Context.new(preloaded_data)
17
- node.render(ctx)
16
+ context = Context.new
17
+ frame = Context::Frame.new(preloaded_data)
18
+ node.render(context, frame)
18
19
  end
19
20
  end
20
21
  end
@@ -4,54 +4,87 @@ require 'babl/utils'
4
4
 
5
5
  module Babl
6
6
  module Rendering
7
- # The rendering context stores the 'current' object.
8
- # Additionally, the context also:
9
- # - Keep a reference to the parent context, in order to implement the parent operation (Parent)
10
- # - Keep a reference to all pinned contexts, in order to goto a pinned context at any time (GotoPin)
11
- #
12
- # It is important to keep this object as small as possible, since an instance is created each time
13
- # we navigate into a property.
14
7
  class Context
15
- attr_reader :key, :object, :parent, :pins
8
+ class Frame
9
+ attr_accessor :object, :key, :parent, :pins
16
10
 
17
- def initialize(object, key = nil, parent = nil, pins = nil)
18
- @key = key
19
- @object = object
20
- @parent = parent
21
- @pins = pins
11
+ def initialize(object = nil)
12
+ @object = object
13
+ end
22
14
  end
23
15
 
24
- # Standard navigation (enter into property)
25
- def move_forward(new_object, key)
26
- Context.new(new_object, key, self, pins)
16
+ def initialize
17
+ @freelist = []
27
18
  end
28
19
 
29
- # Go back to parent
30
- def move_backward
31
- raise Errors::RenderingError, 'There is no parent element' unless parent
32
- Context.new(parent.object, parent.key, parent.parent, pins)
20
+ def move_forward(current_frame, new_object, key)
21
+ with_frame do |new_frame|
22
+ new_frame.object = new_object
23
+ new_frame.key = key
24
+ new_frame.parent = current_frame
25
+ new_frame.pins = current_frame.pins
26
+
27
+ yield new_frame
28
+ end
33
29
  end
34
30
 
35
- # Go to a pinned context
36
- def goto_pin(ref)
37
- pin = pins&.[](ref)
38
- raise Errors::RenderingError, 'Pin reference cannot be used here' unless pin
39
- Context.new(pin.object, pin.key, pin.parent, (pin.pins || Utils::Hash::EMPTY).merge(pins))
31
+ def move_backward(current_frame)
32
+ with_frame do |new_frame|
33
+ parent_frame = current_frame.parent
34
+ raise Errors::RenderingError, 'There is no parent element' unless parent_frame
35
+
36
+ new_frame.object = parent_frame.object
37
+ new_frame.parent = parent_frame.parent
38
+ new_frame.key = parent_frame.key
39
+ new_frame.pins = current_frame.pins
40
+
41
+ yield new_frame
42
+ end
40
43
  end
41
44
 
42
- # Associate a pin to current context
43
- def create_pin(ref)
44
- Context.new(object, key, parent, (pins || Utils::Hash::EMPTY).merge(ref => self))
45
+ def goto_pin(current_frame, ref)
46
+ current_pins = current_frame.pins || Utils::Hash::EMPTY
47
+ pin_frame = current_pins[ref]
48
+ raise Errors::RenderingError, 'Pin reference cannot be used here' unless pin_frame
49
+
50
+ with_frame do |new_frame|
51
+ new_frame.object = pin_frame.object
52
+ new_frame.parent = pin_frame.parent
53
+ new_frame.key = pin_frame.key
54
+ new_frame.pins = (pin_frame.pins || Utils::Hash::EMPTY).merge(current_pins)
55
+
56
+ yield new_frame
57
+ end
45
58
  end
46
59
 
47
- def formatted_stack(*additional_stack_items)
48
- stack_trace = ([:__root__] + stack + additional_stack_items).join('.')
60
+ def create_pin(current_frame, ref)
61
+ with_frame do |new_frame|
62
+ new_frame.parent = current_frame.parent
63
+ new_frame.object = current_frame.object
64
+ new_frame.key = current_frame.key
65
+ new_frame.pins = (current_frame.pins || Utils::Hash::EMPTY).merge(ref => new_frame)
66
+
67
+ yield new_frame
68
+ end
69
+ end
70
+
71
+ def stack(current_frame)
72
+ parent_frame = current_frame.parent
73
+ (parent_frame ? stack(parent_frame) : Utils::Array::EMPTY) + [current_frame.key].compact
74
+ end
75
+
76
+ def formatted_stack(current_frame, *additional_stack_items)
77
+ stack_trace = ([:__root__] + stack(current_frame) + additional_stack_items).join('.')
49
78
  "BABL @ #{stack_trace}"
50
79
  end
51
80
 
52
- # Return an array containing the navigation history
53
- def stack
54
- (parent ? parent.stack : Utils::Array::EMPTY) + [key].compact
81
+ private
82
+
83
+ def with_frame
84
+ frame = @freelist.pop || Frame.new
85
+ yield frame
86
+ ensure
87
+ @freelist << frame
55
88
  end
56
89
  end
57
90
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Babl
3
- VERSION = '0.5.2'
3
+ VERSION = '0.5.3'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babl-json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frederic Terrazzoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-06 00:00:00.000000000 Z
11
+ date: 2018-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coveralls