cel 0.2.1 → 0.2.2

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
  SHA256:
3
- metadata.gz: 54879dbe064eebebe6597acd098c6b10b8376f7b2333d2f822ca02c24a0815bb
4
- data.tar.gz: 95e2fed808711b64aedc8ed6aff2f8bc8eb9e5f9562907c0d794df186a35f035
3
+ metadata.gz: ed190ec0ddbda3e8c5229160dff580efa6cf1175f8b5ed5245e8de40f1feb800
4
+ data.tar.gz: 5f5d64c6a0199a0d47c7c29a3ef0c022f666e752147cadefbe6fc7090685e819
5
5
  SHA512:
6
- metadata.gz: 59349c9633015f0a63c297573e30e33d459de63f1af8ff032f808b045c069716c19142e2208f653864bd4a2363009dd7cb54c8feed3160e6c792c260853cc79f
7
- data.tar.gz: 2070807c5f7a01217117d96373372e111697727069b915a665acfc6fd2a58c6ff4adfb4fd747522585d7b03733cfb77ee2b7b726b6c36edb3f6d828a93ffed10
6
+ metadata.gz: c1c1aec4b0d8e54cf52a18057933c1ed214cddd79671ba6280f4e46f852c595f62259b4a10e2d8d0187d0b296f726b6dcae0b07aaccded157769b55f44d88900
7
+ data.tar.gz: 06c5d2653edca32b4cfb411a788734a0de1c9dcd6368f95b4ad4dcaeffe0b7fb82504c8e861d515acd19dbadb514804c5c6c108aa09e1600da0b9c1a60aec519
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.2] - 2023-08-17
4
+
5
+ * Reimplements `Cel::Literal#==` in a simpler way, to avoid several comparison issues arising from the previous implementation.
6
+ * fix initialization of `Cel::Duration` and `Cel::Timestamp` from string notation.
7
+ * fix protobuf-to-cel parsing of negative literals.
8
+ * more consistent usage of Cel types internally.
9
+ * fix condition clause evaluation.
10
+
11
+
3
12
  ## [0.2.1] - 2023-07-26
4
13
 
5
14
 
@@ -60,9 +60,15 @@ module Cel
60
60
 
61
61
  value = value.fetch(key, value)
62
62
 
63
- value = Number.new(:double, value) if key == "number_value"
64
-
65
- value
63
+ value = case key
64
+ when "null_value"
65
+ Null.new if value.zero?
66
+ when "number_value"
67
+ value = -value.operands.first if value.is_a?(Operation) && value.op == "-" && value.unary?
68
+ Number.new(:double, value)
69
+ else
70
+ value
71
+ end
66
72
  when "BoolValue", "google.protobuf.BoolValue"
67
73
  value = value.nil? ? Bool.new(false) : value[Identifier.new("value")]
68
74
  when "BytesValue", "google.protobuf.BytesValue"
@@ -143,6 +143,7 @@ module Cel
143
143
  end
144
144
 
145
145
  def ==(other)
146
+ other = other.value if other.is_a?(Literal)
146
147
  @value == other || super
147
148
  end
148
149
 
@@ -194,7 +195,7 @@ module Cel
194
195
  OUT
195
196
  end
196
197
 
197
- LOGICAL_OPERATORS.each do |op|
198
+ (LOGICAL_OPERATORS - %w[==]).each do |op|
198
199
  class_eval(<<-OUT, __FILE__, __LINE__ + 1)
199
200
  def #{op}(other)
200
201
  Bool.new(super)
@@ -208,13 +209,17 @@ module Cel
208
209
  super(:bool, value)
209
210
  end
210
211
 
211
- LOGICAL_OPERATORS.each do |op|
212
+ (LOGICAL_OPERATORS - %w[==]).each do |op|
212
213
  class_eval(<<-OUT, __FILE__, __LINE__ + 1)
213
214
  def #{op}(other)
214
215
  Bool.new(super)
215
216
  end
216
217
  OUT
217
218
  end
219
+
220
+ def !
221
+ Bool.new(super)
222
+ end
218
223
  end
219
224
 
220
225
  class Null < Literal
@@ -246,14 +251,6 @@ module Cel
246
251
  Macro.matches(self, pattern)
247
252
  end
248
253
 
249
- LOGICAL_OPERATORS.each do |op|
250
- class_eval(<<-OUT, __FILE__, __LINE__ + 1)
251
- def #{op}(other)
252
- other.is_a?(Cel::Literal) ? Bool.new(super) : super
253
- end
254
- OUT
255
- end
256
-
257
254
  %i[+ -].each do |op|
258
255
  class_eval(<<-OUT, __FILE__, __LINE__ + 1)
259
256
  def #{op}(other)
@@ -272,7 +269,7 @@ module Cel
272
269
  [self]
273
270
  end
274
271
 
275
- LOGICAL_OPERATORS.each do |op|
272
+ (LOGICAL_OPERATORS - %w[==]).each do |op|
276
273
  class_eval(<<-OUT, __FILE__, __LINE__ + 1)
277
274
  def #{op}(other)
278
275
  Bool.new(super)
@@ -358,7 +355,7 @@ module Cel
358
355
  class Timestamp < Literal
359
356
  def initialize(value)
