babl-json 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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