///|
/// Stable, documented reason codes used to classify the outcome of every
/// encoding, parsing and protocol step. Codes are permanent identifiers:
/// they never change meaning across releases, and new codes are only
/// appended. The full mapping is documented in `docs/REASON_CODES.md`.
pub(all) enum ReasonCode {
  /// Header field name is syntactically valid.
  MM_HEADER_001
  /// Header value contains CR/LF; rejected as injection (RFC 5322 3.6.8, 鎼?5).
  MM_HEADER_002
  /// Header value was folded at a whitespace boundary within 78 columns.
  MM_HEADER_003
  /// Header field name contains characters outside the RFC 5322 field-name set.
  MM_HEADER_004
  /// Address parsed as a valid addr-spec (RFC 5322 3.4.1).
  MM_ADDR_001
  /// Address rejected: missing `@` separating local-part and domain.
  MM_ADDR_002
  /// Address rejected: empty local-part.
  MM_ADDR_003
  /// Address rejected: empty domain.
  MM_ADDR_004
  /// Address rejected: illegal character in dot-atom local-part.
  MM_ADDR_005
  /// Address rejected: illegal character in domain.
  MM_ADDR_006
  /// Address rejected: quoted-string local-part not closed.
  MM_ADDR_007
  /// Address list split respecting quoted strings and groups.
  MM_ADDR_008
  /// QP encoder produced a soft line break at <= 76 characters.
  MM_ENCOD_001
  /// Base64 encoder produced lines of exactly 76 characters.
  MM_ENCOD_002
  /// 7bit body rejected: content contains bytes above 127.
  MM_ENCOD_003
  /// 8bit body accepted with a single trailing CRLF per line.
  MM_ENCOD_004
  /// Encoder produced a line longer than the configured limit.
  MM_ENCOD_005
  /// MIME boundary is unique within the message.
  MM_MIME_001
  /// MIME boundary does not collide with body content.
  MM_MIME_002
  /// MIME boundary uses only RFC 2046 boundary characters.
  MM_MIME_003
  /// Content-Type parsed into type/subtype plus parameters.
  MM_MIME_004
  /// Content-Type rejected: empty or malformed type.
  MM_MIME_005
  /// Content-Disposition built with sanitized filename.
  MM_MIME_006
  /// CRLF normalization: arbitrary newlines turned into CRLF.
  MM_CRLF_001
  /// dot-stuffing applied to a line starting with `.`.
  MM_DOT_001
  /// Header injection protection rejected a CR/LF in a header value.
  MM_INJ_001
  /// Header injection protection rejected a NUL byte.
  MM_INJ_002
  /// Filename sanitized for Content-Disposition.
  MM_INJ_003
  /// SMTP reply parsed: 3-digit code and optional enhanced code.
  MM_SMTP_001
  /// SMTP reply is multiline and was fully accumulated.
  MM_SMTP_002
  /// SMTP reply code classified (positive / transient / permanent).
  MM_SMTP_003
  /// EHLO capability advertised by the server.
  MM_SMTP_004
  /// MAIL FROM accepted.
  MM_SMTP_005
  /// RCPT TO accepted.
  MM_SMTP_006
  /// DATA accepted and message body transmitted.
  MM_SMTP_007
  /// CRAM-MD5 digest computed and verified.
  MM_AUTH_001
  /// AUTH LOGIN/PLAIN credential exchange completed.
  MM_AUTH_002
  /// Transport read/write performed.
  MM_TRANS_001
  /// FakeTransport scripted exchange performed deterministically.
  MM_TRANS_002
  /// Unclassified or generic outcome.
  Other
} derive(Eq, Debug)

///|
pub fn ReasonCode::to_string(self : ReasonCode) -> String {
  match self {
    MM_HEADER_001 => "MM_HEADER_001"
    MM_HEADER_002 => "MM_HEADER_002"
    MM_HEADER_003 => "MM_HEADER_003"
    MM_HEADER_004 => "MM_HEADER_004"
    MM_ADDR_001 => "MM_ADDR_001"
    MM_ADDR_002 => "MM_ADDR_002"
    MM_ADDR_003 => "MM_ADDR_003"
    MM_ADDR_004 => "MM_ADDR_004"
    MM_ADDR_005 => "MM_ADDR_005"
    MM_ADDR_006 => "MM_ADDR_006"
    MM_ADDR_007 => "MM_ADDR_007"
    MM_ADDR_008 => "MM_ADDR_008"
    MM_ENCOD_001 => "MM_ENCOD_001"
    MM_ENCOD_002 => "MM_ENCOD_002"
    MM_ENCOD_003 => "MM_ENCOD_003"
    MM_ENCOD_004 => "MM_ENCOD_004"
    MM_ENCOD_005 => "MM_ENCOD_005"
    MM_MIME_001 => "MM_MIME_001"
    MM_MIME_002 => "MM_MIME_002"
    MM_MIME_003 => "MM_MIME_003"
    MM_MIME_004 => "MM_MIME_004"
    MM_MIME_005 => "MM_MIME_005"
    MM_MIME_006 => "MM_MIME_006"
    MM_CRLF_001 => "MM_CRLF_001"
    MM_DOT_001 => "MM_DOT_001"
    MM_INJ_001 => "MM_INJ_001"
    MM_INJ_002 => "MM_INJ_002"
    MM_INJ_003 => "MM_INJ_003"
    MM_SMTP_001 => "MM_SMTP_001"
    MM_SMTP_002 => "MM_SMTP_002"
    MM_SMTP_003 => "MM_SMTP_003"
    MM_SMTP_004 => "MM_SMTP_004"
    MM_SMTP_005 => "MM_SMTP_005"
    MM_SMTP_006 => "MM_SMTP_006"
    MM_SMTP_007 => "MM_SMTP_007"
    MM_AUTH_001 => "MM_AUTH_001"
    MM_AUTH_002 => "MM_AUTH_002"
    MM_TRANS_001 => "MM_TRANS_001"
    MM_TRANS_002 => "MM_TRANS_002"
    Other => "OTHER"
  }
}

///|
pub impl Show for ReasonCode with fn output(self, logger) {
  logger.write_string(self.to_string())
}