Skip to content

Commit

Permalink
Merge 2b12513 into 45a5f8f
Browse files Browse the repository at this point in the history
  • Loading branch information
cb372 committed Dec 11, 2019
2 parents 45a5f8f + 2b12513 commit 3797015
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 5 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ import enumeratum.values._

sealed abstract class LibraryItem(val value: Int, val name: String) extends IntEnumEntry

case object LibraryItem extends IntEnum[LibraryItem] {
object LibraryItem extends IntEnum[LibraryItem] {


case object Book extends LibraryItem(value = 1, name = "book")
Expand All @@ -268,6 +268,32 @@ assert(LibraryItem.withValue(1) == LibraryItem.Book)
LibraryItem.withValue(10) // => java.util.NoSuchElementException:
```

If you want to allow aliases in your enumeration, i.e. multiple entries that share the same value, you can extend the
`enumeratum.values.AllowAlias` trait:

```scala
import enumeratum.values._

sealed abstract class Judgement(val value: Int) extends IntEnumEntry with AllowAlias

object Judgement extends IntEnum[Judgement] {

case object Good extends Judgement(1)
case object OK extends Judgement(2)
case object Meh extends Judgement(2)
case object Bad extends Judgement(3)

val values = findValues

}
```

Calling `withValue` with an aliased value will return one of the corresponding entries. Which one it returns is undefined:

```scala
assert(Judgement.withValue(2) == Judgement.OK || Judgement.withValue(2) == Judgement.Meh)
```

**Restrictions**
- `ValueEnum`s must have their value members implemented as literal values.

Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ lazy val core = crossProject(JSPlatform, JVMPlatform)
name := "enumeratum",
version := Versions.Core.head,
crossScalaVersions := scalaVersionsAll,
libraryDependencies += "com.beachape" %% "enumeratum-macros" % Versions.Macros.stable
//libraryDependencies += "com.beachape" %% "enumeratum-macros" % Versions.Macros.stable
)
// .dependsOn(macros) // used for testing macros
.dependsOn(macros) // used for testing macros
lazy val coreJS = core.js
lazy val coreJVM = core.jvm

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,23 @@ class ValueEnumSpec extends FunSpec with Matchers with ValueEnumHelpers {
""" shouldNot compile
}

it("compile even when values are repeated if AllowAlias is extended") {
"""
sealed abstract class ContentTypeRepeated(val value: Long, name: String) extends LongEnumEntry with AllowAlias
case object ContentTypeRepeated extends LongEnum[ContentTypeRepeated] {
case object Text extends ContentTypeRepeated(value = 1L, name = "text")
case object Image extends ContentTypeRepeated(value = 2L, name = "image")
case object Video extends ContentTypeRepeated(value = 2L, name = "video")
case object Audio extends ContentTypeRepeated(value = 4L, name = "audio")
val values = findValues
}
""" should (compile)
}

it("should fail to compile when there are non literal values") {
"""
sealed abstract class ContentTypeRepeated(val value: Long, name: String) extends LongEnumEntry
Expand Down
11 changes: 9 additions & 2 deletions macros/src/main/scala/enumeratum/ValueEnumMacros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ContextUtils.Context

import scala.reflect.ClassTag
import scala.collection.immutable._
import enumeratum.values.AllowAlias

@SuppressWarnings(Array("org.wartremover.warts.StringPlusAny"))
object ValueEnumMacros {
Expand Down Expand Up @@ -105,8 +106,14 @@ object ValueEnumMacros {
subclassTrees,
processFoundValues
)
// Make sure the processed found value implementations are unique
ensureUnique[ProcessedValue](c)(treeWithVals)

if (weakTypeOf[ValueEntryType] <:< c.typeOf[AllowAlias]) {
// Skip the uniqueness check
} else {
// Make sure the processed found value implementations are unique
ensureUnique[ProcessedValue](c)(treeWithVals)
}

// Finish by building our Sequence
val subclassSymbols = treeWithVals.map(_.tree.symbol)
EnumMacros.buildSeqExpr[ValueEntryType](c)(subclassSymbols)
Expand Down
12 changes: 12 additions & 0 deletions macros/src/main/scala/enumeratum/values/AllowAlias.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package enumeratum.values

/**
* Marker trait. You can extend this to tell enumeratum that you
* want to allow 'aliases', i.e. define multiple entries with the
* same value.
*
* Note: if you define multiple entries with the same value, calling
* `withValue` for that value will return one of them. Which one it
* returns is undefined.
*/
trait AllowAlias

0 comments on commit 3797015

Please sign in to comment.