babl-json 0.2.6 → 0.3.0

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: 2ba3e05ba09552694ee2869f3105feb91ec3459c
4
- data.tar.gz: 1c5c24a986f264dc33db0d48a5f0885621c56793
3
+ metadata.gz: 871e1b12d52df06d65775112f9ff0f13aa42dfab
4
+ data.tar.gz: 72c86a1b58a6469be3dddbdf01e49b087abee471
5
5
  SHA512:
6
- metadata.gz: 4014ee582da9da899725759eb4b3f0242929c8870f7326de59a5e65416e17b92469dab7cbb7c960ab4d783f696e6aa5d0840cbde14ec0fc7f951de0012e915fd
7
- data.tar.gz: e3d4615978a94bd19c48f7089fa0722613b10dc44411f32d9f27cd8dbdf27c18f6dd62f59a9a0880fc22fb74991afbfcb111bb099e090d03f4f2c4523366dd63
6
+ metadata.gz: b32c9e4b2eec50edd2f427b4e05c7e6bc45220d22bfbef3c7d1f87387b6487f63068001f9385b82becaad66f0a9725e65d81e9eff321430544b251f4d4ecda41
7
+ data.tar.gz: 2d80756fd150ed750c5639a0a65187dba8ae4c58f64c0dfde2d2e80d859db1897322f1b126573522a799ce6b1b74a46aa63db7318632a0f27d43b18a6f7f79fb
data/lib/babl.rb CHANGED
@@ -7,12 +7,13 @@ require 'babl/operators'
7
7
 
8
8
  module Babl
9
9
  class Config
10
- attr_accessor :search_path, :preloader, :pretty
10
+ attr_accessor :search_path, :preloader, :pretty, :cache_templates
11
11
 
12
12
  def initialize
13
13
  @search_path = nil
14
14
  @preloader = Babl::Rendering::NoopPreloader
15
15
  @pretty = true
16
+ @cache_templates = false
16
17
  end
17
18
  end
18
19
 
@@ -14,15 +14,27 @@ module Babl
14
14
  @builder = builder
15
15
  end
16
16
 
17
- def compile(preloader: Rendering::NoopPreloader, pretty: true)
18
- node = precompile
17
+ def compile(preloader: Rendering::NoopPreloader, pretty: true, optimize: true)
18
+ # Compute dependencies & schema on the non-simplified node tree in order
19
+ # to catch all errors.
20
+ tree = precompile
21
+ dependencies = tree.dependencies
22
+ schema = tree.schema
23
+
24
+ # Recompute dependencies & schema on the simplified tree before
25
+ # exposing them to the user.
26
+ if optimize
27
+ tree = tree.optimize
28
+ dependencies = tree.dependencies
29
+ schema = tree.schema
30
+ end
19
31
 
20
32
  Rendering::CompiledTemplate.with(
21
33
  preloader: preloader,
22
34
  pretty: pretty,
23
- node: node,
24
- dependencies: node.dependencies,
25
- json_schema: node.schema.json
35
+ node: tree,
36
+ dependencies: dependencies,
37
+ json_schema: schema.json
26
38
  )
27
39
  end
28
40
 
data/lib/babl/nodes.rb CHANGED
@@ -5,11 +5,11 @@ require 'babl/nodes/each'
5
5
  require 'babl/nodes/fixed_array'
6
6
  require 'babl/nodes/goto_pin'
7
7
  require 'babl/nodes/internal_value'
8
+ require 'babl/nodes/is_null'
8
9
  require 'babl/nodes/merge'
9
10
  require 'babl/nodes/nav'
10
11
  require 'babl/nodes/object'
11
12
  require 'babl/nodes/parent'
12
- require 'babl/nodes/static'
13
13
  require 'babl/nodes/switch'
14
14
  require 'babl/nodes/terminal_value'
15
15
  require 'babl/nodes/typed'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'babl/schema'
3
+ require 'babl/utils'
4
+
5
+ module Babl
6
+ module Nodes
7
+ class Constant < Utils::Value.new(:value, :schema)
8
+ def render(_ctx)
9
+ value
10
+ end
11
+
12
+ def dependencies
13
+ Utils::Hash::EMPTY
14
+ end
15
+
16
+ def pinned_dependencies
17
+ Utils::Hash::EMPTY
18
+ end
19
+
20
+ def optimize
21
+ self
22
+ end
23
+ end
24
+ end
25
+ end
@@ -19,6 +19,11 @@ module Babl
19
19
  def pinned_dependencies
