Generic json decoder trait with Circe implementation [duplicate]

孤街醉人 提交于 2019-12-13 00:16:29

问题


I have a trait used to inject json decoder as dependency to components of my project:

trait JsonDecoder {
  def apply[T](s: String): Option[T]
}

When I try to implement it with Circe:

import io.circe.generic.auto._
import io.circe.parser.decode

case class CirceJsonDecoder() extends JsonDecoder {
  def apply[T](s: String): Option[T] = {
    decode[T](s).fold(_ => None, s => Some(s)) 
  }
}

and run:

case class C()

def test(d: JsonDecoder) = d[C]("{}")

test(CirceJsonDecoder())

it does not compile with error:

could not find implicit value for parameter decoder: io.circe.Decoder[T]

I tried to add ClassTag, TypeTag or WeakTypeTag context bounds for T but it still can not find implicit value for Decoder.

I can not add Decoder context bound or implicit parameter to JsonDecoder.apply because components what use it should not know about implementation details.

How should I provide implicit io.circe.Decoder? May be there is some way to get it from TypeTag?


回答1:


I don't think you can without affecting your apply method signature in any way involving circe. If you could, it'd mean circe.auto_ is capable of bringing an implicit decoder in scope for any type T, which is not true.

AFAIK, there's no better type annotation than adding an implicit Decoder to your function to signal circe that it actually knows how to handle this type (if you prefer, you can use the T: Decoder version, but it's the same in the end).



来源:https://stackoverflow.com/questions/41058947/generic-json-decoder-trait-with-circe-implementation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!