bijection
bijection copied to clipboard
Inversion failure for TEnumCodec
Scrooge generated ThriftEnum does extend the apache TEnum, e.g. https://github.com/twitter/scrooge/blob/master/scrooge-core/src/main/scala/com/twitter/scrooge/ThriftEnum.scala#L5
sealed trait EngagementType extends ThriftEnum with Serializable
But the com.twitter.bijection.thrift.TEnumCodec.toBinary[T <: TEnum] throws when used with scrooge TEnum.
Maybe the solution is to simply create a com.twitter.bijection.scrooge.ThriftEnumCodec, though it would be nice to catch this at compile time.
scala> import com.twitter.discover.summingbird.common.thriftscala.EngagementType
import com.twitter.discover.summingbird.common.thriftscala.EngagementType
scala> import EngagementType._
import EngagementType._
scala> val inj = com.twitter.bijection.thrift.TEnumCodec.toBinary[EngagementType]
inj: com.twitter.bijection.Injection[com.twitter.discover.summingbird.common.thriftscala.EngagementType,Array[Byte]] = com.twitter.bijection.Injection$$anon$1@12141052
scala> inj(Click)
res0: Array[Byte] = Array(0, 0, 0, 1)
scala> inj.invert(res0).get
java.lang.NoSuchMethodException: com.twitter.discover.summingbird.common.thriftscala.EngagementType.findByValue(int)
at java.lang.Class.getMethod(Class.java:1622)
at com.twitter.bijection.thrift.TEnumCodec.findByValue(ThriftCodecs.scala:117)
at com.twitter.bijection.thrift.TEnumCodec$$anonfun$invert$3.apply(ThriftCodecs.scala:121)
at com.twitter.bijection.thrift.TEnumCodec$$anonfun$invert$3.apply(ThriftCodecs.scala:121)
at scala.collection.mutable.MapLike$class.getOrElseUpdate(MapLike.scala:176)
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:45)
at com.twitter.bijection.thrift.TEnumCodec.invert(ThriftCodecs.scala:121)
at com.twitter.bijection.thrift.TEnumCodec.invert(ThriftCodecs.scala:114)
at com.twitter.bijection.Injection$$anon$1$$anonfun$invert$1.apply(Injection.scala:41)
at com.twitter.bijection.Injection$$anon$1$$anonfun$invert$1.apply(Injection.scala:41)
at scala.util.Success.flatMap(Try.scala:199)
at com.twitter.bijection.Injection$$anon$1.invert(Injection.scala:41)
at .<init>(<console>:14)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:722)
So, the issue here is that when doing reflection on the TEnum, we can't see that the reflection will fail.
The right way to solve this is probably with a macro: the macro should look for the method at compile time so the error is seen (or actually, even better, we look for the correct method).