I am wondering if it is possible to do pattern matching on Jackson JSON objects in Scala. We are currently using jackson-module-scala in a Project heavily and would benefit from being able to do pattern matching of Json ObjectNode/JsonNode objects.
If this is not possible, how would I go about adding this functionality? I was thinking something in terms of implicit conversion from JsonNode/ObjectNode to MyClass, where MyClass would have unapply method, doing JsonNode.toString and regex matching. If my logic is correct, I could then do pattern matching on JsonNode objects. Of course, there could be better ways I am not aware of, or this one may not work for reasons I am not yet aware of. To illustrate my case, I would like to be able to perform something in terms of:
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val json = mapper.createObjectNode()
.put("key1","value1")
.put("key2","value2")
.put("key3","value3")
json match {
case MyClass("key1", "value1", "key2", y) => println("Found key1 with value1, where key2 is " + y)
case MyClass("key1", x) => println("Key1 value is " + x)
...
_ => println("No match found")
}
Have you tried to make use of the case class deserialization?
https://github.com/FasterXML/jackson-module-scala/blob/master/src/test/scala/com/fasterxml/jackson/module/scala/deser/CaseClassDeserializerTest.scala
If that doesn’t work, I think you would be better off creating extractors to represent your domain objects. Code below assumes a scala Map, but it should give you an idea. No implicit conversion required.
However, if you insist on trying to match against the key/value pairs, there may be ways to accomplish something which is acceptable for you. It is not possible to pass input into the unapply function from the
case, which I think would be required if I understand what you want to do correctly. It may be possible to do this with macros which are experimental in the soon-to-be-officially-released scala 2.10. I haven’t played with them enough to know if this is or is not possible though.If ordering of keys was assumed, you could come up with a
::unapply operator similar to::for list. This could extract theK, Vpairs in this known order. Personally, this is too fragile for my tastes.You would not be able to extract keys in the wrong order though
You could write
Key1,Key2,Key3as well. This may or may not scale well.