Search code examples
scalaargonaut

Raising Argonaut tuple arity to 23


I'm trying to implement a CodecJson with arity 23. It looks something like this:

implicit def infoCodec: CodecJson[Info] = CodecJson(
    (x: Info) => argonaut.Json(
      "a" -> x.a,
      "b" -> x.b,
      "c" -> x.c,
      ...(a total of 23 fields)
    ),
cursor => for {
      a <- cursor.get("a")
      b <- cursor.get("b")
      c <- cursor.get("c")
      ...(a total of 23 fields)
    }
  )

However, I get type errors on all fields such as:

type mismatch;
  Id|Json
      "a" -> x.a,

How do I convert x.a into Json - and so on for all other fields/types?

Thank you!


Solution

  • EDIT: Scala functions are limited to an arity of 22. So this may just be your problem.

    You need to use the "methods" supplied by Argonaut for constructing a JSON: := and ->:. For example:

    case class MyCookie(name: String, value: String)
    implicit def myCookieCodec = CodecJson((c: MyCookie) =>
        ("name" := c.name) ->:
        ("value" := c.value) ->: 
        jEmptyObject,
        c => for {
            name <- (c --\ "name").as[String]
            value <- (c --\ "value").as[String]
        } yield Cookie(name, value)
    )
    

    The ->: implies a "prepend", this means you have to read a chain of ->: calls from right to left. Regarding the example above:

    1. Start with an empty object (jEmptyObject)
    2. Add a key "value" with the value "c.value" (("value" := c.value))
    3. Add a key "name" with the value "c.name" (("name" := c.name))

    := constructs a JSON key-value pair.

    I think your decoding part (the second parameter to CodecJson.apply()) should work as intended.