Argonaut.io: Come rinominare JSON Property per il diritto / sinistra in caso di classe contenente entrambi

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

  •  20-12-2019
  •  | 
  •  

Domanda

ad Argonaut, come si rinomina facilmente il nome della proprietà JSON corrispondente in istanze in cui una cassa di cassa contiene unica.

Ad esempio, data questa definizione:

  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")
.

Conversione di un FooBar in JSON come FooBar(Right(Bar("hello"))).asJson.spaces4 Risultati:

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

Qual è il modo più semplice per rinominare il "giusto" a qualcosa di più significativo nell'output sopra?(Il mio vero scenario ha molte classi di case con molti etuithers, quindi sto cercando il modo più conciso possibile.)

È stato utile?

Soluzione

Ecco un approccio ragionevolmente semplice:

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")))
)
.

E poi:

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

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

Potresti anche rendere le istanze Implicit fooOrBar, ma sopravvalutarvi in questo modo tende ad essere disapprovazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top