Home > other >  Scala sealed abstract class with enum object matching against string
Scala sealed abstract class with enum object matching against string

Time:08-19

I am a beginner in scala, I have a case class for the response I am getting as json payload

case class CallbackPayload(
            automation_id: String,
            business_key: String,
            state: String #received , validating
       )

I have a sealed abstract class

object ExecutionStatus {
  sealed abstract class ExecutionState(status: String) {
    override def toString: String = status
  }

  case object RECEIVED extends ExecutionState("received")
  case object VALIDATING extends ExecutionState("validating")
}

Now based on the response payload state I want to do a match against the ExecutionStatus objects

Something like below

def callback(payload: CallbackPayload): Either[Throwable, Json] = {
    payload.state match {
      case VALIDATING => Right(Json.obj("status" -> Json.fromString("validating")))
    .....
    }
  }

Now because of payload.state type string I am unable to . How to do that in scala.

CodePudding user response:

It looks like you may want to match on the status string, like so (using a simplified model of your code):

object ExecutionStatus {
  sealed abstract class ExecutionState(val status: String) {
    override def toString: String = status
  }    

  case object RECEIVED extends ExecutionState("received")
  case object VALIDATING extends ExecutionState("validating")
}

def parse(state: String): Either[Throwable, Map[String, String]] = {
  state match {
    case ExecutionStatus.RECEIVED.status =>
      Right(Map("status" -> "received"))
    case ExecutionStatus.VALIDATING.status =>
      Right(Map("status" -> "validating"))
    case _ => 
      Left(new IllegalArgumentException(s"unrecognized state $state"))
  }
}

assert(parse("received") == Right(Map("status" -> "received")))
assert(parse("validating") == Right(Map("status" -> "validating")))
assert(parse("foo").isLeft)

You can play around with this code here on Scastie.

Notice that in order to do so I had to make status a val so that it's public (without it, status is only a constructor parameter).

  • Related