Scala : Enumeration with special characters

Viewed 80

How to create and use an enumeration that have some special characters and spaces within its values ?

object Bots extends Enumeration {
  type Bots = Value
  val `apis-google`, `mediapartners-google`, `adsbot-google-mobile-apps`, `google favicon` = Value
}

When this enumeration is called, the special characters seems to be replaced by some internal identifiers or changed their encoding:

for (bot <- Bots.values) println(bot)

output:

apis$minusgoogle 
mediapartners$minusgoogle 
adsbot$minusgoogle$minusmobile$minusapps 
google$u0020favicon

EDIT : Im using scala 2.2

3 Answers
$ scala
Starting scala3 REPL...
scala> object Bots extends Enumeration {                                                                                                                                                                           
     |   type Bots = Value
     |   val `apis-google`: Bots = Value(0, "apis-google")
     |   val `mediapartners-google`: Bots = Value(1, "mediapartners-google") 
     |   val `adsbot-google-mobile-apps`: Bots = Value(2, "adsbot-google-mobile-apps")
     |   val `google favicon`: Bots = Value(3, "google favicon")
     | }
     | 
// defined object Bots

scala> for (bot <- Bots.values) println(bot)                                                                                                                                                                       
     | 
apis-google
mediapartners-google
adsbot-google-mobile-apps
google favicon

You could change enumeration's naming behaviour by overriding Enumeration#Val#toString

scala> object Bots extends Enumeration {
     |   val `apis-google`
     |     , `mediapartners-google`
     |     , `adsbot-google-mobile-apps`
     |     , `google favicon` = new Val {
     |         override def toString() = 
     |           super.toString()
     |             .replace("$minus", "-")
     |             .replace("$u0020", " ")
     |       }
     | }
object Bots

scala> Bots.values.foreach(println)
apis-google
mediapartners-google
adsbot-google-mobile-apps
google favicon

or try enumeratum library

scala> import enumeratum._
     | 
     | sealed trait Bots extends EnumEntry
     | 
     | object Bots extends Enum[Bots] {
     |   val values = findValues
     | 
     |   case object `apis-google` extends Bots
     |   case object `mediapartners-google` extends Bots
     |   case object `adsbot-google-mobile-apps` extends Bots
     |   case object `google favicon` extends Bots
     | 
     | }
import enumeratum._
trait Bots
object Bots

scala> Bots.values.foreach(println)
apis-google
mediapartners-google
adsbot-google-mobile-apps
google favicon

or Scala 3

scala> enum Bots:                                                                                                                                             
     |   case `apis-google`, `mediapartners-google`, `adsbot-google-mobile-apps`, `google favicon`
     | 
// defined class Bots

scala> Bots.values.foreach(println)
apis-google
mediapartners-google
adsbot-google-mobile-apps
google favicon

actually you can use NameTransformer object to encode your string. Problem is that enum is comparing string with name of enum which is scala symbol (so this name is encoded to build the name which is correct java name) in withName method. Code looks like this:

  test("enum") {
    println(definitions.Countries.`United Kingdom`.toString())
    // prints United$u0020Kingdom
    val UK = definitions.Countries.withName(NameTransformer.encode("United Kingdom"))
    UK shouldBe definitions.Countries.`United Kingdom`
  }
Related