blob: ef61b1506317f25ed27a844dc1f256c13d821f8a (
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
package cc.spray.json
package object lenses {
type JsPred = JsValue => Boolean
type Id[T] = T
type Validated[T] = Either[Exception, T]
type SafeJsValue = Validated[JsValue]
type Operation = SafeJsValue => SafeJsValue
type ScalarProjection = Projection[Id]
type OptProjection = Projection[Option]
type SeqProjection = Projection[Seq]
def ??? = sys.error("NYI")
def unexpected(message: String) = Left(new RuntimeException(message))
def outOfBounds(message: String) = Left(new IndexOutOfBoundsException(message))
implicit def rightBiasEither[A, B](e: Either[A, B]): Either.RightProjection[A, B] = e.right
case class GetOrThrow[B](e: Either[Throwable, B]) {
def getOrThrow: B = e match {
case Right(b) => b
case Left(e) => throw e
}
}
implicit def orThrow[B](e: Either[Throwable, B]): GetOrThrow[B] = GetOrThrow(e)
trait Reader[T] {
def read(js: JsValue): Validated[T]
}
object Reader {
implicit def safeMonadicReader[T: JsonReader]: Reader[T] = new Reader[T] {
def read(js: JsValue): Validated[T] =
safe(js.convertTo[T])
}
}
def safe[T](body: => T): Validated[T] =
try {
Right(body)
} catch {
case e: Exception => Left(e)
}
case class ValidateOption[T](option: Option[T]) {
def getOrError(message: => String): Validated[T] = option match {
case Some(t) => Right(t)
case None => unexpected(message)
}
}
implicit def validateOption[T](o: Option[T]): ValidateOption[T] = ValidateOption(o)
case class RichJsValue(value: JsValue) {
def update(updater: Update): JsValue = updater(value)
def update[T: JsonWriter, M[_]](lens: UpdateLens, pValue: T): JsValue =
lens ! Operations.set(pValue) apply value
// This can't be simplified because we don't want the type constructor
// of projection to appear in the type paramater list.
def extract[T: Reader](p: Projection[Id]): T =
p.get[T](value)
def extract[T: Reader](p: Projection[Option]): Option[T] =
p.get[T](value)
def extract[T: Reader](p: Projection[Seq]): Seq[T] =
p.get[T](value)
def as[T: Reader]: Validated[T] =
implicitly[Reader[T]].read(value)
}
implicit def updatable(value: JsValue): RichJsValue = RichJsValue(value)
}
|