Skip to content

Commit 1c5745b

Browse files
Add Expression.asBoolean() (#15547)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 83d0a4e commit 1c5745b

File tree

6 files changed

+269
-158
lines changed

6 files changed

+269
-158
lines changed

Firestore/Swift/Source/ExpressionImplementation.swift

Lines changed: 92 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,24 @@ extension Expression {
376376
}
377377

378378
public extension Expression {
379+
func asBoolean() -> BooleanExpression {
380+
switch self {
381+
case let boolExpr as BooleanExpression:
382+
return boolExpr
383+
case let constant as Constant:
384+
return BooleanConstant(constant)
385+
case let field as Field:
386+
return BooleanField(field)
387+
case let funcExpr as FunctionExpression:
388+
return BooleanFunctionExpression(funcExpr)
389+
default:
390+
// This should be unreachable if all expression types are handled.
391+
fatalError(
392+
"Unknown expression type \(Swift.type(of: self)) cannot be converted to BooleanExpression"
393+
)
394+
}
395+
}
396+
379397
func `as`(_ name: String) -> AliasedExpression {
380398
return AliasedExpression(self, name)
381399
}
@@ -474,38 +492,56 @@ public extension Expression {
474492
}
475493

476494
func arrayContains(_ element: Expression) -> BooleanExpression {
477-
return BooleanExpression(functionName: "array_contains", args: [self, element])
495+
return BooleanFunctionExpression(functionName: "array_contains", args: [self, element])
478496
}
479497

480498
func arrayContains(_ element: Sendable) -> BooleanExpression {
481-
return BooleanExpression(
499+
return BooleanFunctionExpression(
482500
functionName: "array_contains",
483501
args: [self, Helper.sendableToExpr(element)]
484502
)
485503
}
486504

487505
func arrayContainsAll(_ values: [Expression]) -> BooleanExpression {
488-
return BooleanExpression(functionName: "array_contains_all", args: [self, Helper.array(values)])
506+
return BooleanFunctionExpression(
507+
functionName: "array_contains_all",
508+
args: [self, Helper.array(values)]
509+
)
489510
}
490511

491512
func arrayContainsAll(_ values: [Sendable]) -> BooleanExpression {
492-
return BooleanExpression(functionName: "array_contains_all", args: [self, Helper.array(values)])
513+
return BooleanFunctionExpression(
514+
functionName: "array_contains_all",
515+
args: [self, Helper.array(values)]
516+
)
493517
}
494518

495519
func arrayContainsAll(_ arrayExpression: Expression) -> BooleanExpression {
496-
return BooleanExpression(functionName: "array_contains_all", args: [self, arrayExpression])
520+
return BooleanFunctionExpression(
521+
functionName: "array_contains_all",
522+
args: [self, arrayExpression]
523+
)
497524
}
498525

499526
func arrayContainsAny(_ values: [Expression]) -> BooleanExpression {
500-
return BooleanExpression(functionName: "array_contains_any", args: [self, Helper.array(values)])
527+
return BooleanFunctionExpression(
528+
functionName: "array_contains_any",
529+
args: [self, Helper.array(values)]
530+
)
501531
}
502532

503533
func arrayContainsAny(_ values: [Sendable]) -> BooleanExpression {
504-
return BooleanExpression(functionName: "array_contains_any", args: [self, Helper.array(values)])
534+
return BooleanFunctionExpression(
535+
functionName: "array_contains_any",
536+
args: [self, Helper.array(values)]
537+
)
505538
}
506539

507540
func arrayContainsAny(_ arrayExpression: Expression) -> BooleanExpression {
508-
return BooleanExpression(functionName: "array_contains_any", args: [self, arrayExpression])
541+
return BooleanFunctionExpression(
542+
functionName: "array_contains_any",
543+
args: [self, arrayExpression]
544+
)
509545
}
510546

511547
func arrayLength() -> FunctionExpression {
@@ -532,96 +568,105 @@ public extension Expression {
532568
}
533569

534570
func greaterThan(_ other: Expression) -> BooleanExpression {
535-
return BooleanExpression(functionName: "greater_than", args: [self, other])
571+
return BooleanFunctionExpression(functionName: "greater_than", args: [self, other])
536572
}
537573

538574
func greaterThan(_ other: Sendable) -> BooleanExpression {
539575
let exprOther = Helper.sendableToExpr(other)
540-
return BooleanExpression(functionName: "greater_than", args: [self, exprOther])
576+
return BooleanFunctionExpression(functionName: "greater_than", args: [self, exprOther])
541577
}
542578

543579
func greaterThanOrEqual(_ other: Expression) -> BooleanExpression {
544-
return BooleanExpression(functionName: "greater_than_or_equal", args: [self, other])
580+
return BooleanFunctionExpression(functionName: "greater_than_or_equal", args: [self, other])
545581
}
546582

547583
func greaterThanOrEqual(_ other: Sendable) -> BooleanExpression {
548584
let exprOther = Helper.sendableToExpr(other)
549-
return BooleanExpression(functionName: "greater_than_or_equal", args: [self, exprOther])
585+
return BooleanFunctionExpression(functionName: "greater_than_or_equal", args: [self, exprOther])
550586
}
551587

552588
func lessThan(_ other: Expression) -> BooleanExpression {
553-
return BooleanExpression(functionName: "less_than", args: [self, other])
589+
return BooleanFunctionExpression(functionName: "less_than", args: [self, other])
554590
}
555591

556592
func lessThan(_ other: Sendable) -> BooleanExpression {
557593
let exprOther = Helper.sendableToExpr(other)
558-
return BooleanExpression(functionName: "less_than", args: [self, exprOther])
594+
return BooleanFunctionExpression(functionName: "less_than", args: [self, exprOther])
559595
}
560596

561597
func lessThanOrEqual(_ other: Expression) -> BooleanExpression {
562-
return BooleanExpression(functionName: "less_than_or_equal", args: [self, other])
598+
return BooleanFunctionExpression(functionName: "less_than_or_equal", args: [self, other])
563599
}
564600

565601
func lessThanOrEqual(_ other: Sendable) -> BooleanExpression {
566602
let exprOther = Helper.sendableToExpr(other)
567-
return BooleanExpression(functionName: "less_than_or_equal", args: [self, exprOther])
603+
return BooleanFunctionExpression(functionName: "less_than_or_equal", args: [self, exprOther])
568604
}
569605

570606
func equal(_ other: Expression) -> BooleanExpression {
571-
return BooleanExpression(functionName: "equal", args: [self, other])
607+
return BooleanFunctionExpression(functionName: "equal", args: [self, other])
572608
}
573609

574610
func equal(_ other: Sendable) -> BooleanExpression {
575611
let exprOther = Helper.sendableToExpr(other)
576-
return BooleanExpression(functionName: "equal", args: [self, exprOther])
612+
return BooleanFunctionExpression(functionName: "equal", args: [self, exprOther])
577613
}
578614

579615
func notEqual(_ other: Expression) -> BooleanExpression {
580-
return BooleanExpression(functionName: "not_equal", args: [self, other])
616+
return BooleanFunctionExpression(functionName: "not_equal", args: [self, other])
581617
}
582618

583619
func notEqual(_ other: Sendable) -> BooleanExpression {
584-
return BooleanExpression(functionName: "not_equal", args: [self, Helper.sendableToExpr(other)])
620+
return BooleanFunctionExpression(
621+
functionName: "not_equal",
622+
args: [self, Helper.sendableToExpr(other)]
623+
)
585624
}
586625

587626
func equalAny(_ others: [Expression]) -> BooleanExpression {
588-
return BooleanExpression(functionName: "equal_any", args: [self, Helper.array(others)])
627+
return BooleanFunctionExpression(functionName: "equal_any", args: [self, Helper.array(others)])
589628
}
590629

591630
func equalAny(_ others: [Sendable]) -> BooleanExpression {
592-
return BooleanExpression(functionName: "equal_any", args: [self, Helper.array(others)])
631+
return BooleanFunctionExpression(functionName: "equal_any", args: [self, Helper.array(others)])
593632
}
594633

595634
func equalAny(_ arrayExpression: Expression) -> BooleanExpression {
596-
return BooleanExpression(functionName: "equal_any", args: [self, arrayExpression])
635+
return BooleanFunctionExpression(functionName: "equal_any", args: [self, arrayExpression])
597636
}
598637

599638
func notEqualAny(_ others: [Expression]) -> BooleanExpression {
600-
return BooleanExpression(functionName: "not_equal_any", args: [self, Helper.array(others)])
639+
return BooleanFunctionExpression(
640+
functionName: "not_equal_any",
641+
args: [self, Helper.array(others)]
642+
)
601643
}
602644

603645
func notEqualAny(_ others: [Sendable]) -> BooleanExpression {
604-
return BooleanExpression(functionName: "not_equal_any", args: [self, Helper.array(others)])
646+
return BooleanFunctionExpression(
647+
functionName: "not_equal_any",
648+
args: [self, Helper.array(others)]
649+
)
605650
}
606651

607652
func notEqualAny(_ arrayExpression: Expression) -> BooleanExpression {
608-
return BooleanExpression(functionName: "not_equal_any", args: [self, arrayExpression])
653+
return BooleanFunctionExpression(functionName: "not_equal_any", args: [self, arrayExpression])
609654
}
610655

611656
// MARK: Checks
612657

613658
// --- Added Type Check Operations ---
614659

615660
func exists() -> BooleanExpression {
616-
return BooleanExpression(functionName: "exists", args: [self])
661+
return BooleanFunctionExpression(functionName: "exists", args: [self])
617662
}
618663

619664
func isError() -> BooleanExpression {
620-
return BooleanExpression(functionName: "is_error", args: [self])
665+
return BooleanFunctionExpression(functionName: "is_error", args: [self])
621666
}
622667

623668
func isAbsent() -> BooleanExpression {
624-
return BooleanExpression(functionName: "is_absent", args: [self])
669+
return BooleanFunctionExpression(functionName: "is_absent", args: [self])
625670
}
626671

627672
// --- Added String Operations ---
@@ -647,63 +692,69 @@ public extension Expression {
647692
}
648693

649694
func like(_ pattern: String) -> BooleanExpression {
650-
return BooleanExpression(functionName: "like", args: [self, Helper.sendableToExpr(pattern)])
695+
return BooleanFunctionExpression(
696+
functionName: "like",
697+
args: [self, Helper.sendableToExpr(pattern)]
698+
)
651699
}
652700

653701
func like(_ pattern: Expression) -> BooleanExpression {
654-
return BooleanExpression(functionName: "like", args: [self, pattern])
702+
return BooleanFunctionExpression(functionName: "like", args: [self, pattern])
655703
}
656704

657705
func regexContains(_ pattern: String) -> BooleanExpression {
658-
return BooleanExpression(
706+
return BooleanFunctionExpression(
659707
functionName: "regex_contains",
660708
args: [self, Helper.sendableToExpr(pattern)]
661709
)
662710
}
663711

664712
func regexContains(_ pattern: Expression) -> BooleanExpression {
665-
return BooleanExpression(functionName: "regex_contains", args: [self, pattern])
713+
return BooleanFunctionExpression(functionName: "regex_contains", args: [self, pattern])
666714
}
667715

668716
func regexMatch(_ pattern: String) -> BooleanExpression {
669-
return BooleanExpression(
717+
return BooleanFunctionExpression(
670718
functionName: "regex_match",
671719
args: [self, Helper.sendableToExpr(pattern)]
672720
)
673721
}
674722

675723
func regexMatch(_ pattern: Expression) -> BooleanExpression {
676-
return BooleanExpression(functionName: "regex_match", args: [self, pattern])
724+
return BooleanFunctionExpression(functionName: "regex_match", args: [self, pattern])
677725
}
678726

679727
func stringContains(_ substring: String) -> BooleanExpression {
680-
return BooleanExpression(
728+
return BooleanFunctionExpression(
681729
functionName: "string_contains",
682730
args: [self, Helper.sendableToExpr(substring)]
683731
)
684732
}
685733

686734
func stringContains(_ expression: Expression) -> BooleanExpression {
687-
return BooleanExpression(functionName: "string_contains", args: [self, expression])
735+
return BooleanFunctionExpression(functionName: "string_contains", args: [self, expression])
688736
}
689737

690738
func startsWith(_ prefix: String) -> BooleanExpression {
691-
return BooleanExpression(
739+
return BooleanFunctionExpression(
692740
functionName: "starts_with",
693741
args: [self, Helper.sendableToExpr(prefix)]
694742
)
695743
}
696744

697745
func startsWith(_ prefix: Expression) -> BooleanExpression {
698-
return BooleanExpression(functionName: "starts_with", args: [self, prefix])
746+
return BooleanFunctionExpression(functionName: "starts_with", args: [self, prefix])
699747
}
700748

701749
func endsWith(_ suffix: String) -> BooleanExpression {
702-
return BooleanExpression(functionName: "ends_with", args: [self, Helper.sendableToExpr(suffix)])
750+
return BooleanFunctionExpression(
751+
functionName: "ends_with",
752+
args: [self, Helper.sendableToExpr(suffix)]
753+
)
703754
}
704755

705756
func endsWith(_ suffix: Expression) -> BooleanExpression {
706-
return BooleanExpression(functionName: "ends_with", args: [self, suffix])
757+
return BooleanFunctionExpression(functionName: "ends_with", args: [self, suffix])
707758
}
708759

709760
func toLower() -> FunctionExpression {

Firestore/Swift/Source/Helper/PipelineHelper.swift

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ enum Helper {
2525
}
2626

2727
static func sendableToExpr(_ value: Sendable?) -> Expression {
28-
guard let value = value else {
28+
guard let value else {
2929
return Constant.nil
3030
}
31-
32-
if let exprValue = value as? Expression {
31+
switch value {
32+
case let exprValue as Expression:
3333
return exprValue
34-
} else if let dictionaryValue = value as? [String: Sendable?] {
34+
case let dictionaryValue as [String: Sendable?]:
3535
return map(dictionaryValue)
36-
} else if let arrayValue = value as? [Sendable?] {
36+
case let arrayValue as [Sendable?]:
3737
return array(arrayValue)
38-
} else if let timeUnitValue = value as? TimeUnit {
38+
case let timeUnitValue as TimeUnit:
3939
return Constant(timeUnitValue.rawValue)
40-
} else {
40+
default:
4141
return Constant(value)
4242
}
4343
}
@@ -91,23 +91,23 @@ enum Helper {
9191

9292
// This function is used to convert Swift type into Objective-C type.
9393
static func sendableToAnyObjectForRawStage(_ value: Sendable?) -> AnyObject {
94-
guard let value = value, !(value is NSNull) else {
94+
guard let value, !(value is NSNull) else {
9595
return Constant.nil.bridge
9696
}
97-
98-
if let exprValue = value as? Expression {
97+
switch value {
98+
case let exprValue as Expression:
9999
return exprValue.toBridge()
100-
} else if let aggregateFunctionValue = value as? AggregateFunction {
100+
case let aggregateFunctionValue as AggregateFunction:
101101
return aggregateFunctionValue.bridge
102-
} else if let dictionaryValue = value as? [String: Sendable?] {
102+
case let dictionaryValue as [String: Sendable?]:
103103
let mappedValue: [String: Sendable] = dictionaryValue.mapValues {
104104
if let aggFunc = $0 as? AggregateFunction {
105105
return aggFunc.bridge
106106
}
107107
return sendableToExpr($0).toBridge()
108108
}
109109
return mappedValue as NSDictionary
110-
} else {
110+
default:
111111
return Constant(value).bridge
112112
}
113113
}

Firestore/Swift/Source/SwiftAPI/Pipeline/Expressions/Expression.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
import Foundation
2121

2222
public protocol Expression: Sendable {
23+
/// Casts the expression to a `BooleanExpression`.
24+
///
25+
/// - Returns: A `BooleanExpression` representing the same expression.
26+
func asBoolean() -> BooleanExpression
27+
2328
/// Assigns an alias to this expression.
2429
///
2530
/// Aliases are useful for renaming fields in the output of a stage or for giving meaningful

0 commit comments

Comments
 (0)