20
20
  node.pinned_dependencies.reject { |k, _v| k == ref }
21
21
  end
22
+
23
+ def optimize
24
+ optimized = node.optimize
25
+ optimized.pinned_dependencies[ref] ? CreatePin.new(optimized, ref) : optimized
26
+ end
22
27
  end
23
28
  end
24
29
  end
@@ -24,6 +24,10 @@ module Babl
24
24
  Babl::Utils::Hash.deep_merge(node.dependencies, path)
25
25
  end
26
26
 
27
+ def optimize
28
+ Dep.new(node.optimize, path)
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def canonicalize(path)
@@ -25,6 +25,10 @@ module Babl
25
25
  end
26
26
  collection.each_with_index.map { |value, idx| node.render(ctx.move_forward(value, idx)) }
27
27
  end
28
+
29
+ def optimize
30
+ Each.new(node.optimize)
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/schema'
3
3
  require 'babl/utils'
4
+ require 'babl/nodes/constant'
4
5
 
5
6
  module Babl
6
7
  module Nodes
@@ -20,6 +21,13 @@ module Babl
20
21
  def render(ctx)
21
22
  nodes.map { |node| node.render(ctx) }
22
23
  end
24
+
25
+ def optimize
26
+ optimized_nodes = nodes.map(&:optimize)
27
+ fixed_array = FixedArray.new(optimized_nodes)
28
+ return fixed_array unless optimized_nodes.all? { |node| Constant === node }
29
+ Constant.new(fixed_array.render(nil), fixed_array.schema)
30
+ end
23
31
  end
24
32
  end
25
33
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/utils'
3
+ require 'babl/nodes/constant'
3
4
 
4
5
  module Babl
5
6
  module Nodes
@@ -19,6 +20,11 @@ module Babl
19
20
  def render(ctx)
20
21
  node.render(ctx.goto_pin(ref))
21
22
  end
23
+
24
+ def optimize
25
+ optimized = node.optimize
26
+ Constant === optimized ? optimized : GotoPin.new(optimized, ref)
27
+ end
22
28
  end
23
29
  end
24
30
  end
@@ -13,9 +13,11 @@ module Babl
13
13
  class InternalValue
14
14
  include Singleton
15
15
 
16
+ # :nocov:
16
17
  def schema
17
18
  raise Errors::InvalidTemplate, 'Internal nodes cannot be documented'
18
19
  end
20
+ # :nocov:
19
21
 
20
22
  def dependencies
21
23
  Utils::Hash::EMPTY
@@ -28,6 +30,10 @@ module Babl
28
30
  def render(ctx)
29
31
  ctx.object
30
32
  end
33
+
34
+ def optimize
35
+ self
36
+ end
31
37
  end
32
38
  end
33
39
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require 'babl/utils'
3
+ require 'babl/schema'
4
+ require 'singleton'
5
+
6
+ module Babl
7
+ module Nodes
8
+ class IsNull
9
+ include Singleton
10
+
11
+ def schema
12
+ Schema::Typed::BOOLEAN
13
+ end
14
+
15
+ def dependencies
16
+ Utils::Hash::EMPTY
17
+ end
18
+
19
+ def pinned_dependencies
20
+ Utils::Hash::EMPTY
21
+ end
22
+
23
+ def render(ctx)
24
+ ::NilClass === ctx.object
25
+ end
26
+
27
+ def optimize
28
+ self
29
+ end
30
+ end
31
+ end
32
+ end
@@ -2,6 +2,7 @@
2
2
  require 'babl/errors'
3
3
  require 'babl/utils'
4
4
  require 'babl/schema'
5
+ require 'babl/nodes/constant'
5
6
 
6
7
  module Babl
7
8
  module Nodes
@@ -25,32 +26,67 @@ module Babl
25
26
  }
26
27
  end
27
28
 
