15
15
package cel
16
16
17
17
import (
18
+ "fmt"
18
19
"math"
19
20
"strconv"
20
21
"strings"
@@ -35,9 +36,11 @@ const (
35
36
optMapMacro = "optMap"
36
37
optFlatMapMacro = "optFlatMap"
37
38
hasValueFunc = "hasValue"
39
+ unwrapOptFunc = "unwrapOpt"
38
40
optionalNoneFunc = "optional.none"
39
41
optionalOfFunc = "optional.of"
40
42
optionalOfNonZeroValueFunc = "optional.ofNonZeroValue"
43
+ optionalUnwrapFunc = "optional.unwrap"
41
44
valueFunc = "value"
42
45
unusedIterVar = "#unused"
43
46
)
@@ -281,6 +284,16 @@ func (stdLibrary) ProgramOptions() []ProgramOption {
281
284
//
282
285
// This is syntactic sugar for msg.elements[msg.elements.size()-1].
283
286
287
+ // # Unwrap / UnwrapOpt
288
+ //
289
+ // Introduced in version: 2
290
+ //
291
+ // Returns a list of all the values that are not none in the input list of optional values.
292
+ // Can be used as optional.unwrap(List[T]) or with postfix notation: List[T].unwrapOpt()
293
+ //
294
+ // optional.unwrap([optional.of(42), optional.none()]) == [42]
295
+ // [optional.of(42), optional.none()].unwrapOpt() == [42]
296
+
284
297
func OptionalTypes (opts ... OptionalTypesOption ) EnvOption {
285
298
lib := & optionalLib {version : math .MaxUint32 }
286
299
for _ , opt := range opts {
@@ -324,6 +337,7 @@ func (lib *optionalLib) CompileOptions() []EnvOption {
324
337
optionalTypeV := OptionalType (paramTypeV )
325
338
listTypeV := ListType (paramTypeV )
326
339
mapTypeKV := MapType (paramTypeK , paramTypeV )
340
+ listOptionalTypeV := ListType (optionalTypeV )
327
341
328
342
opts := []EnvOption {
329
343
// Enable the optional syntax in the parser.
@@ -427,6 +441,13 @@ func (lib *optionalLib) CompileOptions() []EnvOption {
427
441
}),
428
442
),
429
443
))
444
+
445
+ opts = append (opts , Function (optionalUnwrapFunc ,
446
+ Overload ("optional_unwrap" , []* Type {listOptionalTypeV }, listTypeV ,
447
+ UnaryBinding (optUnwrap ))))
448
+ opts = append (opts , Function (unwrapOptFunc ,
449
+ MemberOverload ("optional_unwrapOpt" , []* Type {listOptionalTypeV }, listTypeV ,
450
+ UnaryBinding (optUnwrap ))))
430
451
}
431
452
432
453
return opts
@@ -493,6 +514,23 @@ func optFlatMap(meh MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Exp
493
514
), nil
494
515
}
495
516
517
+ func optUnwrap (value ref.Val ) ref.Val {
518
+ list := value .(traits.Lister )
519
+ var unwrappedList []ref.Val
520
+ iter := list .Iterator ()
521
+ for iter .HasNext () == types .True {
522
+ val := iter .Next ()
523
+ opt , isOpt := val .(* types.Optional )
524
+ if ! isOpt {
525
+ return types .WrapErr (fmt .Errorf ("value %v is not optional" , val ))
526
+ }
527
+ if opt .HasValue () {
528
+ unwrappedList = append (unwrappedList , opt .GetValue ())
529
+ }
530
+ }
531
+ return types .DefaultTypeAdapter .NativeToValue (unwrappedList )
532
+ }
533
+
496
534
func enableOptionalSyntax () EnvOption {
497
535
return func (e * Env ) (* Env , error ) {
498
536
e .prsrOpts = append (e .prsrOpts , parser .EnableOptionalSyntax (true ))
0 commit comments