Skip to content

Commit 171c6f0

Browse files
committed
Add a slim version of OptionConverters for JS only
1 parent 966617f commit 171c6f0

File tree

4 files changed

+133
-3
lines changed

4 files changed

+133
-3
lines changed

build.sbt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ lazy val compat = new MultiScalaCrossProject(
9191
exclude[ReversedMissingMethodProblem]("scala.collection.compat.PackageShared.*"), // it's package-private
9292
exclude[Problem]("scala.collection.compat.*PreservingBuilder*")
9393
)
94-
},
94+
}
9595
)
9696
.jvmSettings(
9797
Test / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "compat/src/test/scala-jvm",
@@ -104,7 +104,7 @@ lazy val compat = new MultiScalaCrossProject(
104104
jvmParent / "scala-2.11_2.12"
105105
}
106106
},
107-
junit,
107+
junit
108108
)
109109
.disablePlugins(ScalafixPlugin),
110110
_.jsSettings(
@@ -120,6 +120,15 @@ lazy val compat = new MultiScalaCrossProject(
120120
}
121121
Seq(s"$opt:$x->$y/")
122122
},
123+
Compile / unmanagedSourceDirectories += {
124+
val jsParent = (ThisBuild / baseDirectory).value / "compat/js/src/main"
125+
CrossVersion.partialVersion(scalaVersion.value) match {
126+
case Some((3, _) | (2, 13)) =>
127+
jsParent / "scala-2.13"
128+
case _ =>
129+
jsParent / "scala-2.11_2.12"
130+
}
131+
},
123132
Test / fork := false // Scala.js cannot run forked tests
124133
).jsEnablePlugins(ScalaJSJUnitPlugin),
125134
_.nativeSettings(
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.jdk
14+
15+
import java.util.Optional
16+
17+
/** This object provides extension methods that convert between Scala `Option` and Java `Optional`
18+
* types.
19+
*
20+
* It differs from the JVM version as in it does not provide any conversions for the Optional primitive type
21+
* wrappers which are available in the JDK but not in Scala-JS or Scala-Native.
22+
*
23+
* Scala `Option` is extended with a `toJava` method that creates a corresponding `Optional`.
24+
*
25+
* Java `Optional` is extended with a `toScala` method.
26+
*
27+
*
28+
* Example usage:
29+
*
30+
* {{{
31+
* import scala.jdk.OptionConverters._
32+
* val a = Option("example").toJava // Creates java.util.Optional[String] containing "example"
33+
* val b = (None: Option[String]).toJava // Creates an empty java.util.Optional[String]
34+
* val c = a.toScala // Back to Option("example")
35+
* val d = b.toScala // Back to None typed as Option[String]
36+
* }}}
37+
*/
38+
object OptionConverters {
39+
40+
/** Provides conversions from Java `Optional` to Scala `Option` and specialized `Optional` types */
41+
implicit class RichOptional[A](private val o: java.util.Optional[A]) extends AnyVal {
42+
43+
/** Convert a Java `Optional` to a Scala `Option` */
44+
def toScala: Option[A] = if (o.isPresent) Some(o.get) else None
45+
46+
/** Convert a Java `Optional` to a Scala `Option` */
47+
@deprecated("Use `toScala` instead", "2.13.0")
48+
def asScala: Option[A] = if (o.isPresent) Some(o.get) else None
49+
}
50+
51+
/** Provides conversions from Scala `Option` to Java `Optional` types */
52+
implicit class RichOption[A](private val o: Option[A]) extends AnyVal {
53+
54+
/** Convert a Scala `Option` to a generic Java `Optional` */
55+
def toJava: Optional[A] = o match {
56+
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
57+
}
58+
59+
/** Convert a Scala `Option` to a generic Java `Optional` */
60+
@deprecated("Use `toJava` instead", "2.13.0")
61+
def asJava: Optional[A] = o match {
62+
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
63+
}
64+
}
65+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package test.scala.jdk
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
6+
import java.util.Optional
7+
import scala.jdk.OptionConverters._
8+
9+
/**
10+
* The tests were copied from the Scala 2.13 Standard Library. `scala.jdk.javaapi` stuff has been omitted and
11+
* everything concerning `OptionalInt`, `OptionalDouble` and `OptionalLong` is only available on the jvm tests.
12+
*
13+
* See https://github.com/scala/scala/blob/2.13.x/test/junit/scala/jdk/OptionConvertersTest.scala.
14+
*/
15+
class OptionConvertersTest {
16+
@Test
17+
def scalaToEverything(): Unit = {
18+
val o = Option("fish")
19+
val n = None: Option[String]
20+
val od = Option(2.7)
21+
val nd = None: Option[Double]
22+
val oi = Option(4)
23+
val ni = None: Option[Int]
24+
val ol = Option(-1L)
25+
val nl = None: Option[Long]
26+
assertEquals(o.toJava, Optional.of(o.get))
27+
assertEquals(n.toJava, Optional.empty[String])
28+
assertEquals(od.toJava.get: Double, Optional.of(od.get).get: Double, 0)
29+
assertEquals(nd.toJava, Optional.empty[Double])
30+
assertEquals(oi.toJava.get: Int, Optional.of(oi.get).get: Int)
31+
assertEquals(ni.toJava, Optional.empty[Int])
32+
assertEquals(ol.toJava.get: Long, Optional.of(ol.get).get: Long)
33+
assertEquals(nl.toJava, Optional.empty[Long])
34+
}
35+
36+
@Test
37+
def javaGenericToEverything(): Unit = {
38+
val o = Optional.of("fish")
39+
val n = Optional.empty[String]
40+
val od = Optional.of(2.7)
41+
val nd = Optional.empty[Double]
42+
val oi = Optional.of(4)
43+
val ni = Optional.empty[Int]
44+
val ol = Optional.of(-1L)
45+
val nl = Optional.empty[Long]
46+
assertEquals(o.toScala, Option(o.get))
47+
assertEquals(n.toScala, Option.empty[String])
48+
assertEquals(od.toScala, Option(od.get))
49+
assertEquals(nd.toScala, Option.empty[Double])
50+
assertEquals(oi.toScala, Option(oi.get))
51+
assertEquals(ni.toScala, Option.empty[Int])
52+
assertEquals(ol.toScala, Option(ol.get))
53+
assertEquals(nl.toScala, Option.empty[Long])
54+
}
55+
}

compat/src/test/scala-jvm/test/scala/jdk/OptionConvertersTest.scala renamed to compat/src/test/scala-jvm/test/scala/jdk/OptionConvertersJVMTest.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import scala.jdk.OptionConverters._
1111
*
1212
* See https://github.com/scala/scala/blob/2.13.x/test/junit/scala/jdk/OptionConvertersTest.scala.
1313
*/
14-
class OptionConvertersTest {
14+
class OptionConvertersJVMTest {
1515
@Test
1616
def scalaToEverything(): Unit = {
1717
val o = Option("fish")
1818
val n = (None: Option[String])
1919
val od = Option(2.7)
2020
val nd = (None: Option[Double])
21+
2122
val oi = Option(4)
2223
val ni = (None: Option[Int])
2324
val ol = Option(-1L)

0 commit comments

Comments
 (0)