360
357
  value = case value
361
- when String then Time.parse(value)
358
+ when ::String then Time.parse(value)
362
359
  when Numeric then Time.at(value)
363
360
  else value
364
361
  end
@@ -443,7 +440,7 @@ module Cel
443
440
  class Duration < Literal
444
441
  def initialize(value)
445
442
  value = case value
446
- when String
443
+ when ::String
447
444
  init_from_string(value)
448
445
  when Hash
449
446
  seconds, nanos = value.values_at(:seconds, :nanos)
@@ -553,6 +550,10 @@ module Cel
553
550
  end
554
551
  end
555
552
 
553
+ def unary?
554
+ @operands.size == 1
555
+ end
556
+
556
557
  def to_s
557
558
  return "#{@op}#{@operands.first}" if @operands.size == 1
558
559
 
data/lib/cel/ast/types.rb CHANGED
@@ -21,6 +21,8 @@ module Cel
21
21
  end
22
22
 
23
23
  def cast(value)
24
+ value = value.value if value.is_a?(Literal)
25
+
24
26
  case @type
25
27
  when :int
26
28
  Number.new(:int, Integer(value))
data/lib/cel/checker.rb CHANGED
@@ -357,7 +357,7 @@ module Cel
357
357
 
358
358
  return unless typ
359
359
 
360
- return convert(typ) if id_call_chain.empty?
360
+ convert(typ) if id_call_chain.empty?
361
361
  end
362
362
 
363
363
  def convert(typ)
data/lib/cel/macro.rb CHANGED
@@ -43,21 +43,24 @@ module Cel
43
43
  end
44
44
 
45
45
  def all(collection, identifier, predicate, context:)
46
- collection.all? do |element, *|
46
+ return_value = collection.all? do |element, *|
47
47
  Program.new(context.merge(identifier.to_sym => element)).evaluate(predicate).value
48
48
  end
49
+ Bool.new(return_value)
49
50
  end
50
51
 
51
52
  def exists(collection, identifier, predicate, context:)
52
- collection.any? do |element, *|
53
+ return_value = collection.any? do |element, *|
53
54
  Program.new(context.merge(identifier.to_sym => element)).evaluate(predicate).value
54
55
  end
56
+ Bool.new(return_value)
55
57
  end
56
58
 
57
59
  def exists_one(collection, identifier, predicate, context:)
58
- collection.one? do |element, *|
60
+ return_value = collection.one? do |element, *|
59
61
  Program.new(context.merge(identifier.to_sym => element)).evaluate(predicate).value
60
62
  end
63
+ Bool.new(return_value)
61
64
  end
62
65
 
63
66
  def filter(collection, identifier, predicate, context:)
data/lib/cel/program.rb CHANGED
@@ -57,20 +57,22 @@ module Cel
57
57
  ev_operand
58
58
  end
59
59
 
60
- if values.size == 1 &&
60
+ if operation.unary? &&
61
61
  op != "!" # https://bugs.ruby-lang.org/issues/18246
62
62
  # unary operations
63
- values.first.__send__(:"#{op}@")
63
+ Literal.to_cel_type(values.first.__send__(:"#{op}@"))
64
64
  elsif op == "&&"
65
- Bool.new(values.all? { |x| true == x }) # rubocop:disable Style/YodaCondition
65
+ Bool.new(values.all? { |x| true == x.value }) # rubocop:disable Style/YodaCondition
66
66
  elsif op == "||"
67
- Bool.new(values.any? { |x| true == x }) # rubocop:disable Style/YodaCondition
67
+ Bool.new(values.any? { |x| true == x.value }) # rubocop:disable Style/YodaCondition
68
68
  elsif op == "in"
69
69
  element, collection = values
70
70
  Bool.new(collection.include?(element))
71
71
  else
72
72
  op_value, *values = values
73
- op_value.public_send(op, *values)
73
+ val = op_value.public_send(op, *values)
74
+
75
+ Literal.to_cel_type(val)
74
76
  end
75
77
  end
76
78
 
@@ -120,7 +122,7 @@ module Cel
120
122
  end
121
123
 
122
124
  def evaluate_condition(condition)
123
- call(condition.if) ? call(condition.then) : call(condition.else)
125
+ call(condition.if).value ? call(condition.then) : call(condition.else)
124
126
  end
125
127
 
126
128
  def evaluate_standard_func(funcall)
@@ -135,11 +137,11 @@ module Cel
135
137
  val.class
136
138
  # MACROS
137
139
  when :has
138
- Bool.new(Macro.__send__(func, *args))
140
+ Macro.__send__(func, *args)
139
141
  when :size
140
142
  Cel::Number.new(:int, Macro.__send__(func, *args))
141
143
  when :matches
142
- Bool.new(Macro.__send__(func, *args.map(&method(:call))))
144
+ Macro.__send__(func, *args.map(&method(:call)))
143
145
  when :int, :uint, :string, :double, :bytes, :duration, :timestamp
144
146
  type = TYPES[func]
145
147
  type.cast(call(args.first))
data/lib/cel/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cel
4
4
  module Ruby
5
- VERSION = "0.2.1"
5
+ VERSION = "0.2.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-26 00:00:00.000000000 Z
11
+ date: 2023-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest