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

argonaut.ACursor.scala Maven / Gradle / Ivy

The newest version!
package argonaut

case class ACursor(either: Either[HCursor, HCursor]) {
  import CursorOp._
  import Json._

  /** Get the current hcursor if we are in an succeeded state. Alias for `success`. */
  def hcursor: Option[HCursor] =
    either.right.toOption

  /** Get the current hcursor if we are in an succeeded state. Alias for `hcursor`. */
  def success: Option[HCursor] =
    hcursor

  /** Get the failed hcursor if we are in an failed state. */
  def failure: Option[HCursor] =
    either.left.toOption

  /**
   * Attempts to decode this cursor focus value to another data type.
   */
  def jdecode[A](implicit e: DecodeJson[A]): DecodeResult[A] =
    e.tryDecode(this)

  /**
   * Attempts to decode this cursor focus value to another data type.
   * Alias for `jdecode`.
   */
  def as[A](implicit e: DecodeJson[A]): DecodeResult[A] =
    jdecode[A]

  /**
   * Attempts to move down onto a field `name` and decode the focus.
   */
  def get[A](name: String)(implicit e: DecodeJson[A]): DecodeResult[A] =
    downField(name).as[A]

  def succeeded: Boolean =
    hcursor.isDefined

  def failed: Boolean =
    !succeeded

  def cursor: Option[Cursor] =
    hcursor.map(_.cursor)

  def any: HCursor =
    either.fold(l => l, r => r)

  def history: CursorHistory =
    any.history

  def reattempt: ACursor =
    either match {
      case Left(HCursor(cursor, CursorHistory(history))) => ACursor.ok(HCursor(cursor, CursorHistory(reattemptOp +: history)))
      case Right(_) => this
    }

  def unary_~ : ACursor =
    reattempt

  /** Return the current focus, iff we are succeeded */
  def focus: Option[Json] =
    success.map(_.focus)

  /** Return the previous focus, iff we are !succeeded. */
  def failureFocus: Option[Json] =
    failure.map(_.focus)

  /** Update the focus with the given function (alias for `withFocus`). */
  def >->(k: Json => Json): ACursor =
    withFocus(k)

  /** Update the focus with the given function (alias for `>->`). */
  def withFocus(k: Json => Json): ACursor =
    ACursor(either.right.map(_.withFocus(k)))

  /** Set the focus to the given value (alias for `:=`). */
  def set(j: Json): ACursor =
    withFocus(_ => j)

  /** Set the focus to the given value (alias for `set`). */
  def :=(j: Json): ACursor =
    set(j)

  /**
   * Return the values left of focus in a JSON array.
   */
  def lefts: Option[JsonArray] =
    hcursor.flatMap(_.lefts)

  /**
   * Return the values right of focus in a JSON array.
   */
  def rights: Option[JsonArray] = hcursor.flatMap(_.rights)

  def withHCursor(f: HCursor => ACursor): ACursor =
    ACursor(either.right.flatMap(c => f(c).either))

  /** Move the cursor left in a JSON array. */
  def left: ACursor =
    withHCursor(_.left)

  /** Move the cursor right in a JSON array. */
  def right: ACursor =
    withHCursor(_.right)

  /** Move the cursor to the first in a JSON array. */
  def first: ACursor =
    withHCursor(_.first)

  /** Move the cursor to the last in a JSON array. */
  def last: ACursor =
    withHCursor(_.last)

  /** Move the cursor left in a JSON array the given number of times. A negative value will move the cursor right (alias for `leftN`). */
  def -<-:(n: Int): ACursor =
    withHCursor(c => n -<-: c)

  /** Move the cursor left in a JSON array the given number of times. A negative value will move the cursor right (alias for `-<-:`). */
  def leftN(n: Int): ACursor =
    withHCursor(_.leftN(n))

  /** Move the cursor right in a JSON array the given number of times. A negative value will move the cursor left (alias for `rightN`). */
  def :->-(n: Int): ACursor =
    withHCursor(c => c :->- n)

  /** Move the cursor right in a JSON array the given number of times. A negative value will move the cursor left (alias for `:->-`). */
  def rightN(n: Int): ACursor =
    withHCursor(_.rightN(n))

  /** Move the cursor left in a JSON array until the given predicate matches the focus (alias for `leftAt`). */
  def ?<-:(p: Json => Boolean): ACursor =
    withHCursor(c => p ?<-: c)

  /** Move the cursor left in a JSON array until the given predicate matches the focus (alias for `?<-:`). */
  def leftAt(p: Json => Boolean): ACursor =
    withHCursor(_.leftAt(p))

  /** Move the cursor right in a JSON array until the given predicate matches the focus (alias for `rightAt`). */
  def :->?(p: Json => Boolean): ACursor =
    withHCursor(c => c :->? p)

  /** Move the cursor right in a JSON array until the given predicate matches the focus (alias for `:->?`). */
  def rightAt(p: Json => Boolean): ACursor =
    withHCursor(_.rightAt(p))

  /** Find the first element at or to the right of focus in a JSON array where the given predicate matches the focus. */
  def find(p: Json => Boolean): ACursor =
    withHCursor(_.find(p))

  /** Move the cursor to the given sibling field in a JSON object (alias for `field`). */
  def --(q: JsonField): ACursor =
    withHCursor(c => c -- q)

  /** Move the cursor to the given sibling field in a JSON object (alias for `--`). */
  def field(q: JsonField): ACursor =
    withHCursor(_.field(q))

  /** Move the cursor down to a JSON object at the given field (alias for `downField`). */
  def --\(q: JsonField): ACursor =
    withHCursor(c => c --\ q)

  /** Move the cursor down to a JSON object at the given field (alias for `--\`). */
  def downField(q: JsonField): ACursor =
    withHCursor(_.downField(q))

  /** Move the cursor down to a JSON array at the first element (alias for `\\`). */
  def downArray: ACursor =
    withHCursor(_.downArray)

  /** Move the cursor down to a JSON array at the first element (alias for `downArray`). */
  def \\ : ACursor =
    withHCursor(_.\\)

  /** Move the cursor down to a JSON array at the first element satisfying the given predicate (alias for `downAt`). */
  def -\(p: Json => Boolean): ACursor =
    withHCursor(c => c -\ p)

  /** Move the cursor down to a JSON array at the first element satisfying the given predicate (alias for `-\`). */
  def downAt(p: Json => Boolean): ACursor =
    withHCursor(_.downAt(p))

  /** Move the cursor down to a JSON array at the given index (alias for `downN`). */
  def =\(n: Int): ACursor =
    withHCursor(c => c =\ n)

  /** Move the cursor down to a JSON array at the given index (alias for `=\`). */
  def downN(n: Int): ACursor =
    withHCursor(_.downN(n))

  /** Deletes the JSON value at focus and moves up to parent (alias for `deleteGoParent`). */
  def delete : ACursor =
    withHCursor(_.delete)

  /** Deletes the JSON value at focus and moves up to parent (alias for `deleteGoParent`). */
  def unary_! : ACursor =
    withHCursor(_.unary_!)

  /** Deletes the JSON value at focus and moves up to parent (alias for `unary_!`). */
  def deleteGoParent: ACursor =
    withHCursor(_.deleteGoParent)

  /** Deletes the JSON value at focus and moves to the left in a JSON array. */
  def deleteGoLeft: ACursor =
    withHCursor(_.deleteGoLeft)

  /** Deletes the JSON value at focus and moves to the right in a JSON array. */
  def deleteGoRight: ACursor =
    withHCursor(_.deleteGoRight)

  /** Deletes the JSON value at focus and moves to the first in a JSON array. */
  def deleteGoFirst: ACursor =
    withHCursor(_.deleteGoFirst)

  /** Deletes the JSON value at focus and moves to the last in a JSON array. */
  def deleteGoLast: ACursor =
    withHCursor(_.deleteGoLast)

  /** Deletes the JSON value at focus and moves to the given sibling field in a JSON object. */
  def deleteGoField(q: JsonField): ACursor =
    withHCursor(_.deleteGoField(q))

  /** Deletes all JSON values to left of focus in a JSON array. */
  def deleteLefts: ACursor =
    withHCursor(_.deleteLefts)

  /** Deletes all JSON values to right of focus in a JSON array. */
  def deleteRights: ACursor =
    withHCursor(_.deleteRights)

  /** Set the values to the left of focus in a JSON array. */
  def setLefts(x: List[Json]): ACursor =
    withHCursor(_.setLefts(x))

  /** Set the values to the right of focus in a JSON array. */
  def setRights(x: List[Json]): ACursor =
    withHCursor(_.setRights(x))

  /** Move the cursor up one step to the parent context. */
  def up: ACursor =
    withHCursor(_.up)

  def |||(c: => ACursor): ACursor = {
    if(succeeded) this else c
  }

  /** Unapplies the cursor to the top-level parent (alias for `undo`). */
  def unary_- : Option[Json] =
    hcursor.map(_.undo)

  /** Unapplies the cursor to the top-level parent (alias for `unary_-`). */
  def undo: Option[Json] =
    hcursor.map(_.undo)
}

object ACursor extends ACursors {
  def ok(cursor: HCursor) =
    ACursor(Right(cursor))

  def fail(cursor: HCursor) =
    ACursor(Left(cursor))
}

trait ACursors {
  def okACursor(cursor: HCursor) =
    ACursor.ok(cursor)

  def failACursor(cursor: HCursor) =
    ACursor.fail(cursor)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy