1use std::error::Error as StdError;
2use std::fmt;
3use std::result;
4
5pub(crate) fn new_error(kind: ErrorKind) -> Error {
7 Error(Box::new(kind))
8}
9
10pub type Result<T> = result::Result<T, Error>;
12
13#[derive(Debug)]
15pub struct Error(Box<ErrorKind>);
16
17impl Error {
18 pub fn kind(&self) -> &ErrorKind {
20 &self.0
21 }
22
23 pub fn into_kind(self) -> ErrorKind {
25 *self.0
26 }
27}
28
29#[derive(Debug)]
31pub enum ErrorKind {
32 InvalidToken,
34 InvalidSignature,
36 InvalidEcdsaKey,
38 InvalidRsaKey,
40 InvalidAlgorithmName,
42 InvalidKeyFormat,
44
45 ExpiredSignature,
48 InvalidIssuer,
50 InvalidAudience,
52 InvalidSubject,
54 ImmatureSignature,
56 InvalidAlgorithm,
59
60 Base64(base64::DecodeError),
63 Json(serde_json::Error),
65 Utf8(::std::string::FromUtf8Error),
67 Crypto(::ring::error::Unspecified),
69
70 #[doc(hidden)]
76 __Nonexhaustive,
77}
78
79impl StdError for Error {
80 fn cause(&self) -> Option<&dyn StdError> {
81 match *self.0 {
82 ErrorKind::InvalidToken => None,
83 ErrorKind::InvalidSignature => None,
84 ErrorKind::InvalidEcdsaKey => None,
85 ErrorKind::InvalidRsaKey => None,
86 ErrorKind::ExpiredSignature => None,
87 ErrorKind::InvalidIssuer => None,
88 ErrorKind::InvalidAudience => None,
89 ErrorKind::InvalidSubject => None,
90 ErrorKind::ImmatureSignature => None,
91 ErrorKind::InvalidAlgorithm => None,
92 ErrorKind::InvalidAlgorithmName => None,
93 ErrorKind::InvalidKeyFormat => None,
94 ErrorKind::Base64(ref err) => Some(err),
95 ErrorKind::Json(ref err) => Some(err),
96 ErrorKind::Utf8(ref err) => Some(err),
97 ErrorKind::Crypto(ref err) => Some(err),
98 ErrorKind::__Nonexhaustive => None,
99 }
100 }
101}
102
103impl fmt::Display for Error {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 match *self.0 {
106 ErrorKind::InvalidToken
107 | ErrorKind::InvalidSignature
108 | ErrorKind::InvalidEcdsaKey
109 | ErrorKind::InvalidRsaKey
110 | ErrorKind::ExpiredSignature
111 | ErrorKind::InvalidIssuer
112 | ErrorKind::InvalidAudience
113 | ErrorKind::InvalidSubject
114 | ErrorKind::ImmatureSignature
115 | ErrorKind::InvalidAlgorithm
116 | ErrorKind::InvalidKeyFormat
117 | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
118 ErrorKind::Json(ref err) => write!(f, "JSON error: {}", err),
119 ErrorKind::Utf8(ref err) => write!(f, "UTF-8 error: {}", err),
120 ErrorKind::Crypto(ref err) => write!(f, "Crypto error: {}", err),
121 ErrorKind::Base64(ref err) => write!(f, "Base64 error: {}", err),
122 ErrorKind::__Nonexhaustive => write!(f, "Unknown error"),
123 }
124 }
125}
126
127impl From<base64::DecodeError> for Error {
128 fn from(err: base64::DecodeError) -> Error {
129 new_error(ErrorKind::Base64(err))
130 }
131}
132
133impl From<serde_json::Error> for Error {
134 fn from(err: serde_json::Error) -> Error {
135 new_error(ErrorKind::Json(err))
136 }
137}
138
139impl From<::std::string::FromUtf8Error> for Error {
140 fn from(err: ::std::string::FromUtf8Error) -> Error {
141 new_error(ErrorKind::Utf8(err))
142 }
143}
144
145impl From<::ring::error::Unspecified> for Error {
146 fn from(err: ::ring::error::Unspecified) -> Error {
147 new_error(ErrorKind::Crypto(err))
148 }
149}
150
151impl From<::ring::error::KeyRejected> for Error {
152 fn from(_err: ::ring::error::KeyRejected) -> Error {
153 new_error(ErrorKind::InvalidEcdsaKey)
154 }
155}
156
157impl From<ErrorKind> for Error {
158 fn from(kind: ErrorKind) -> Error {
159 new_error(kind)
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn test_error_rendering() {
169 assert_eq!(
170 "InvalidAlgorithmName",
171 Error::from(ErrorKind::InvalidAlgorithmName).to_string()
172 );
173 }
174}