blob: 311669b8164b22b668ba5fbfeb811fa420103a29 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package cc.spray.json
package lenses
trait JsonPathIntegration { self: ScalarLenses with SeqLenses =>
/**
* Create a Lens from a json-path expression.
*/
def fromPath(path: String): Lens[Seq] =
fromPath(JsonPathParser(path))
def fromPath(ast: JsonPath.Path): Lens[Seq] = {
def convertPath(path: JsonPath.Path): Lens[Seq] = path match {
case JsonPath.Root => value.toSeq
case JsonPath.Selection(inner, proj) => convertPath(inner) / convertLens(proj)
}
def convertLens(proj: JsonPath.Projection): Lens[Seq] =
proj match {
case JsonPath.ByField(name) => field(name).toSeq
case JsonPath.ByIndex(i) => element(i).toSeq
case JsonPath.AllElements => elements
case JsonPath.ByPredicate(pred) => filter(convertPredicate(pred))
}
def convertPredicate(pred: JsonPath.Predicate): JsPred = pred match {
case op: JsonPath.BinOpPredicate =>
val f1 = convertExpr(op.expr1)
val f2 = convertSimpleExpr(op.expr2)
js => {
val v2 = f2(js)
f1(js).right.forall(_.forall(v1 => op.predicate(v1, v2)))
}
case JsonPath.Exists(path) =>
js => convertPath(path).retr(js).isRight
}
def convertExpr(expr: JsonPath.Expr): JsValue => Validated[Seq[JsValue]] = expr match {
case JsonPath.PathExpr(path) => js => convertPath(path).retr(js)
case simple: JsonPath.SimpleExpr => js => Right(Seq(convertSimpleExpr(simple)(js)))
}
def convertSimpleExpr(expr: JsonPath.SimpleExpr): JsValue => JsValue = expr match {
case JsonPath.Constant(x) => _ => x
}
convertPath(ast)
}
}
|