Skip to content

Commit b8d844d

Browse files
committed
Scala: Use pass by name in implicits functions
Allows the functions to be overridden by users JAVA-3578
1 parent 75de008 commit b8d844d

File tree

2 files changed

+73
-12
lines changed

2 files changed

+73
-12
lines changed

driver-scala/src/main/scala/org/mongodb/scala/ObservableImplicits.scala

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import scala.concurrent.Future
3232
*/
3333
trait ObservableImplicits {
3434

35-
implicit class BoxedPublisher[T](publisher: Publisher[T]) extends Observable[T] {
35+
implicit class BoxedPublisher[T](pub: => Publisher[T]) extends Observable[T] {
36+
val publisher = pub
3637
private def sub(observer: Observer[_ >: T]): Unit = publisher.subscribe(observer)
3738

3839
/**
@@ -44,7 +45,8 @@ trait ObservableImplicits {
4445
override def subscribe(s: Subscriber[_ >: T]): Unit = sub(BoxedSubscriber(s))
4546
}
4647

47-
implicit class BoxedSubscriber[T](subscriber: Subscriber[_ >: T]) extends Observer[T] {
48+
implicit class BoxedSubscriber[T](sub: => Subscriber[_ >: T]) extends Observer[T] {
49+
val subscriber = sub
4850

4951
override def onSubscribe(subscription: Subscription): Unit = subscriber.onSubscribe(subscription)
5052

@@ -55,7 +57,7 @@ trait ObservableImplicits {
5557
override def onNext(result: T): Unit = subscriber.onNext(result)
5658
}
5759

58-
implicit class BoxedSubscription(subscription: JSubscription) extends Subscription {
60+
implicit class BoxedSubscription(subscription: => JSubscription) extends Subscription {
5961
val cancelled = new AtomicBoolean(false)
6062
override def request(n: Long): Unit = subscription.request(n)
6163

@@ -68,11 +70,13 @@ trait ObservableImplicits {
6870

6971
}
7072

71-
implicit class ToObservableString(publisher: Publisher[java.lang.String]) extends Observable[String] {
73+
implicit class ToObservableString(pub: => Publisher[java.lang.String]) extends Observable[String] {
74+
val publisher = pub
7275
override def subscribe(observer: Observer[_ >: String]): Unit = publisher.toObservable().subscribe(observer)
7376
}
7477

75-
implicit class ToSingleObservablePublisher[T](publisher: Publisher[T]) extends SingleObservable[T] {
78+
implicit class ToSingleObservablePublisher[T](pub: => Publisher[T]) extends SingleObservable[T] {
79+
val publisher = pub
7680

7781
/**
7882
* Converts the [[Observable]] to a single result [[Observable]].
@@ -125,27 +129,32 @@ trait ObservableImplicits {
125129
}
126130
}
127131

128-
implicit class ToSingleObservableInt(publisher: Publisher[java.lang.Integer]) extends SingleObservable[Int] {
132+
implicit class ToSingleObservableInt(pub: => Publisher[java.lang.Integer]) extends SingleObservable[Int] {
133+
val publisher = pub
129134
override def subscribe(observer: Observer[_ >: Int]): Unit =
130135
publisher.toObservable().map(_.intValue()).toSingle().subscribe(observer)
131136
}
132137

133-
implicit class ToSingleObservableLong(publisher: Publisher[java.lang.Long]) extends SingleObservable[Long] {
138+
implicit class ToSingleObservableLong(pub: => Publisher[java.lang.Long]) extends SingleObservable[Long] {
139+
val publisher = pub
134140
override def subscribe(observer: Observer[_ >: Long]): Unit =
135141
publisher.toObservable().map(_.longValue()).toSingle().subscribe(observer)
136142
}
137143

138-
implicit class ToSingleObservableObjectId(publisher: Publisher[org.bson.types.ObjectId])
144+
implicit class ToSingleObservableObjectId(pub: => Publisher[org.bson.types.ObjectId])
139145
extends SingleObservable[ObjectId] {
146+
val publisher = pub
140147
override def subscribe(observer: Observer[_ >: ObjectId]): Unit = publisher.toSingle().subscribe(observer)
141148
}
142149

143-
implicit class ToSingleObservableGridFS(publisher: Publisher[com.mongodb.client.gridfs.model.GridFSFile])
150+
implicit class ToSingleObservableGridFS(pub: => Publisher[com.mongodb.client.gridfs.model.GridFSFile])
144151
extends SingleObservable[GridFSFile] {
152+
val publisher = pub
145153
override def subscribe(observer: Observer[_ >: GridFSFile]): Unit = publisher.toSingle().subscribe(observer)
146154
}
147155

148-
implicit class ToSingleObservableVoid(publisher: Publisher[Void]) extends SingleObservable[Void] {
156+
implicit class ToSingleObservableVoid(pub: => Publisher[Void]) extends SingleObservable[Void] {
157+
val publisher = pub
149158
override def subscribe(observer: Observer[_ >: Void]): Unit =
150159
publisher
151160
.toSingle()
@@ -161,7 +170,8 @@ trait ObservableImplicits {
161170
})
162171
}
163172

164-
implicit class ObservableFuture[T](observable: Observable[T]) {
173+
implicit class ObservableFuture[T](obs: => Observable[T]) {
174+
val observable = obs
165175

166176
/**
167177
* Collects the [[Observable]] results and converts to a [[scala.concurrent.Future]].
@@ -176,7 +186,8 @@ trait ObservableImplicits {
176186

177187
}
178188

179-
implicit class SingleObservableFuture[T](observable: SingleObservable[T]) {
189+
implicit class SingleObservableFuture[T](obs: => SingleObservable[T]) {
190+
val observable = obs
180191

181192
/**
182193
* Collects the [[Observable]] results and converts to a [[scala.concurrent.Future]].
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 org.mongodb.scala.internal
18+
19+
import scala.concurrent.duration.DurationInt
20+
import org.mongodb.scala.{ BaseSpec, Observable }
21+
22+
import scala.concurrent.ExecutionContext.Implicits.global
23+
import scala.concurrent.{ Await, Future }
24+
25+
object ObservableImplicitOverride {
26+
implicit class ObservableFuture[T](obs: => Observable[T]) {
27+
def toFuture(): Future[String] = Future("Overridden observable")
28+
}
29+
30+
}
31+
32+
class OverridableObservableImplicitsSpec extends BaseSpec {
33+
34+
"Observable implicits" should "be overrideable" in {
35+
import ObservableImplicitOverride._
36+
37+
val observable: Observable[Int] = Observable(1 to 10)
38+
39+
Await.result(observable.toFuture(), 1.second) should equal("Overridden observable")
40+
}
41+
42+
it should "also allow the default implementation to work" in {
43+
import org.mongodb.scala._
44+
val observable: Observable[Int] = Observable(1 to 10)
45+
46+
Await.result(observable.toFuture(), 1.second) should equal((1 to 10).toList)
47+
48+
}
49+
50+
}

0 commit comments

Comments
 (0)