Skip to content

Instantly share code, notes, and snippets.

@leandrob13
Last active January 20, 2017 15:27
Show Gist options
  • Save leandrob13/9c73bcabcdb71f4765808c615b530e10 to your computer and use it in GitHub Desktop.
Save leandrob13/9c73bcabcdb71f4765808c615b530e10 to your computer and use it in GitHub Desktop.
How to resolve implicitly the companion of a protobuf class. The issue on ScalaPB regarding this proposal is: https://github.com/scalapb/ScalaPB/issues/229
trait Event
object KafkaEncoder {
type KafkaProtobufEvent[T <: Event] = GeneratedMessage with Message[T] with Updatable[T] with Event
type KafkaProtobufEncoder[E <: KafkaProtobufEvent[E]] = GeneratedMessageCompanion[E]
def apply[T <: KafkaProtobufEvent[T]](implicit enc: KafkaEncoder[T]) = enc
def serialize[T <: KafkaProtobufEvent[T]](data: T)(implicit companion: KafkaProtobufEncoder[T]): Array[Byte] =
companion.toByteArray(data)
def deserealize[T <: KafkaProtobufEvent[T]](bytes: Array[Byte])(implicit companion: KafkaProtobufEncoder[T]): Try[T] =
Try(companion.parseFrom(bytes))
}
trait KafkaEncoder[T <: KafkaEncoder.KafkaProtobufEvent[T]] {
val companion: KafkaEncoder.KafkaProtobufEncoder[T]
def serialize(data: T): Array[Byte] = companion.toByteArray(data)
def deserealize(bytes: Array[Byte]): Try[T] = Try(companion.parseFrom(bytes))
}
object Test {
import KafkaEncoder._
//I thought I was supposed to do this but compiles without it
//implicit val uc: GeneratedMessageCompanion[TESTCASE] = TESTCASE
//Implicit instance that defines the companion, which is not necessary thanks to the implicit def messageCompanion
implicit val testCaseEncoder: KafkaEncoder[TESTCASE] = new KafkaEncoder[TESTCASE] {
override val companion = TESTCASE
}
val byDeclaringImplicitInstance: Array[Byte] = KafkaEncoder[TESTCASE].serialize(TESTCASE())
//compiles
val bytes: Array[Byte] = serialize(TESTCASE())
val testCase: Try[TESTCASE] = deserealize[TESTCASE](bytes)
}
case class TESTCASE() extends GeneratedMessage with Message[TESTCASE] with Updatable[TESTCASE] with Event {
override def writeTo(output: CodedOutputStream): Unit = ???
override def getField(field: FieldDescriptor): Any = ???
override def companion: GeneratedMessageCompanion[_] = ???
override def serializedSize: Int = ???
override def mergeFrom(input: CodedInputStream): TESTCASE = ???
}
object TESTCASE extends GeneratedMessageCompanion[TESTCASE] {
implicit def messageCompanion: GeneratedMessageCompanion[TESTCASE] = this
override def fromFieldsMap(fields: Map[FieldDescriptor, Any]): TESTCASE = ???
override def descriptor: Descriptor = ???
override def messageCompanionForField(field: FieldDescriptor): GeneratedMessageCompanion[_] = ???
override def enumCompanionForField(field: FieldDescriptor): GeneratedEnumCompanion[_] = ???
override def defaultInstance: TESTCASE = ???
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment