babl-json 0.2.6 → 0.3.0

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: 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