An end-to-end example of Json Logic Scala
This example starts from typed JsonLogic data, then deserializes it into a Scala data structure. With json-logic-scala, it would be just as easy to perform the reverse process (starting from a Scala struture and serializing it as Typed JsonLogic).
1. Represent an expression as JsonLogic-typed
Consider the following expression.
\[\mathbf{price} \ge 20\ \&\ \mathbf{label}\neq\mathbf{label2}\]You can represent this expression, along with possible values in a single Json data file:
[
{
"and": [
{
">=": [
{
"var": "price",
"type": {
"codename": "int"
}
},
{
"var": "price_threshold",
"type": {
"codename": "int"
}
}
]
},
{
"!=": [
{
"var": "value",
"type": {
"codename": "string"
}
},
{
"var": "value_to_be_different",
"type": {
"codename": "string"
}
}
]
}
]
},
{
"price": 45,
"price_threshold": 20,
"value": "label456",
"value_to_be_different": "label2"
}
]
Note that, in this snippet, data and logic are separate objects.
Let’s assume this json is written in a json file named binary_expression.json
.
2. Deserialize the Json as a Scala Data structure
Using Json Logic Scala, you can deserialize the preceding JSON snippet as a scala data structure. The expression and data looks like this:
import play.api.libs.json.Json
val jsonString: String = scala.io.Source.fromFile("binary_expression.json").mkString
implicit val deserializerConf: DeserializerConf = DeserializerConf.createConf()
val deserializer = new Deserializer()
val jsonLogicCore = deserializer.deserialize(jsonString)
the resulting jsonLogicCore
structure is equivalent to
import com.celadari.jsonlogicscala.tree.types.DefaultTypes.{INT_CODENAME, STRING_CODENAME}
val tree = new ComposeLogic("and", Array(
new ComposeLogic(">=", Array(
ValueLogic(Some(45), typeOpt = Some(SimpleTypeValue(INT_CODENAME)), pathNameOpt = Some("price")),
ValueLogic(Some(20), typeOpt = Some(SimpleTypeValue(INT_CODENAME)), pathNameOpt = Some("price_threshold"))
)),
new ComposeLogic("!=", Array(
ValueLogic(Some("label456"), typeOpt = Some(SimpleTypeValue(STRING_CODENAME)), pathNameOpt = Some("value")),
ValueLogic(Some("label2"), typeOpt = Some(SimpleTypeValue(STRING_CODENAME)), pathNameOpt = Some("value_to_be_different"))
))
))
3. Evaluate the expression
Finally, you can evaluate this Scala data structure.
val evaluator = new EvaluatorLogic
evaluator.eval(tree)
// false: Any
The price value is 45, and the tested threshold is 20. 45 is greater than 20, so the result will be false
.
4. Serialize to TypedJson
Using Json Logic Scala, you can serialize the json-scala data structure to a JSON snippet. The expression and data looks like this:
import com.celadari.jsonlogicscala.tree.types.DefaultTypes.{INT_CODENAME, STRING_CODENAME}
val tree = new ComposeLogic("and", Array(
new ComposeLogic(">=", Array(
ValueLogic(Some(45), typeOpt = Some(SimpleTypeValue(INT_CODENAME)), pathNameOpt = Some("price")),
ValueLogic(Some(20), typeOpt = Some(SimpleTypeValue(INT_CODENAME)), pathNameOpt = Some("price_threshold"))
)),
new ComposeLogic("!=", Array(
ValueLogic(Some("label456"), typeOpt = Some(SimpleTypeValue(STRING_CODENAME)), pathNameOpt = Some("value")),
ValueLogic(Some("label2"), typeOpt = Some(SimpleTypeValue(STRING_CODENAME)), pathNameOpt = Some("value_to_be_different"))
))
))
import play.api.libs.json.Json
implicit val serializerConf: SerializerConf = SerializerConf.createConf()
val serializer = new Serializer()
val jsonLogicCore = serializer.serialize(tree)