28
- def self.build(nodes)
29
- return new(nodes) if nodes.empty?
30
- return nodes.first if nodes.size == 1 && Object === nodes.first
31
-
32
- expanded = nodes.flat_map { |node| Merge === node ? node.nodes : [node] }
33
- out = []
34
- op1 = nil
35
- op2 = expanded[0]
36
- expanded.drop(1).each do |elm|
37
- op1 = op2
38
- op2 = elm
39
- if Object === op1 && Object === op2
40
- op2 = Object.new(op1.nodes.merge(op2.nodes))
41
- op1 = nil
29
+ def optimize
30
+ optimize_empty ||
31
+ optimize_single ||
32
+ optimize_merged_objects ||
33
+ optimize_nested_merges ||
34
+ optimize_premergeable_objects ||
35
+ self
36
+ end
37
+
38
+ private
39
+
40
+ def optimize_empty
41
+ Constant.new({}, Schema::Object::EMPTY) if nodes.empty?
42
+ end
43
+
44
+ def optimize_single
45
+ return unless nodes.size == 1
46
+ optimized = nodes.first.optimize
47
+ case
48
+ when Object === optimized then optimized
49
+ when Constant === optimized && optimized.value.nil? then Object::EMPTY
50
+ end
51
+ end
52
+
53
+ def optimize_merged_objects
54
+ optimized_nodes = nodes.map(&:optimize)
55
+ optimized_nodes == nodes ? nil : Merge.new(optimized_nodes).optimize
56
+ end
57
+
58
+ def optimize_nested_merges
59
+ return unless nodes.any? { |node| Merge === node }
60
+ Merge.new(nodes.flat_map { |node| Merge === node ? node.nodes : [node] }).optimize
61
+ end
62
+
63
+ def optimize_premergeable_objects
64
+ nodes.each_cons(2).each_with_index do |(obj1, obj2), idx|
65
+ obj1 = constant_to_object(obj1) if Constant === obj1
66
+ obj2 = constant_to_object(obj2) if Constant === obj2
67
+
68
+ if Object === obj1 && Object === obj2
69
+ new_nodes = nodes.dup
70
+ new_nodes[idx] = Object.new(obj1.nodes.merge(obj2.nodes))
71
+ new_nodes[idx + 1] = nil
72
+ return Merge.new(new_nodes.compact).optimize
42
73
  end
43
- out << op1 if op1
44
74
  end
45
- out << op2 if op2
46
- new(out)
75
+ nil
47
76
  end
48
77
 
49
- private
78
+ def constant_to_object(constant)
79
+ case constant.schema
80
+ when Schema::Object
81
+ Object.new(constant.schema.property_set.map { |property|
82
+ [property.name, Constant.new(constant.value[property.name], property.value)]
83
+ }.to_h)
84
+ end
85
+ end
50
86
 
51
87
  AS_OBJECT_MAPPING = {
52
88
  Schema::Anything.instance => Schema::Object::EMPTY_WITH_ADDITIONAL,
53
- Schema::Static::NULL => Schema::Object::EMPTY
89
+ Schema::Primitive::NULL => Schema::Object::EMPTY
54
90
  }
55
91
 
56
92
  # Merge two documentations together
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/utils'
3
+ require 'babl/nodes/constant'
4
+ require 'babl/nodes/parent'
3
5
 
4
6
  module Babl
5
7
  module Nodes
@@ -25,9 +27,11 @@ module Babl
25
27
  node.render(ctx.move_forward(value, through))
26
28
  end
27
29
 
28
- private
29
-
30
- def navigate(object)
30
+ def optimize
31
+ optimized = node.optimize
32
+ return optimized if Constant === optimized
33
+ return optimized.node if Parent === optimized
34
+ Nav.new(through, optimized)
31
35
  end
32
36
  end
33
37
  end
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/schema'
3
3
  require 'babl/utils'
4
+ require 'babl/nodes/constant'
4
5
 
5
6
  module Babl
6
7
  module Nodes
7
8
  class Object < Utils::Value.new(:nodes)
9
+ EMPTY = new({})
10
+
8
11
  def dependencies
9
12
  nodes.values.map(&:dependencies).reduce(Utils::Hash::EMPTY) { |a, b| Babl::Utils::Hash.deep_merge(a, b) }
10
13
  end
@@ -24,6 +27,13 @@ module Babl
24
27
  nodes.each { |k, v| out[k] = v.render(ctx) }
25
28
  out
26
29
  end
30
+
31
+ def optimize
32
+ optimized_nodes = nodes.map { |k, v| [k, v.optimize] }.to_h
33
+ optimized_object = Object.new(optimized_nodes)
34
+ return optimized_object unless optimized_nodes.values.all? { |node| Constant === node }
35
+ Constant.new(optimized_object.render(nil), optimized_object.schema)
36
+ end
27
37
  end
28
38
  end
29
39
  end
@@ -24,6 +24,10 @@ module Babl
24
24
  node.render(ctx)
25
25
  end
26
26
 
27
+ def optimize
28
+ Resolver.new(node.optimize)
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def backpropagate_dependencies(deps)
@@ -59,6 +63,11 @@ module Babl
59
63
  def render(ctx)
60
64
  node.render(ctx.move_backward)
61
65
  end
66
+
67
+ def optimize
68
+ optimized = node.optimize
69
+ Constant === optimized ? optimized : Parent.new(optimized)
70
+ end
62
71
  end
63
72
  end
64
73
  end
@@ -2,28 +2,67 @@
2
2
  require 'babl/schema'
3
3
  require 'babl/errors'
4
4
  require 'babl/utils'
5
+ require 'babl/nodes/constant'
5
6
 
6
7
  module Babl
7
8
  module Nodes
8
9
  class Switch < Utils::Value.new(:nodes)
10
+ def initialize(nodes)
11
+ raise Errors::InvalidTemplate, 'A least one switch() condition must be taken' if nodes.empty?
12
+ super
13
+ end
14
+
9
15
  def dependencies
10
- (nodes.values + nodes.keys).map(&:dependencies)
16
+ nodes.flatten(1).map(&:dependencies)
11
17
  .reduce(Utils::Hash::EMPTY) { |a, b| Babl::Utils::Hash.deep_merge(a, b) }
12
18
  end
13
19
 
14
20
  def pinned_dependencies
15
- (nodes.values + nodes.keys).map(&:pinned_dependencies)
21
+ nodes.flatten(1).map(&:pinned_dependencies)
16
22
  .reduce(Utils::Hash::EMPTY) { |a, b| Babl::Utils::Hash.deep_merge(a, b) }
17
23
  end
18
24
 
19
25
  def schema
20
- Schema::AnyOf.canonicalized(nodes.values.map(&:schema))
26
+ Schema::AnyOf.canonicalized(nodes.map(&:last).map(&:schema))
21
27
  end
22
28
 
23
29
  def render(ctx)
24
30
  nodes.each { |cond, value| return value.render(ctx) if cond.render(ctx) }
25
31
  raise Errors::RenderingError, 'A least one switch() condition must be taken'
26
32
  end
33
+
34
+ def optimize
35
+ optimize_condition_and_values ||
36
+ optimize_falsy_conditions ||
37
+ optimize_truthy_conditions ||
38
+ optimize_always_same_outputs ||
39
+ self
40
+ end
41
+
42
+ private
43
+
44
+ def optimize_always_same_outputs
45
+ return unless nodes.map(&:first).any? { |node| Constant === node && node.value }
46
+ return unless nodes.map(&:last).uniq.size == 1
47
+ nodes.first.last.optimize
48
+ end
49
+
50
+ def optimize_truthy_conditions
51
+ nodes[0...-1].each_with_index do |(cond, _value), index|
52
+ return Switch.new(nodes[0..index]).optimize if Constant === cond && cond.value
53
+ end
54
+ nil
55
+ end
56
+
57
+ def optimize_condition_and_values
58
+ optimized = nodes.map { |k, v| [k.optimize, v.optimize] }
59
+ optimized == nodes ? nil : Switch.new(optimized).optimize
60
+ end
61
+
62
+ def optimize_falsy_conditions
63
+ optimized = nodes.reject { |(cond, _value)| Constant === cond && !cond.value }
64
+ optimized.size == nodes.size ? nil : Switch.new(optimized).optimize
65
+ end
27
66
  end
28
67
  end
29
68
  end
@@ -35,10 +35,15 @@ module Babl
35
35
  when ::String, ::Numeric, ::NilClass, ::TrueClass, ::FalseClass then obj
36
36
  when ::Hash then render_hash(obj, stack || [])
37
37
  when ::Array then render_array(obj, stack || [])
38
+ when ::Symbol then obj.to_s
38
39
  else raise TerminalValueError.new("Only primitives can be serialized: #{obj}", stack || [])
39
40
  end
40
41
  end
41
42
 
43
+ def optimize
44
+ self
45
+ end
46
+
42
47
  private
43
48
 
44
49
  def render_array(array, stack)
@@ -23,6 +23,10 @@ module Babl
23
23
  return value if schema.classes.any? { |clazz| clazz === value }
24
24
  raise Errors::RenderingError, "Expected type '#{schema.type}': #{value}\n#{ctx.formatted_stack}"
25
25
  end
26
+
27
+ def optimize
28
+ self
29
+ end
26
30
  end
27
31
  end
28
32
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'babl/utils'
3
+ require 'babl/nodes/constant'
3
4
 
4
5
  module Babl
5
6
  module Nodes
@@ -27,6 +28,12 @@ module Babl
27
28
  end
28
29
  node.render(ctx.move_forward(value, :__block__))
29
30
  end
31
+
32
+ def optimize
33
+ optimized = node.optimize
34
+ return optimized if Constant === optimized
35
+ With.new(optimized, nodes.map(&:optimize), block)
36
+ end
30
37
  end
31
38
  end
32
39
  end
@@ -7,6 +7,7 @@ require 'babl/operators/dep'
7
7
  require 'babl/operators/each'
8
8
  require 'babl/operators/enter'
9
9
  require 'babl/operators/extends'
10
+ require 'babl/operators/is_null'
10
11
  require 'babl/operators/merge'
11
12
  require 'babl/operators/nav'
12
13
  require 'babl/operators/null'
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ require 'babl/nodes'
3
+
4
+ module Babl
5
+ module Operators
6
+ module IsNull
7
+ module DSL
8
+ def null?
9
+ construct_terminal { Nodes::IsNull.instance }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -11,7 +11,7 @@ module Babl
11
11
  return call(Utils::Hash::EMPTY) if templates.empty?
12
12
 
