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

scodec.Err.scala Maven / Gradle / Ivy

There is a newer version: 1.11.3
Show newest version
package scodec

/**
 * Describes an error.
 *
 * An error has a message and a list of context identifiers that provide insight into where an error occurs in a large structure.
 *
 * This type is not sealed so that codecs can return domain specific
 * subtypes and dispatch on those subtypes.
 */
trait Err {

  /** Gets a description of the error. */
  def message: String

  /**
   * Gets a stack of context identifiers.
   *
   * The head of the list is the outermost (i.e., least specific) identifier.
   */
  def context: List[String]

  /** Gets a description of the error with the context identifiers prefixing the message. */
  def messageWithContext: String =
    (if (context.isEmpty) "" else context.mkString("", "/", ": ")) + message

  /** Returns a new error with the specified context identifier pushed in to the context stack. */
  def pushContext(ctx: String): Err

  override def toString = messageWithContext
}

/** Companion for [[Err]]. */
object Err {

  final case class General(message: String, context: List[String]) extends Err {
    def this(message: String) = this(message, Nil)
    def pushContext(ctx: String) = copy(context = ctx :: context)
  }

  final case class InsufficientBits(needed: Long, have: Long, context: List[String]) extends Err {
    def this(needed: Long, have: Long) = this(needed, have, Nil)
    def message = s"cannot acquire $needed bits from a vector that contains $have bits"
    def pushContext(ctx: String) = copy(context = ctx :: context)
  }

  final case class MatchingDiscriminatorNotFound[A](a: A, context: List[String]) extends Err {
    def this(a: A) = this(a, Nil)
    def message = s"could not find matching case for $a"
    def pushContext(ctx: String) = copy(context = ctx :: context)
  }

  final case class Composite(errs: List[Err], context: List[String]) extends Err {
    def this(errs: List[Err]) = this(errs, Nil)
    def message: String = errs.map(_.message).mkString("composite errors (", ",", ")")
    def push(err: Err) = copy(errs = err :: errs)
    def pushContext(ctx: String): Err = copy(context = ctx :: context)
  }

  def apply(message: String): Err = new General(message)
  def apply(errs: List[Err]): Err = new Composite(errs)
  def insufficientBits(needed: Long, have: Long): Err = new InsufficientBits(needed, have)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy