2016-12-09 4 views
1

Ich habe eine Eigenschaft verwendet, um json Decoder als Abhängigkeit Komponenten meines Projekts zu injizieren:Generisches json Decoder Merkmal mit Circe Implementierung

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

Wenn ich versuche, es zu implementieren mit 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)) 
    } 
} 

und laufen:

case class C() 

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

test(CirceJsonDecoder()) 

es nicht mit dem Fehler nicht kompilieren:

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

Ich versuchte ClassTag, TypeTag oder WeakTypeTag Kontext Grenzen für T hinzufügen, aber es kann immer noch nicht impliziten Wert für Decoder finden.

Ich kann Decoder Kontext gebundenen oder impliziten Parameter zu JsonDecoder.apply nicht hinzufügen, da Komponenten, die es verwenden sollten nicht über Implementierungsdetails wissen sollten.

Wie soll ich implizit io.circe.Decoder bereitstellen? Kann es einen Weg geben, es von TypeTag zu bekommen?

+1

Von was ich verstehe, wie Sie versucht haben, es zu beheben (Hinzufügen von Reflektion über 'ClassTag' /' TypeTag'), nehmen Sie an, Circe verwendet Reflektion, um die JSON-Codecs abzuleiten. Das ist nicht der Fall. Stattdessen leitet circe die Codecs bei compiletime ab, also benötigt es mehr Informationen als nur "T" über einen Typ. Sie könnten 'shapeless.LabledGeneric' oder' shapless.Generic' Kontext gebunden versuchen. – Reactormonk

Antwort

4

Ich glaube nicht, dass Sie ohne Ihre Anwendung Methode Unterschrift in irgendeiner Weise mit circe beeinflussen können. Wenn Sie könnten, würde es bedeuten, circe.auto_ ist in der Lage, einen impliziten Decoder in den Geltungsbereich für jeden Typ T bringen, was nicht wahr ist.

AFAIK, gibt es keine bessere Art Anmerkung als eine implizite Decoder an Ihre Funktion Hinzufügen circe, um zu signalisieren, dass es tatsächlich weiß, wie man diese Art zu behandeln (wenn Sie möchten, können Sie die T: Decoder Version verwenden, aber es ist das gleiche am Ende).

+0

Danke! Ich habe Ihre Antwort geupdated, aber ich habe die gleiche Frage schon einmal gestellt und diese als Duplikat markiert. Ich werde meine endgültige Lösung dort posten. Ich verwende den Typklassenansatz, wie Sie und der Typ aus dieser Frage vorgeschlagen haben. – mixel

+0

Siehe http://stackoverflow.com/a/41102192/746347. – mixel

Verwandte Themen