///|
/// Errors raised while decoding ASN.1 DER/BER input.
///
/// The decoder only accepts the canonical forms allowed by the Distinguished
/// Encoding Rules (X.690): definite, minimal lengths and minimal
/// high-tag-number and subidentifier encodings. Anything else is reported
/// through one of these variants.
pub(all) suberror DerError {
  /// The input ended before a complete value could be read.
  UnexpectedEof
  /// The identifier octets are not a valid tag.
  InvalidTag(Int)
  /// BER indefinite-length encoding (`0x80`) is not allowed in DER.
  IndefiniteLength
  /// A declared length is larger than the remaining input.
  Truncated(Int)
  /// The length field uses more octets than supported (at most four).
  LengthTooLong(Int)
  /// The length is not encoded using the minimal number of octets.
  NonMinimalLength(Int)
  /// A value carried a different tag than the caller expected.
  ExpectedTag(String, String)
  /// The content octets are not valid for the declared type.
  InvalidValue(String)
  /// Bytes remained after the requested value was decoded.
  TrailingData(Int)
} derive(@debug.Debug)

///|
/// Renders the error as a human readable message.
pub fn DerError::to_string(self : DerError) -> String {
  match self {
    UnexpectedEof => "unexpected end of input"
    InvalidTag(byte) => "invalid tag octet " + byte.to_string()
    IndefiniteLength => "indefinite length is not allowed in DER"
    Truncated(length) =>
      "declared length " + length.to_string() + " exceeds the input"
    LengthTooLong(count) =>
      "length uses " + count.to_string() + " octets, at most four are supported"
    NonMinimalLength(length) =>
      "length " + length.to_string() + " is not minimally encoded"
    ExpectedTag(expected, actual) => "expected " + expected + ", got " + actual
    InvalidValue(message) => message
    TrailingData(count) =>
      count.to_string() + " trailing octets after the value"
  }
}