///|
pub fn ParseError::kind(self : ParseError) -> String {
  match self {
    UnexpectedEnd(_) => "unexpected-end"
    UnexpectedCharacter(_, _) => "unexpected-character"
    Expected(_, _) => "expected"
    InvalidEscape(_, _) => "invalid-escape"
    InvalidNumber(_, _) => "invalid-number"
    DuplicateKey(_, _) => "duplicate-key"
    TrailingContent(_) => "trailing-content"
  }
}

///|
pub fn ParseError::to_json(self : ParseError) -> String {
  let location = match self {
    UnexpectedEnd(position) => position
    UnexpectedCharacter(position, _) => position
    Expected(position, _) => position
    InvalidEscape(position, _) => position
    InvalidNumber(position, _) => position
    DuplicateKey(position, _) => position
    TrailingContent(position) => position
  }
  "{\"kind\":" +
  canonical_string(self.kind()) +
  ",\"position\":" +
  location.to_string() +
  ",\"message\":" +
  canonical_string(self.message()) +
  "}"
}

///|
pub fn CanonicalError::kind(self : CanonicalError) -> String {
  match self {
    InvalidNumber(_, _) => "invalid-number"
    NonFiniteNumber(_) => "non-finite-number"
  }
}

///|
pub fn CanonicalError::to_json(self : CanonicalError) -> String {
  "{\"kind\":" +
  canonical_string(self.kind()) +
  ",\"message\":" +
  canonical_string(self.message()) +
  "}"
}

///|
pub fn LimitViolation::to_json(self : LimitViolation) -> String {
  "{\"message\":" + canonical_string(self.message()) + "}"
}

///|
pub fn DocumentLimits::to_json(self : DocumentLimits) -> String {
  "{\"max_depth\":" +
  self.max_depth.to_string() +
  ",\"max_values\":" +
  self.max_values.to_string() +
  ",\"max_array_length\":" +
  self.max_array_length.to_string() +
  ",\"max_object_members\":" +
  self.max_object_members.to_string() +
  ",\"max_string_length\":" +
  self.max_string_length.to_string() +
  ",\"max_number_length\":" +
  self.max_number_length.to_string() +
  "}"
}