2

Considering the following code :

sealed trait Foo {
  def name: String
}

case object FooA extends Foo {
  override val name: String = "a"
}

case object FooB extends Foo {
  override val name: String = "b"
}

object Foo {
  def fromString(name: String): Foo = {
    name match {
     case FooA.name => FooA
     case FooB.name => FooB  
  }
}

Can I refactor the fromString() method to avoid having a case per case object instance ? Some more generic code able to enumerate through all Foo instances ?

In my real version, I start to have a lot of case object, and the wall of case bla.name => bla is boring me ^^

Thanks :)

C4stor
  • 8,355
  • 6
  • 29
  • 47

2 Answers2

2

Beachape provide an enum library which can do this for you out of the box:

include this in your build.sbt

"com.beachape" %% "enumeratum" % "1.5.15"

The Enum class provided just needs to be extended like so:

import enumeratum._

sealed trait Foo

object Foo extends Enum[Foo] {
  case object FooA extends Foo 
  case object FooB extends Foo 
}

There is a function called withName that will allow you to get the right sealed trait via its string name:

Foo.withName("FooA")
C4stor
  • 8,355
  • 6
  • 29
  • 47
randal25
  • 1,290
  • 13
  • 10
1

How about something like this?

sealed trait Foo {
  def name: String
}

object Foo {
  case object FooA extends Foo {
    override val name: String = "a"
  }

  case object FooB extends Foo {
    override val name: String = "b"
  }

  val values = Seq(FooA, FooB)

  def withName(name: String): Option[Foo] = {
    values.find(value => value.name.equals(name))
  }
}

You can then use the withName(String) method to get the corresponding concrete object of type Foo as an Option:

val testFooAName = "a"
val testFooA = Foo.withName(testFooAName) // Will yield Some(FooA)

testFooA match {
    case Some(Foo.FooA) => println("Matched Foo.FooA!")
    case Some(Foo.FooB) => println("Matched Foo.FooB!")
}

val testFooNoneName = "none"
val testFooNone = Foo.withName(testFooNoneName) // Will yield None

Output:
Matched Foo.FooA!
lostsoul29
  • 746
  • 2
  • 11
  • 19