Converting Proto Enum to Enum

Viewed 66

I have to enums in two different proto files.

enum Some {
    OPTIONA = 0;
    OPTIONB = 1;
    OPTIONC = 2;
}
enum SomeOther {
    OPTIONA = 0;
    OPTIONB = 1;
    OPTIONC = 2;
}

They autogenerate into this in one file:

sealed abstract class Some(val value: _root_.scala.Int) extends _root_.scalapb.GeneratedEnum {}
object Some extends _root_.scalapb.GeneratedEnumCompanion[Some] {}

and this in another

sealed abstract class SomeOther(val value: _root_.scala.Int) extends _root_.scalapb.GeneratedEnum {...}
object SomeOther extends _root_.scalapb.GeneratedEnumCompanion[SomeOther] {...}

I would like to be able to convert Some to SomeOther or viceversa seamlessly without having to pattern match.

I really like chimney's expression something like:

Some.transformInto[SomeOther]

But it doesn't work as the chimney library errors out with the types being ambiguous

I tried to make an implicit class like so:

  implicit class EnumToEnum[From <: GeneratedEnum](enum : GeneratedEnumCompanion[From]) {
    def transformTo[To <: GeneratedEnum](err : Error): Either[Error, GeneratedEnumCompanion[To]] {
      GeneratedEnumCompanion[To].fromValue(enum.value)
      ???
    }
  }

However I can't quite do that because GeneratedEnumCompanion and GeneratedEnum are traits.

So is there a way to convert seamlessly between proto enums with chimney and if not how can I write my own generic method?

1 Answers

Checking scalapb, it doesn't seem like there is a better solution besides the ones you already mentioned:

Since Scala type equality is not type-safe (a == b will compile even when a and b are of types that can never be equal), it is recommended to use the various isX methods or pattern matching for comparison:

// Using isX:
val t = if (phoneType.isMobile) "Mobile" else "Not Mobile"

// Using pattern matching
phoneType match {
  case PhoneType.MOBILE => println("Mobile!")
  case _                => println("Not mobile!")
}

I couldn't find any useful example on converting between enumerations on Chimney either.

Doing a generic method might just work, but you'll need to consider using reflection such as ClassTag due to type erasure. Consider checking this out.

Related