///|
pub(all) enum TlvRange {
  Registered
  CustomRange
  ExperimentalRange
  FutureReservedRange
  UnknownRange
} derive(Eq, Debug)

///|
pub fn classify_tlv_range(type_code : Byte) -> TlvRange {
  let value = type_code.to_int()
  if value >= 0xe0 && value <= 0xef {
    CustomRange
  } else if value >= 0xf0 && value <= 0xf7 {
    ExperimentalRange
  } else if value >= 0xf8 {
    FutureReservedRange
  } else if is_registered_tlv(type_code) {
    Registered
  } else {
    UnknownRange
  }
}

///|
pub fn tlv_type_name(type_code : Byte) -> String {
  match type_code {
    TLV_ALPN => "ALPN"
    TLV_AUTHORITY => "AUTHORITY"
    TLV_CRC32C => "CRC32C"
    TLV_NOOP => "NOOP"
    TLV_UNIQUE_ID => "UNIQUE_ID"
    TLV_SSL => "SSL"
    TLV_SSL_VERSION => "SSL_VERSION"
    TLV_SSL_CN => "SSL_CN"
    TLV_SSL_CIPHER => "SSL_CIPHER"
    TLV_SSL_SIG_ALG => "SSL_SIG_ALG"
    TLV_SSL_KEY_ALG => "SSL_KEY_ALG"
    TLV_SSL_GROUP => "SSL_GROUP"
    TLV_SSL_SIG_SCHEME => "SSL_SIG_SCHEME"
    TLV_SSL_CLIENT_CERT => "SSL_CLIENT_CERT"
    TLV_NETNS => "NETNS"
    _ =>
      match classify_tlv_range(type_code) {
        CustomRange => "CUSTOM"
        ExperimentalRange => "EXPERIMENTAL"
        FutureReservedRange => "FUTURE_RESERVED"
        _ => "UNKNOWN"
      }
  }
}