-1

For example suppose I have

case class Test(a: String, b: String)
...
implicit val testFormat = jsonFormat2(Test.apply)

and a json with an extra c field:

val test = "{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\"}"

then I want to find a way (config/param/whatever) to make the following line throw and exception:

test.parseJson.convertTo[Test]

It's very hard to work this out from reading the source code and github documentation.

samthebest
  • 30,803
  • 25
  • 102
  • 142

1 Answers1

0

I didn't see anything in the library that provides that functionality, so I created a wrapper that does a quick check on the number of fields present before delegating the read call to the supplied formatter.

case class StrictRootFormat[T](format: RootJsonFormat[T], size: Int) extends RootJsonFormat[T] {

  def read(json: JsValue): T = {
    if(json.asJsObject.fields.size > size) deserializationError("JSON has too many fields: \n " + json.toString())
    else format.read(json)
  }

  def write(obj: T): JsValue = format.write(obj)

}

Usage:

implicit val testFormat = StrictRootFormat(jsonFormat2(Test.apply), 2)

You could enhance the read implementation so that you don't need to supply the "size" argument.

Eric Woods
  • 106
  • 4
  • Hmm, thanks for the answer, not quite what we need, since we could have some `Option`al fields missing and end up with the exact same size. Nevertheless I think I could edit it to work - by supplying the `ClassTag` we can use `productIterator.toSet`. Ideally I'd also like to ensure this also works with http://stackoverflow.com/questions/33367983/how-to-parse-json-with-spray-json-that-uses-snake-case-underscore-notation-ins/33367984#33367984 – samthebest Oct 27 '15 at 12:27