0

I have the following type Converter:

import scala.concurrent.duration._

/**
  * Type classes that define the message transformations to and fro between JSON and
  * case class types
  */
object JsonMessageConversion {
  implicit val resolveTimeout: Timeout = Timeout(3.seconds)

  case class FailedMessageConversion(kafkaTopic: String, msg: String, msgType: String)

  trait Converter[T <: KafkaMessage] {
      def convertFromJson(msg: String): Either[FailedMessageConversion, T]
      def convertToJson(msg: T): String
  }

  //Here is where we create implicit objects for each Message Type you wish to convert to/from JSON
  object Converter {

    val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    implicit val jodaDateTimeReads: Reads[DateTime] = Reads[DateTime](js =>
      js.validate[String].map[DateTime](dt =>
        DateTime.parse(dt, DateTimeFormat.forPattern(dateFormat))
      )
    )

    implicit val jodaDateTimeWrites: Writes[DateTime] = new Writes[DateTime] {
      def writes(dt: DateTime): JsValue = JsString(dt.toString())
    }

    implicit object DefaultMessageConverter extends Converter[DefaultMessage] {

      implicit val defaultMessageReads: Reads[DefaultMessage] = (
        (__ \ "message").read[String] and
        (__ \ "timestamp").read[DateTime](jodaDateTimeReads)
      )(DefaultMessage.apply _)

      implicit val defaultMessageWrites: Writes[DefaultMessage] = (
        (__ \ "message").write[String] and
        (__ \ "timestamp").write[DateTime](jodaDateTimeWrites)
      )(unlift(DefaultMessage.unapply))

      implicit val defaultMessageFormat: Format[DefaultMessage] =
        Format(defaultMessageReads, defaultMessageWrites)

      override def convertFromJson(msg: String): Either[FailedMessageConversion, DefaultMessage] = {
        Json.parse(msg).validate[DefaultMessage] match {
          case s: JsSuccess[DefaultMessage] => Right(s.value)
          case _: JsError => Left(FailedMessageConversion("kafkaTopic", msg, "to: DefaultMessage"))
        }
      }

      override def convertToJson(msg: DefaultMessage): String = {
        Json.toJson(msg).toString()
      }
    }

    implicit object DefaultMessageBundleConverter extends Converter[DefaultMessageBundle] {

      implicit val defaultMessageReads = Converter.DefaultMessageConverter.defaultMessageReads
      implicit val defaultMessageWrites = Converter.DefaultMessageConverter.defaultMessageWrites

      implicit val defaultMessageBundleReads: Reads[DefaultMessageBundle] = (
        (__ \ "messages").read[Seq[DefaultMessage]] and
          (__ \ "timestamp").read[DateTime](jodaDateTimeReads)
        )(DefaultMessageBundle.apply _)

      implicit val defaultMessageBundleWrites: Writes[DefaultMessageBundle] = (
        (__ \ "messages").write[Seq[DefaultMessage]] and
          (__ \ "timestamp").write[DateTime](jodaDateTimeWrites)
        )(unlift(DefaultMessageBundle.unapply))

      implicit val defaultMessageFormat: Format[DefaultMessageBundle] =
        Format(defaultMessageBundleReads, defaultMessageBundleWrites)

      override def convertFromJson(msg: String): Either[FailedMessageConversion, DefaultMessageBundle] = {
        Json.parse(msg).validate[DefaultMessageBundle] match {
          case s: JsSuccess[DefaultMessageBundle] => Right(s.value)
          case _: JsError => Left(FailedMessageConversion("kafkaTopic", msg, "to: DefaultMessageBundle"))
        }
      }

      override def convertToJson(msg: DefaultMessageBundle): String = {
        Json.toJson(msg).toString()
      }
    }

    def apply[T: Converter] : Converter[T] = implicitly
  }
}

I get an error when compilation:

Error:(98, 16) type arguments [T] do not conform to trait Converter's type parameter bounds [T <: com.eon.pm.messages.KafkaMessage]
    def apply[T: Converter] : Converter[T] = implicitly

How can I get rid of this error?

1 Answer 1

1

Just add the same type bound to that method as well:

def apply[T <: KafkaMessage : Converter] : Converter[T] = implicitly

I am not sure why the compiler requires this redundancy, but this gets rid of the error.

Sign up to request clarification or add additional context in comments.

1 Comment

It does get rid of the error, but I thought this might solve another problem that I originally had, but it didn't! Here is the post that I asked a few minutes ago: stackoverflow.com/questions/48290065/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.