Skip to content

Commit d96bfd5

Browse files
authored
Implement switch expression (#1055)
JAVA-4813
1 parent 59fdaeb commit d96bfd5

18 files changed

+776
-13
lines changed

driver-core/src/main/com/mongodb/client/model/expressions/ArrayExpression.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,8 @@ default ArrayExpression<T> slice(final int start, final int length) {
112112
ArrayExpression<T> union(ArrayExpression<? extends T> set);
113113

114114
ArrayExpression<T> distinct();
115+
116+
<R extends Expression> R passArrayTo(Function<? super ArrayExpression<T>, ? extends R> f);
117+
118+
<R extends Expression> R switchArrayOn(Function<Branches<ArrayExpression<T>>, ? extends BranchesTerminal<ArrayExpression<T>, ? extends R>> on);
115119
}

driver-core/src/main/com/mongodb/client/model/expressions/BooleanExpression.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.mongodb.client.model.expressions;
1818

19+
import java.util.function.Function;
20+
1921
/**
2022
* Expresses a boolean value.
2123
*/
@@ -58,4 +60,8 @@ public interface BooleanExpression extends Expression {
5860
* @param <T> The type of the resulting expression.
5961
*/
6062
<T extends Expression> T cond(T left, T right);
63+
64+
<R extends Expression> R passBooleanTo(Function<? super BooleanExpression, ? extends R> f);
65+
66+
<R extends Expression> R switchBooleanOn(Function<Branches<BooleanExpression>, ? extends BranchesTerminal<BooleanExpression, ? extends R>> on);
6167
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.client.model.expressions;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.function.Function;
22+
23+
public final class Branches<T extends Expression> {
24+
25+
Branches() {
26+
}
27+
28+
private static <T extends Expression, R extends Expression> BranchesIntermediary<T, R> with(final Function<T, SwitchCase<R>> switchCase) {
29+
List<Function<T, SwitchCase<R>>> v = new ArrayList<>();
30+
v.add(switchCase);
31+
return new BranchesIntermediary<>(v);
32+
}
33+
34+
private static <T extends Expression> MqlExpression<?> mqlEx(final T value) {
35+
return (MqlExpression<?>) value;
36+
}
37+
38+
// is fn
39+
40+
public <T extends Expression, R extends Expression> BranchesIntermediary<T, R> is(final Function<? super T, BooleanExpression> o, final Function<? super T, ? extends R> r) {
41+
return with(value -> new SwitchCase<>(o.apply(value), r.apply(value)));
42+
}
43+
44+
// eq lt lte
45+
46+
public <R extends Expression> BranchesIntermediary<T, R> eq(final T v, final Function<? super T, ? extends R> r) {
47+
return is(value -> value.eq(v), r);
48+
}
49+
50+
public <R extends Expression> BranchesIntermediary<T, R> lt(final T v, final Function<? super T, ? extends R> r) {
51+
return is(value -> value.lt(v), r);
52+
}
53+
54+
public <R extends Expression> BranchesIntermediary<T, R> lte(final T v, final Function<? super T, ? extends R> r) {
55+
return is(value -> value.lte(v), r);
56+
}
57+
58+
// is type
59+
60+
public <R extends Expression> BranchesIntermediary<T, R> isBoolean(final Function<? super BooleanExpression, ? extends R> r) {
61+
return is(v -> mqlEx(v).isBoolean(), v -> r.apply((BooleanExpression) v));
62+
}
63+
64+
public <R extends Expression> BranchesIntermediary<T, R> isNumber(final Function<? super NumberExpression, ? extends R> r) {
65+
return is(v -> mqlEx(v).isNumber(), v -> r.apply((NumberExpression) v));
66+
}
67+
68+
public <R extends Expression> BranchesIntermediary<T, R> isInteger(final Function<? super IntegerExpression, ? extends R> r) {
69+
return is(v -> mqlEx(v).isInteger(), v -> r.apply((IntegerExpression) v));
70+
}
71+
72+
public <R extends Expression> BranchesIntermediary<T, R> isString(final Function<? super StringExpression, ? extends R> r) {
73+
return is(v -> mqlEx(v).isString(), v -> r.apply((StringExpression) v));
74+
}
75+
76+
public <R extends Expression> BranchesIntermediary<T, R> isDate(final Function<? super DateExpression, ? extends R> r) {
77+
return is(v -> mqlEx(v).isDate(), v -> r.apply((DateExpression) v));
78+
}
79+
80+
@SuppressWarnings("unchecked")
81+
public <R extends Expression, Q extends Expression> BranchesIntermediary<T, R> isArray(final Function<? super ArrayExpression<Q>, ? extends R> r) {
82+
return is(v -> mqlEx(v).isArray(), v -> r.apply((ArrayExpression<Q>) v));
83+
}
84+
85+
public <R extends Expression> BranchesIntermediary<T, R> isDocument(final Function<? super DocumentExpression, ? extends R> r) {
86+
return is(v -> mqlEx(v).isDocumentOrMap(), v -> r.apply((DocumentExpression) v));
87+
}
88+
89+
@SuppressWarnings("unchecked")
90+
public <R extends Expression, Q extends Expression> BranchesIntermediary<T, R> isMap(final Function<? super MapExpression<Q>, ? extends R> r) {
91+
return is(v -> mqlEx(v).isDocumentOrMap(), v -> r.apply((MapExpression<Q>) v));
92+
}
93+
94+
public <R extends Expression> BranchesIntermediary<T, R> isNull(final Function<? super Expression, ? extends R> r) {
95+
return is(v -> mqlEx(v).isNull(), v -> r.apply(v));
96+
}
97+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.client.model.expressions;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.function.Function;
22+
23+
public final class BranchesIntermediary<T extends Expression, R extends Expression> extends BranchesTerminal<T, R> {
24+
BranchesIntermediary(final List<Function<T, SwitchCase<R>>> branches) {
25+
super(branches, null);
26+
}
27+
28+
private BranchesIntermediary<T, R> with(final Function<T, SwitchCase<R>> switchCase) {
29+
List<Function<T, SwitchCase<R>>> v = new ArrayList<>(this.getBranches());
30+
v.add(switchCase);
31+
return new BranchesIntermediary<>(v);
32+
}
33+
34+
private static <T extends Expression> MqlExpression<?> mqlEx(final T value) {
35+
return (MqlExpression<?>) value;
36+
}
37+
38+
// is fn
39+
40+
public BranchesIntermediary<T, R> is(final Function<? super T, BooleanExpression> o, final Function<? super T, ? extends R> r) {
41+
return this.with(value -> new SwitchCase<>(o.apply(value), r.apply(value)));
42+
}
43+
44+
// eq lt lte
45+
46+
public BranchesIntermediary<T, R> eq(final T v, final Function<? super T, ? extends R> r) {
47+
return is(value -> value.eq(v), r);
48+
}
49+
50+
public BranchesIntermediary<T, R> lt(final T v, final Function<? super T, ? extends R> r) {
51+
return is(value -> value.lt(v), r);
52+
}
53+
54+
public BranchesIntermediary<T, R> lte(final T v, final Function<? super T, ? extends R> r) {
55+
return is(value -> value.lte(v), r);
56+
}
57+
58+
// is type
59+
60+
public BranchesIntermediary<T, R> isBoolean(final Function<? super BooleanExpression, ? extends R> r) {
61+
return is(v -> mqlEx(v).isBoolean(), v -> r.apply((BooleanExpression) v));
62+
}
63+
64+
public BranchesIntermediary<T, R> isNumber(final Function<? super NumberExpression, ? extends R> r) {
65+
return is(v -> mqlEx(v).isNumber(), v -> r.apply((NumberExpression) v));
66+
}
67+
68+
public BranchesIntermediary<T, R> isInteger(final Function<? super IntegerExpression, ? extends R> r) {
69+
return is(v -> mqlEx(v).isInteger(), v -> r.apply((IntegerExpression) v));
70+
}
71+
72+
public BranchesIntermediary<T, R> isString(final Function<? super StringExpression, ? extends R> r) {
73+
return is(v -> mqlEx(v).isString(), v -> r.apply((StringExpression) v));
74+
}
75+
76+
public BranchesIntermediary<T, R> isDate(final Function<? super DateExpression, ? extends R> r) {
77+
return is(v -> mqlEx(v).isDate(), v -> r.apply((DateExpression) v));
78+
}
79+
80+
@SuppressWarnings("unchecked")
81+
public <Q extends Expression> BranchesIntermediary<T, R> isArray(final Function<? super ArrayExpression<Q>, ? extends R> r) {
82+
return is(v -> mqlEx(v).isArray(), v -> r.apply((ArrayExpression<Q>) v));
83+
}
84+
85+
public BranchesIntermediary<T, R> isDocument(final Function<? super DocumentExpression, ? extends R> r) {
86+
return is(v -> mqlEx(v).isDocumentOrMap(), v -> r.apply((DocumentExpression) v));
87+
}
88+
89+
@SuppressWarnings("unchecked")
90+
public <Q extends Expression> BranchesIntermediary<T, R> isMap(final Function<? super MapExpression<Q>, ? extends R> r) {
91+
return is(v -> mqlEx(v).isDocumentOrMap(), v -> r.apply((MapExpression<Q>) v));
92+
}
93+
94+
public BranchesIntermediary<T, R> isNull(final Function<? super Expression, ? extends R> r) {
95+
return is(v -> mqlEx(v).isNull(), v -> r.apply(v));
96+
}
97+
98+
public BranchesTerminal<T, R> defaults(final Function<? super T, ? extends R> r) {
99+
return this.withDefault(value -> r.apply(value));
100+
}
101+
102+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb.client.model.expressions;
18+
19+
import com.mongodb.lang.Nullable;
20+
21+
import java.util.List;
22+
import java.util.function.Function;
23+
24+
public class BranchesTerminal<T extends Expression, R extends Expression> {
25+
26+
private final List<Function<T, SwitchCase<R>>> branches;
27+
28+
private final Function<T, R> defaults;
29+
30+
BranchesTerminal(final List<Function<T, SwitchCase<R>>> branches, @Nullable final Function<T, R> defaults) {
31+
this.branches = branches;
32+
this.defaults = defaults;
33+
}
34+
35+
protected BranchesTerminal<T, R> withDefault(final Function<T, R> defaults) {
36+
return new BranchesTerminal<>(branches, defaults);
37+
}
38+
39+
protected List<Function<T, SwitchCase<R>>> getBranches() {
40+
return branches;
41+
}
42+
43+
@Nullable
44+
protected Function<T, R> getDefaults() {
45+
return defaults;
46+
}
47+
}

driver-core/src/main/com/mongodb/client/model/expressions/DateExpression.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.mongodb.client.model.expressions;
1818

19+
import java.util.function.Function;
20+
1921
/**
2022
* Expresses a date value.
2123
*/
@@ -33,4 +35,6 @@ public interface DateExpression extends Expression {
3335

3436
StringExpression asString(StringExpression timezone, StringExpression format);
3537

38+
<R extends Expression> R passDateTo(Function<? super DateExpression, ? extends R> f);
39+
<R extends Expression> R switchDateOn(Function<Branches<DateExpression>, ? extends BranchesTerminal<DateExpression, ? extends R>> on);
3640
}

driver-core/src/main/com/mongodb/client/model/expressions/DocumentExpression.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.bson.conversions.Bson;
2020

2121
import java.time.Instant;
22+
import java.util.function.Function;
2223

2324
import static com.mongodb.client.model.expressions.Expressions.of;
2425
import static com.mongodb.client.model.expressions.Expressions.ofMap;
@@ -100,4 +101,7 @@ default <T extends Expression> MapExpression<T> getMap(final String fieldName, f
100101
DocumentExpression merge(DocumentExpression other);
101102

102103
MapExpression<Expression> asMap();
104+
105+
<R extends Expression> R passDocumentTo(Function<? super DocumentExpression, ? extends R> f);
106+
<R extends Expression> R switchDocumentOn(Function<Branches<DocumentExpression>, ? extends BranchesTerminal<DocumentExpression, ? extends R>> on);
103107
}

driver-core/src/main/com/mongodb/client/model/expressions/Expression.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.mongodb.annotations.Evolving;
2020

21+
import java.util.function.Function;
22+
2123
/**
2224
* Expressions express values that may be represented in (or computations that
2325
* may be performed within) a MongoDB server. Each expression evaluates to some
@@ -114,4 +116,9 @@ public interface Expression {
114116
<T extends Expression> MapExpression<T> isMapOr(MapExpression<? extends T> other);
115117

116118
StringExpression asString();
119+
120+
<R extends Expression> R passTo(Function<? super Expression, ? extends R> f);
121+
122+
<R extends Expression> R switchOn(Function<Branches<Expression>, ? extends BranchesTerminal<Expression, ? extends R>> on);
123+
117124
}

driver-core/src/main/com/mongodb/client/model/expressions/IntegerExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.mongodb.client.model.expressions;
1818

19+
import java.util.function.Function;
20+
1921
/**
2022
* Expresses an integer value.
2123
*/
@@ -42,4 +44,7 @@ default IntegerExpression subtract(final int subtract) {
4244
IntegerExpression min(IntegerExpression i);
4345

4446
IntegerExpression abs();
47+
48+
<R extends Expression> R passIntegerTo(Function<? super IntegerExpression, ? extends R> f);
49+
<R extends Expression> R switchIntegerOn(Function<Branches<IntegerExpression>, ? extends BranchesTerminal<IntegerExpression, ? extends R>> on);
4550
}

driver-core/src/main/com/mongodb/client/model/expressions/MapExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.mongodb.client.model.expressions;
1818

19+
import java.util.function.Function;
20+
1921
import static com.mongodb.client.model.expressions.Expressions.of;
2022

2123
public interface MapExpression<T extends Expression> extends Expression {
@@ -57,4 +59,7 @@ default MapExpression<T> unset(final String key) {
5759
ArrayExpression<EntryExpression<T>> entrySet();
5860

5961
<R extends DocumentExpression> R asDocument();
62+
63+
<R extends Expression> R passMapTo(Function<? super MapExpression<T>, ? extends R> f);
64+
<R extends Expression> R switchMapOn(Function<Branches<MapExpression<T>>, ? extends BranchesTerminal<MapExpression<T>, ? extends R>> on);
6065
}

0 commit comments

Comments
 (0)