13
13
  construct_terminal { |context|
14
- Nodes::Merge.build(
14
+ Nodes::Merge.new(
15
15
  templates.map { |t|
16
16
  unscoped.call(t).builder.precompile(
17
17
  Nodes::TerminalValue.instance,
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
+ require 'babl/nodes'
3
+
2
4
  module Babl
3
5
  module Operators
4
6
  module Nullable
5
7
  module DSL
6
- IS_NIL = ->(val) { ::NilClass === val }
7
-
8
- # Nullify the current construction if
9
- # the current element is Nil.
10
- def nullable
8
+ # Nullify the current construction if the condition is truthy.
9
+ # By default, it produces null when the current element is Nil.
10
+ def nullable(nullcond = unscoped.null?)
11
11
  source {
12
12
  switch(
13
- nav(&IS_NIL) => nil,
13
+ nullcond => nil,
14
14
  default => continue
15
15
  )
16
16
  }
@@ -10,7 +10,7 @@ module Babl
10
10
  def static(val)
11
11
  case val
12
12
  when ::String, ::Numeric, ::NilClass, ::TrueClass, ::FalseClass
13
- construct_terminal { Nodes::Static.new(val) }
13
+ construct_terminal { Nodes::Constant.new(val, Schema::Primitive.new(val)) }
14
14
  else call(Nodes::TerminalValue.instance.render_object(val))
15
15
  end
16
16
  rescue Errors::RenderingError => exception
@@ -17,7 +17,7 @@ module Babl
17
17
  .precompile(Nodes::TerminalValue.instance, context.merge(continue: node))
18
18
 
19
19
  [cond_node, value_node]
20
- }.to_h
20
+ }
21
21
 
22
22
  Nodes::Switch.new(nodes)
23
23
  }
data/lib/babl/railtie.rb CHANGED
@@ -1,19 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
  module Babl
3
3
  module ActionView
4
- module Template
5
- class Handler
6
- class_attribute :default_format
7
- self.default_format = Mime[:json]
4
+ class TemplateHandler
5
+ class_attribute :default_format
6
+ self.default_format = Mime[:json]
8
7
 
9
- def self.call(template)
10
- # This implementation is not efficient: it will recompile the BABL template
11
- # for each request. I still don't get why Rails template handlers MUST
12
- # return Ruby code ?! Sucks too much. Ideally, we would like to keep the compiled
13
- # template somewhere. However, I've not yet measured how much like is wasted.
14
- # Maybe it is negligible ?
15
- <<~RUBY
16
- Babl.compile { #{template.source} }.json(local_assigns)
8
+ class << self
9
+ def cached_templates
10
+ @cached_templates ||= {}
11
+ end
12
+
13
+ def call(template)
14
+ Babl.config.cache_templates ? cached_call(template) : uncached_call(template)
15
+ end
16
+
17
+ private
18
+
19
+ def cached_call(template)
20
+ cached_templates[template.identifier] ||= Babl.compile {
21
+ source(template.source, template.identifier)
22
+ }
23
+
24
+ <<-RUBY
25
+ compiled = ::Babl::ActionView::TemplateHandler.cached_templates[#{template.identifier.inspect}]
26
+ compiled.json(local_assigns)
27
+ RUBY
28
+ end
29
+
30
+ def uncached_call(template)
31
+ <<-RUBY
32
+ Babl.compile {
33
+ source(
34
+ #{template.source.inspect},
35
+ #{template.identifier.inspect}
36
+ )
37
+ }.json(local_assigns)
17
38
  RUBY
18
39
  end
19
40
  end
@@ -23,7 +44,7 @@ module Babl
23
44
  class Railtie < Rails::Railtie
24
45
  initializer "babl.initialize" do
25
46
  ActiveSupport.on_load(:action_view) do
26
- ::ActionView::Template.register_template_handler(:babl, Babl::ActionView::Template::Handler)
47
+ ::ActionView::Template.register_template_handler(:babl, Babl::ActionView::TemplateHandler)
27
48
  end
28
49
  end
29
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require 'oj'
2
+ require 'multi_json'
3
3
  require 'babl/rendering'
4
4
  require 'babl/utils'
5
5
 
@@ -8,7 +8,7 @@ module Babl
8
8
  class CompiledTemplate < Utils::Value.new(:node, :dependencies, :preloader, :pretty, :json_schema)
9
9
  def json(root)
10
10
  data = render(root)
11
- ::Oj.dump(data, indent: pretty ? 4 : 0, mode: :strict)
11
+ ::MultiJson.dump(data, pretty: pretty)
12
12
  end
13
13
 
14
14
  def render(root)
data/lib/babl/schema.rb CHANGED
@@ -4,5 +4,5 @@ require 'babl/schema/anything'
4
4
  require 'babl/schema/dyn_array'
5
5
  require 'babl/schema/fixed_array'
6
6
  require 'babl/schema/object'
7
- require 'babl/schema/static'
7
+ require 'babl/schema/primitive'
8
8
  require 'babl/schema/typed'
@@ -47,8 +47,8 @@ module Babl
47
47
 
48
48
  # AnyOf[true, false] is just boolean
49
49
  def simplify_boolean
50
- return unless choice_set.include?(Static::TRUE) && choice_set.include?(Static::FALSE)
51
- AnyOf.canonicalized(choice_set - [Static::TRUE, Static::FALSE] + [Typed::BOOLEAN])
50
+ return unless choice_set.include?(Primitive::TRUE) && choice_set.include?(Primitive::FALSE)
51
+ AnyOf.canonicalized(choice_set - [Primitive::TRUE, Primitive::FALSE] + [Typed::BOOLEAN])
52
52
  end
53
53
 
54
54
  # AnyOf[string, 'a string instance', 'another string'] is just string
@@ -59,7 +59,7 @@ module Babl
59
59
  choice_set.each do |typed|
60
60
  next unless Typed === typed
61
61
  instances = choice_set.select { |instance|
62
- Static === instance && typed.classes.any? { |clazz| clazz === instance.value }
62
+ Primitive === instance && typed.classes.any? { |clazz| clazz === instance.value }
63
63
  }
64
64
  next if instances.empty?
65
65
  return AnyOf.canonicalized(choice_set - instances)
@@ -118,7 +118,9 @@ module Babl
118
118
  # We will abort the merging process unless all the other properties are exactly the same.
119
119
  discriminator = obj1props.find { |name, p1|
120
120
  p2 = obj2props[name]
121
- next name if p2 && Static === p2.value && Static === p1.value && p1.value.value != p2.value.value
121
+ next name if p2 && Primitive === p2.value &&
122
+ Primitive === p1.value &&
123
+ p1.value.value != p2.value.value
122
124
  }&.first
123
125
 
124
126
  new_properties = (obj1props.keys + obj2props.keys).uniq.map { |name|
@@ -3,7 +3,7 @@ require 'babl/utils'
3
3
 
4
4
  module Babl
5
5
  module Schema
6
- class Static < Utils::Value.new(:value, :json)
6
+ class Primitive < Utils::Value.new(:value, :json)
7
7
  def initialize(value)
8
8
  super(value, ::NilClass === value ? { type: 'null' } : { enum: [value] })
9
9
  end
data/lib/babl/template.rb CHANGED
@@ -12,6 +12,7 @@ module Babl
12
12
  include Operators::Each::DSL
13
13
  include Operators::Enter::DSL
14
14
  include Operators::Extends::DSL
15
+ include Operators::IsNull::DSL
15
16
  include Operators::Merge::DSL
16
17
  include Operators::Nav::DSL
17
18
  include Operators::Null::DSL
data/lib/babl/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Babl
3
- VERSION = '0.2.6'
3
+ VERSION = '0.3.0'
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.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frederic Terrazzoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-28 00:00:00.000000000 Z
11
+ date: 2017-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -67,19 +67,47 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.8'
69
69
  - !ruby/object:Gem::Dependency
70
- name: oj
70
+ name: coveralls
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '3.0'
75
+ version: '0.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: jbuilder
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: multi_json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1'
76
104
  type: :runtime
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
- version: '3.0'
110
+ version: '1'
83
111
  description: JSON templating on steroids
84
112
  email:
85
113
  - frederic.terrazzoni@gmail.com
@@ -93,17 +121,18 @@ files:
93
121
  - lib/babl/builder/template_base.rb
94
122
  - lib/babl/errors.rb
95
123
  - lib/babl/nodes.rb
124
+ - lib/babl/nodes/constant.rb
96
125
  - lib/babl/nodes/create_pin.rb
97
126
  - lib/babl/nodes/dep.rb
98
127
  - lib/babl/nodes/each.rb
99
128
  - lib/babl/nodes/fixed_array.rb
100
129
  - lib/babl/nodes/goto_pin.rb
101
130
  - lib/babl/nodes/internal_value.rb
131
+ - lib/babl/nodes/is_null.rb
102
132
  - lib/babl/nodes/merge.rb
103
133
  - lib/babl/nodes/nav.rb
104
134
  - lib/babl/nodes/object.rb
105
135
  - lib/babl/nodes/parent.rb
106
- - lib/babl/nodes/static.rb
107
136
  - lib/babl/nodes/switch.rb
108
137
  - lib/babl/nodes/terminal_value.rb
109
138
  - lib/babl/nodes/typed.rb
@@ -117,6 +146,7 @@ files:
117
146
  - lib/babl/operators/each.rb
118
147
  - lib/babl/operators/enter.rb
119
148
  - lib/babl/operators/extends.rb
149
+ - lib/babl/operators/is_null.rb
120
150
  - lib/babl/operators/merge.rb
121
151
  - lib/babl/operators/nav.rb
122
152
  - lib/babl/operators/null.rb
@@ -141,7 +171,7 @@ files:
141
171
  - lib/babl/schema/dyn_array.rb
142
172
  - lib/babl/schema/fixed_array.rb
143
173
  - lib/babl/schema/object.rb
144
- - lib/babl/schema/static.rb
174
+ - lib/babl/schema/primitive.rb
145
175
  - lib/babl/schema/typed.rb
146
176
  - lib/babl/template.rb
147
177
  - lib/babl/utils.rb
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'babl/schema'
3
- require 'babl/utils'
4
-
5
- module Babl
6
- module Nodes
7
- class Static < Utils::Value.new(:value)
8
- def schema
9
- case value
10
- when ::NilClass then Schema::Static::NULL
11
- when ::TrueClass then Schema::Static::TRUE
12
- when ::FalseClass then Schema::Static::FALSE
13
- else Schema::Static.new(value)
14
- end
15
- end
16
-
17
- def render(_ctx)
18
- value
19
- end
20
-
21
- def dependencies
22
- Utils::Hash::EMPTY
23
- end
24
-
25
- def pinned_dependencies
26
- Utils::Hash::EMPTY
27
- end
28
-
29
- private
30
-
31
- def generate_doc
32
- end
33
- end
34
- end
35
- end