All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spray.json.lenses.Lens.scala Maven / Gradle / Ivy

The newest version!
package spray.json
package lenses

/**
 * A Lens combines read and update functions of UpdateLens and ReadLens into
 * combinable chunks.
 *
 * A lens can either operate on a scalar value, or on an optional value, or on a
 * sequence value. This is denoted by the `M[_]` type constructor.
 */
trait Lens[M[_]] extends UpdateLens with ReadLens[M] {
  /**
   * A shortcut for the `combine` lens which combines two lenses.
   */
  def /[M2[_], R[_]](next: Lens[M2])(implicit ev: Join[M2, M, R]): Lens[R]

  def toSeq: Lens[Seq]

  def ops: Ops[M]
}

/**
 * This implements most of the methods of `Lens`. Implementors of a new type of lens
 * must implement `retr` for the read side of the lens and `updated` for the update side of the lens.
 */
abstract class LensImpl[M[_]](implicit val ops: Ops[M]) extends Lens[M] { outer ⇒
  import ExtraImplicits.richValue

  def tryGet[T: Reader](p: JsValue): Validated[M[T]] =
    retr(p).flatMap(mapValue(_)(_.as[T]))

  def get[T: Reader](p: JsValue): M[T] =
    tryGet[T](p).getOrThrow

  def !(op: Operation): Update = new Update {
    def apply(parent: JsValue): JsValue =
      updated(op)(parent).getOrThrow
  }

  def is[U: Reader](f: U ⇒ Boolean): JsPred = value ⇒
    tryGet[U](value) exists (x ⇒ ops.map(x)(f).forall(identity))

  def /[M2[_], R[_]](next: Lens[M2])(implicit ev: Join[M2, M, R]): Lens[R] =
    JsonLenses.combine(this, next)

  def toSeq: Lens[Seq] = this / SeqLenses.asSeq

  private[this] def mapValue[T](value: M[JsValue])(f: JsValue ⇒ Validated[T]): Validated[M[T]] =
    ops.allRight(ops.map(value)(f))
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy