Argonaut.io:So benennen Sie die JSON-Eigenschaft für „Rechts/Links“ um, falls eine Klasse „Entweder“ enthält

StackOverflow https://stackoverflow.com//questions/23003735

  •  20-12-2019
  •  | 
  •  

Frage

Wie kann man in Argonaut den entsprechenden JSON-Eigenschaftsnamen einfach umbenennen, wenn eine Fallklasse ein Entweder enthält?

Nehmen wir zum Beispiel diese Definition:

  case class Foo(f: String)
  case class Bar(b: String)
  case class FooBar(e: Either[Foo, Bar])

  implicit def FooCodecJson: CodecJson[Foo] = casecodec1(Foo.apply, Foo.unapply)("f")

  implicit def BarCodecJson: CodecJson[Bar] = casecodec1(Bar.apply, Bar.unapply)("b")

  implicit def FooBarCodecJson: CodecJson[FooBar] = casecodec1(FooBar.apply, FooBar.unapply)("e")

Umwandeln von a FooBar zu JSON wie FooBar(Right(Bar("hello"))).asJson.spaces4 ergibt folgendes:

{
    "e" : {
        "Right" : {
            "b" : "hello"
        }
    }
}

Was ist der einfachste Weg, das „Recht“ in der obigen Ausgabe in etwas aussagekräftigeres umzubenennen?(Mein aktuelles Szenario hat viele Fallklassen mit vielen Entweder, daher suche ich nach einem möglichst prägnanten Weg.)

War es hilfreich?

Lösung

Hier ist ein einigermaßen einfacher Ansatz:

def renameFields(replacements: (JsonField, JsonField)*)(json: Json) =
  json.withObject(obj =>
    replacements.foldLeft(obj) {
      case (acc, (before, after)) => 
        acc(before).map(v => (acc - before) + (after, v)).getOrElse(acc)
    }
  )

def renamedEitherCodec[A, B](leftName: String, rightName: String)(implicit
  ee: EncodeJson[Either[A, B]],
  de: DecodeJson[Either[A, B]]
) = CodecJson[Either[A, B]](
  e => renameFields("Left" -> leftName, "Right" -> rightName)(ee(e)),
  c => de(c.withFocus(renameFields(leftName -> "Left", rightName -> "Right")))
)

Und dann:

val fooOrBar = namedEitherCodec[Foo, Bar]("Foo", "Bar")

implicit def FooBarCodecJson: CodecJson[FooBar] = casecodec1(
  FooBar.apply, FooBar.unapply
)("e")(fooOrBar, fooOrBar)

Du könntest auch das machen fooOrBar implizit, aber das Überschreiben von Typklasseninstanzen auf diese Weise wird tendenziell verpönt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top