Skip to content

Commit

Permalink
Many to one (#175)
Browse files Browse the repository at this point in the history
* Make namesToValuesMap non-final for overriding in subclasses.
* Use namesToValuesMap instead of values
  • Loading branch information
neilchaudhuri authored and lloydmeta committed Mar 14, 2018
1 parent 6595742 commit d328c23
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 13 deletions.
9 changes: 4 additions & 5 deletions enumeratum-core/src/main/scala/enumeratum/Enum.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package enumeratum

import scala.language.experimental.macros

import scala.collection.immutable._
import scala.language.experimental.macros

/**
* All the cool kids have their own Enumeration implementation, most of which try to
Expand Down Expand Up @@ -38,20 +37,20 @@ trait Enum[A <: EnumEntry] {
/**
* Map of [[A]] object names to [[A]]s
*/
lazy final val namesToValuesMap: Map[String, A] =
lazy val namesToValuesMap: Map[String, A] =
values.map(v => v.entryName -> v).toMap

/**
* Map of [[A]] object names in lower case to [[A]]s for case-insensitive comparison
*/
lazy final val lowerCaseNamesToValuesMap: Map[String, A] =
values.map(v => v.entryName.toLowerCase -> v).toMap
namesToValuesMap.map{ case (k, v) => k.toLowerCase -> v }

/**
* Map of [[A]] object names in upper case to [[A]]s for case-insensitive comparison
*/
lazy final val upperCaseNameValuesToMap: Map[String, A] =
values.map(v => v.entryName.toUpperCase -> v).toMap
namesToValuesMap.map{ case (k, v) => k.toUpperCase() -> v }

/**
* Map of [[A]] to their index in the values sequence.
Expand Down
24 changes: 16 additions & 8 deletions enumeratum-core/src/main/scala/enumeratum/EnumEntry.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,63 +62,71 @@ object EnumEntry {
* Stackable trait to convert the entryName to Capital_Snake_Case .
*/
trait CapitalSnakecase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = camel2WordArray(super.entryName).mkString("_")
}

/**
* Stackable trait to convert the entryName to Capital-Hyphen-Case.
*/
trait CapitalHyphencase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = camel2WordArray(super.entryName).mkString("-")
}

/**
* Stackable trait to convert the entryName to Capital.Dot.Case.
*/
trait CapitalDotcase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = camel2WordArray(super.entryName).mkString(".")
}

/**
* Stackable trait to convert the entryName to Capital Words.
*/
trait CapitalWords extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = camel2WordArray(super.entryName).mkString(" ")
}

/**
* Stackable trait to convert the entryName to CamelCase.
*/
trait Camelcase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = super.entryName.split("_+").map(s => capitalise(s.toLowerCase)).mkString
}

/**
* Stackable trait to convert the entryName to UPPERCASE.
*/
trait Uppercase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = super.entryName.toUpperCase
}

/**
* Stackable trait to convert the entryName to lowercase.
*/
trait Lowercase extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = super.entryName.toLowerCase
}

/**
* Stackable trait to uncapitalise the first letter of the entryName.
*/
trait Uncapitalised extends EnumEntry {
override def entryName: String = stableEntryName
override def entryName: String = stableEntryName

private[this] lazy val stableEntryName: String = uncapitalise(super.entryName)
}

Expand Down
6 changes: 6 additions & 0 deletions enumeratum-core/src/test/scala/enumeratum/EnumSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ class EnumSpec extends FunSpec with Matchers {
UncapitalisedEnum.withName("goodBye") shouldBe UncapitalisedEnum.GoodBye
UncapitalisedEnum.withName("SIKE") shouldBe UncapitalisedEnum.Sike
UncapitalisedEnum.withName("a") shouldBe UncapitalisedEnum.a

MultiEnum.withName("one") shouldBe MultiEnum.One
MultiEnum.withName("1") shouldBe MultiEnum.One
a [NoSuchElementException] should be thrownBy MultiEnum.withName("One")
MultiEnum.withName("eins") shouldBe MultiEnum.One
MultiEnum.withName("two") shouldBe MultiEnum.Two
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions enumeratum-core/src/test/scala/enumeratum/Models.scala
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,22 @@ object UncapitalisedEnum extends Enum[UncapitalisedEnum] {

}

sealed class MultiEnum(override val entryName: String,
val alternateNames: String*) extends EnumEntry


case object MultiEnum extends Enum[MultiEnum] {
val values = findValues

override lazy val namesToValuesMap: Map[String, MultiEnum] =
values.flatMap { n =>
(n.entryName -> n) +: n.alternateNames.map(_ -> n)
}.toMap

case object One extends MultiEnum("one", "1", "eins")
case object Two extends MultiEnum("two", "2", "zwei")
}

object Wrapper {

sealed trait SmartEnum extends EnumEntry
Expand Down

0 comments on commit d328c23

Please sign in to comment.