#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ErrorClass {
Transport = 0x01,
Crypto = 0x02,
State = 0x03,
Policy = 0x04,
Schema = 0x05,
Authz = 0x06,
}
impl TryFrom<u8> for ErrorClass {
type Error = u8;
fn try_from(v: u8) -> Result<Self, u8> {
use ErrorClass::*;
Ok(match v {
0x01 => Transport,
0x02 => Crypto,
0x03 => State,
0x04 => Policy,
0x05 => Schema,
0x06 => Authz,
other => return Err(other),
})
}
}
pub mod codes {
pub const UNSUPPORTED_VERSION: u16 = 0x0001;
pub const UNKNOWN_GROUP: u16 = 0x0002;
pub const EPOCH_MISMATCH: u16 = 0x0003;
pub const TRANSITION_MISMATCH: u16 = 0x0004;
pub const REPLAY_DETECTED: u16 = 0x0005;
pub const DECRYPT_FAILED: u16 = 0x0006;
pub const COMMIT_INVALID: u16 = 0x0007;
pub const STREAM_POLICY_VIOLATION: u16 = 0x0008;
pub const TRANSITION_IN_PROGRESS: u16 = 0x0009;
pub const PREPARE_TIMEOUT: u16 = 0x0010;
pub const READY_TIMEOUT: u16 = 0x0011;
pub const EXECUTE_TIMEOUT: u16 = 0x0012;
pub const COORDINATOR_GONE: u16 = 0x0013;
pub const DIGEST_MISMATCH: u16 = 0x0014;
pub const GAP_BAD_SOURCE_ID: u16 = 0x1001;
pub const GAP_DECODE_FAILED: u16 = 0x1002;
pub const GAP_AUTH_FAILED: u16 = 0x1003;
pub const GAP_REPLAY_DETECTED: u16 = 0x1004;
pub const GAP_EPOCH_STALE: u16 = 0x1005;
pub const GAP_KEY_PHASE_UNKNOWN: u16 = 0x1006;
pub const GTP_BAD_LENGTH: u16 = 0x2001;
pub const GTP_UNSUPPORTED_CONTENT_TYPE: u16 = 0x2002;
pub const GTP_DUPLICATE_MESSAGE: u16 = 0x2003;
pub const GTP_POLICY_REJECTED: u16 = 0x2004;
pub const GTP_ATTACHMENT_INTEGRITY: u16 = 0x2005;
pub const GTP_REQUEST_TIMEOUT: u16 = 0x2006;
pub const GSP_BAD_SCHEMA: u16 = 0x3001;
pub const GSP_UNAUTHORIZED: u16 = 0x3002;
pub const GSP_UNKNOWN_SIGNAL: u16 = 0x3003;
pub const GSP_DUPLICATE_REQUEST: u16 = 0x3004;
pub const GSP_STATE_CONFLICT: u16 = 0x3005;
pub const GSP_PRECONDITION_FAILED: u16 = 0x3006;
}
#[derive(Copy, Clone, Debug)]
pub struct ErrorSpec {
pub code: u16,
pub class: ErrorClass,
pub retryable: bool,
pub fatal: bool,
pub name: &'static str,
}
impl ErrorSpec {
pub fn lookup(code: u16) -> Option<ErrorSpec> {
use codes::*;
Some(match code {
UNSUPPORTED_VERSION => spec(
code,
ErrorClass::Schema,
false,
true,
"ERR_UNSUPPORTED_VERSION",
),
UNKNOWN_GROUP => spec(code, ErrorClass::State, false, true, "ERR_UNKNOWN_GROUP"),
EPOCH_MISMATCH => spec(code, ErrorClass::State, true, false, "ERR_EPOCH_MISMATCH"),
TRANSITION_MISMATCH => spec(
code,
ErrorClass::State,
true,
false,
"ERR_TRANSITION_MISMATCH",
),
REPLAY_DETECTED => spec(
code,
ErrorClass::Crypto,
false,
false,
"ERR_REPLAY_DETECTED",
),
DECRYPT_FAILED => spec(code, ErrorClass::Crypto, true, false, "ERR_DECRYPT_FAILED"),
COMMIT_INVALID => spec(code, ErrorClass::Crypto, false, true, "ERR_COMMIT_INVALID"),
STREAM_POLICY_VIOLATION => spec(
code,
ErrorClass::Policy,
false,
false,
"ERR_STREAM_POLICY_VIOLATION",
),
TRANSITION_IN_PROGRESS => spec(
code,
ErrorClass::State,
false,
false,
"ERR_TRANSITION_IN_PROGRESS",
),
PREPARE_TIMEOUT => spec(code, ErrorClass::State, true, false, "ERR_PREPARE_TIMEOUT"),
READY_TIMEOUT => spec(code, ErrorClass::State, true, false, "ERR_READY_TIMEOUT"),
EXECUTE_TIMEOUT => spec(code, ErrorClass::State, true, false, "ERR_EXECUTE_TIMEOUT"),
COORDINATOR_GONE => spec(code, ErrorClass::State, true, false, "ERR_COORDINATOR_GONE"),
DIGEST_MISMATCH => spec(code, ErrorClass::State, false, true, "ERR_DIGEST_MISMATCH"),
GAP_BAD_SOURCE_ID => spec(
code,
ErrorClass::Schema,
false,
false,
"ERR_GAP_BAD_SOURCE_ID",
),
GAP_DECODE_FAILED => spec(
code,
ErrorClass::Schema,
false,
false,
"ERR_GAP_DECODE_FAILED",
),
GAP_AUTH_FAILED => spec(
code,
ErrorClass::Crypto,
false,
false,
"ERR_GAP_AUTH_FAILED",
),
GAP_REPLAY_DETECTED => spec(
code,
ErrorClass::Crypto,
false,
false,
"ERR_GAP_REPLAY_DETECTED",
),
GAP_EPOCH_STALE => spec(
code,
ErrorClass::Crypto,
false,
false,
"ERR_GAP_EPOCH_STALE",
),
GAP_KEY_PHASE_UNKNOWN => spec(
code,
ErrorClass::Crypto,
false,
false,
"ERR_GAP_KEY_PHASE_UNKNOWN",
),
GTP_BAD_LENGTH => spec(code, ErrorClass::Schema, false, false, "ERR_GTP_BAD_LENGTH"),
GTP_UNSUPPORTED_CONTENT_TYPE => spec(
code,
ErrorClass::Schema,
false,
false,
"ERR_GTP_UNSUPPORTED_CONTENT_TYPE",
),
GTP_DUPLICATE_MESSAGE => spec(
code,
ErrorClass::Policy,
false,
false,
"ERR_GTP_DUPLICATE_MESSAGE",
),
GTP_POLICY_REJECTED => spec(
code,
ErrorClass::Policy,
false,
false,
"ERR_GTP_POLICY_REJECTED",
),
GTP_ATTACHMENT_INTEGRITY => spec(
code,
ErrorClass::Schema,
false,
false,
"ERR_GTP_ATTACHMENT_INTEGRITY",
),
GTP_REQUEST_TIMEOUT => spec(
code,
ErrorClass::State,
true,
false,
"ERR_GTP_REQUEST_TIMEOUT",
),
GSP_BAD_SCHEMA => spec(code, ErrorClass::Schema, false, false, "ERR_GSP_BAD_SCHEMA"),
GSP_UNAUTHORIZED => spec(
code,
ErrorClass::Authz,
false,
false,
"ERR_GSP_UNAUTHORIZED",
),
GSP_UNKNOWN_SIGNAL => spec(
code,
ErrorClass::Schema,
false,
false,
"ERR_GSP_UNKNOWN_SIGNAL",
),
GSP_DUPLICATE_REQUEST => spec(
code,
ErrorClass::Policy,
false,
false,
"ERR_GSP_DUPLICATE_REQUEST",
),
GSP_STATE_CONFLICT => spec(
code,
ErrorClass::State,
true,
false,
"ERR_GSP_STATE_CONFLICT",
),
GSP_PRECONDITION_FAILED => spec(
code,
ErrorClass::State,
false,
false,
"ERR_GSP_PRECONDITION_FAILED",
),
_ => return None,
})
}
}
const fn spec(
code: u16,
class: ErrorClass,
retryable: bool,
fatal: bool,
name: &'static str,
) -> ErrorSpec {
ErrorSpec {
code,
class,
retryable,
fatal,
name,
}
}