1use std::{
2 convert::TryFrom,
3 fmt::{self, Display, Formatter},
4};
5
6#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, failure_derive::Fail)]
7#[allow(missing_docs)]
8pub enum InternalError {
9 NoMemory,
10 InvalidArgument,
11 Unknown,
12 DuplicateMessage,
13 InvalidKey,
14 InvalidKeyId,
15 InvalidMAC,
16 InvalidMessage,
17 InvalidVersion,
18 LegacyMessage,
19 NoSession,
20 StaleKeyExchange,
21 UntrustedIdentity,
22 VerifySignatureVerificationFailed,
23 InvalidProtoBuf,
24 FPVersionMismatch,
25 FPIdentMismatch,
26 Other(i32),
27}
28
29impl InternalError {
30 pub fn from_error_code(code: i32) -> Option<InternalError> {
32 match code {
33 sys::SG_ERR_NOMEM => Some(InternalError::NoMemory),
34 sys::SG_ERR_INVAL => Some(InternalError::InvalidArgument),
35 sys::SG_ERR_UNKNOWN => Some(InternalError::Unknown),
36 sys::SG_ERR_DUPLICATE_MESSAGE => {
37 Some(InternalError::DuplicateMessage)
38 },
39 sys::SG_ERR_INVALID_KEY => Some(InternalError::InvalidKey),
40 sys::SG_ERR_INVALID_KEY_ID => Some(InternalError::InvalidKeyId),
41 sys::SG_ERR_INVALID_MAC => Some(InternalError::InvalidMAC),
42 sys::SG_ERR_INVALID_MESSAGE => Some(InternalError::InvalidMessage),
43 sys::SG_ERR_INVALID_VERSION => Some(InternalError::InvalidVersion),
44 sys::SG_ERR_LEGACY_MESSAGE => Some(InternalError::LegacyMessage),
45 sys::SG_ERR_NO_SESSION => Some(InternalError::NoSession),
46 sys::SG_ERR_STALE_KEY_EXCHANGE => {
47 Some(InternalError::StaleKeyExchange)
48 },
49 sys::SG_ERR_UNTRUSTED_IDENTITY => {
50 Some(InternalError::UntrustedIdentity)
51 },
52 sys::SG_ERR_VRF_SIG_VERIF_FAILED => {
53 Some(InternalError::VerifySignatureVerificationFailed)
54 },
55 sys::SG_ERR_INVALID_PROTO_BUF => {
56 Some(InternalError::InvalidProtoBuf)
57 },
58 sys::SG_ERR_FP_VERSION_MISMATCH => {
59 Some(InternalError::FPVersionMismatch)
60 },
61 sys::SG_ERR_FP_IDENT_MISMATCH => {
62 Some(InternalError::FPIdentMismatch)
63 },
64 _ => None,
65 }
66 }
67
68 pub fn code(self) -> i32 {
70 match self {
71 InternalError::NoMemory => sys::SG_ERR_NOMEM,
72 InternalError::InvalidArgument => sys::SG_ERR_INVAL,
73 InternalError::Unknown => sys::SG_ERR_UNKNOWN,
74 InternalError::DuplicateMessage => sys::SG_ERR_DUPLICATE_MESSAGE,
75 InternalError::InvalidKey => sys::SG_ERR_INVALID_KEY,
76 InternalError::InvalidKeyId => sys::SG_ERR_INVALID_KEY_ID,
77 InternalError::InvalidMAC => sys::SG_ERR_INVALID_MAC,
78 InternalError::InvalidMessage => sys::SG_ERR_INVALID_MESSAGE,
79 InternalError::InvalidVersion => sys::SG_ERR_INVALID_VERSION,
80 InternalError::LegacyMessage => sys::SG_ERR_LEGACY_MESSAGE,
81 InternalError::NoSession => sys::SG_ERR_NO_SESSION,
82 InternalError::StaleKeyExchange => sys::SG_ERR_STALE_KEY_EXCHANGE,
83 InternalError::UntrustedIdentity => sys::SG_ERR_UNTRUSTED_IDENTITY,
84 InternalError::VerifySignatureVerificationFailed => {
85 sys::SG_ERR_VRF_SIG_VERIF_FAILED
86 },
87 InternalError::InvalidProtoBuf => sys::SG_ERR_INVALID_PROTO_BUF,
88 InternalError::FPVersionMismatch => sys::SG_ERR_FP_VERSION_MISMATCH,
89 InternalError::FPIdentMismatch => sys::SG_ERR_FP_IDENT_MISMATCH,
90 InternalError::Other(c) => c,
91 }
92 }
93}
94
95pub trait FromInternalErrorCode: Sized {
97 fn into_result(self) -> Result<(), InternalError>;
99}
100
101pub trait IntoInternalErrorCode: Sized {
103 fn into_code(self) -> i32;
105}
106
107impl FromInternalErrorCode for isize {
108 fn into_result(self) -> Result<(), InternalError> {
109 i32::try_from(self).expect("Overflow").into_result()
110 }
111}
112
113impl FromInternalErrorCode for i32 {
114 fn into_result(self) -> Result<(), InternalError> {
115 if self == 0 {
116 return Ok(());
117 }
118
119 match InternalError::from_error_code(self) {
120 None => Err(InternalError::Other(self)),
121 Some(e) => Err(e),
122 }
123 }
124}
125
126impl<T> IntoInternalErrorCode for Result<T, InternalError> {
127 fn into_code(self) -> i32 {
128 match self {
129 Ok(_) => 0,
130 Err(e) => e.code(),
131 }
132 }
133}
134
135impl From<InternalError> for i32 {
136 fn from(other: InternalError) -> i32 { other.code() }
137}
138
139impl Display for InternalError {
140 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
141 match self {
142 InternalError::NoMemory => write!(f, "No Memory"),
143 InternalError::InvalidArgument => write!(f, "Invalid argument"),
144 InternalError::Unknown => write!(f, "Unknown error"),
145 InternalError::DuplicateMessage => write!(f, "Duplicate message"),
146 InternalError::InvalidKey => write!(f, "Invalid key"),
147 InternalError::InvalidKeyId => write!(f, "Invalid key ID"),
148 InternalError::InvalidMAC => write!(f, "Invalid MAC"),
149 InternalError::InvalidMessage => write!(f, "Invalid message"),
150 InternalError::InvalidVersion => write!(f, "Invalid version"),
151 InternalError::LegacyMessage => write!(f, "Legacy message"),
152 InternalError::NoSession => write!(f, "No session"),
153 InternalError::StaleKeyExchange => write!(f, "Stale key exchange"),
154 InternalError::UntrustedIdentity => write!(f, "Untrusted identity"),
155 InternalError::VerifySignatureVerificationFailed => {
156 write!(f, "Verifying signature failed")
157 },
158 InternalError::InvalidProtoBuf => write!(f, "Invalid protobuf"),
159 InternalError::FPVersionMismatch => {
160 write!(f, "FP version mismatched")
161 },
162 InternalError::FPIdentMismatch => write!(f, "FP ident mismatched"),
163 InternalError::Other(code) => write!(f, "Unknown error {}", code),
164 }
165 }
166}