1use std::error::Error as StdError;
2use std::fmt;
3use std::result;
4use std::sync::Arc;
5
6pub(crate) fn new_error(kind: ErrorKind) -> Error {
8 Error(Box::new(kind))
9}
10
11pub type Result<T> = result::Result<T, Error>;
13
14#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct Error(Box<ErrorKind>);
17
18impl Error {
19 pub fn kind(&self) -> &ErrorKind {
21 &self.0
22 }
23
24 pub fn into_kind(self) -> ErrorKind {
26 *self.0
27 }
28}
29
30#[non_exhaustive]
36#[derive(Clone, Debug)]
37pub enum ErrorKind {
38 InvalidToken,
40 InvalidSignature,
42 InvalidEcdsaKey,
44 InvalidEddsaKey,
46 InvalidRsaKey(String),
48 RsaFailedSigning,
50 InvalidAlgorithmName,
52 InvalidKeyFormat,
54
55 MissingRequiredClaim(String),
58 ExpiredSignature,
60 InvalidIssuer,
62 InvalidAudience,
64 InvalidSubject,
66 ImmatureSignature,
68 InvalidAlgorithm,
71 MissingAlgorithm,
73
74 Base64(base64::DecodeError),
77 Json(Arc<serde_json::Error>),
79 Utf8(::std::string::FromUtf8Error),
81}
82
83impl StdError for Error {
84 fn cause(&self) -> Option<&dyn StdError> {
85 match &*self.0 {
86 ErrorKind::InvalidToken => None,
87 ErrorKind::InvalidSignature => None,
88 ErrorKind::InvalidEcdsaKey => None,
89 ErrorKind::InvalidEddsaKey => None,
90 ErrorKind::RsaFailedSigning => None,
91 ErrorKind::InvalidRsaKey(_) => None,
92 ErrorKind::ExpiredSignature => None,
93 ErrorKind::MissingAlgorithm => None,
94 ErrorKind::MissingRequiredClaim(_) => None,
95 ErrorKind::InvalidIssuer => None,
96 ErrorKind::InvalidAudience => None,
97 ErrorKind::InvalidSubject => None,
98 ErrorKind::ImmatureSignature => None,
99 ErrorKind::InvalidAlgorithm => None,
100 ErrorKind::InvalidAlgorithmName => None,
101 ErrorKind::InvalidKeyFormat => None,
102 ErrorKind::Base64(err) => Some(err),
103 ErrorKind::Json(err) => Some(err.as_ref()),
104 ErrorKind::Utf8(err) => Some(err),
105 }
106 }
107}
108
109impl fmt::Display for Error {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111 match &*self.0 {
112 ErrorKind::InvalidToken
113 | ErrorKind::InvalidSignature
114 | ErrorKind::InvalidEcdsaKey
115 | ErrorKind::ExpiredSignature
116 | ErrorKind::RsaFailedSigning
117 | ErrorKind::MissingAlgorithm
118 | ErrorKind::InvalidIssuer
119 | ErrorKind::InvalidAudience
120 | ErrorKind::InvalidSubject
121 | ErrorKind::ImmatureSignature
122 | ErrorKind::InvalidAlgorithm
123 | ErrorKind::InvalidKeyFormat
124 | ErrorKind::InvalidEddsaKey
125 | ErrorKind::InvalidAlgorithmName => write!(f, "{:?}", self.0),
126 ErrorKind::MissingRequiredClaim(c) => write!(f, "Missing required claim: {}", c),
127 ErrorKind::InvalidRsaKey(msg) => write!(f, "RSA key invalid: {}", msg),
128 ErrorKind::Json(err) => write!(f, "JSON error: {}", err),
129 ErrorKind::Utf8(err) => write!(f, "UTF-8 error: {}", err),
130 ErrorKind::Base64(err) => write!(f, "Base64 error: {}", err),
131 }
132 }
133}
134
135impl PartialEq for ErrorKind {
136 fn eq(&self, other: &Self) -> bool {
137 format!("{:?}", self) == format!("{:?}", other)
138 }
139}
140
141impl Eq for ErrorKind {}
143
144impl From<base64::DecodeError> for Error {
145 fn from(err: base64::DecodeError) -> Error {
146 new_error(ErrorKind::Base64(err))
147 }
148}
149
150impl From<serde_json::Error> for Error {
151 fn from(err: serde_json::Error) -> Error {
152 new_error(ErrorKind::Json(Arc::new(err)))
153 }
154}
155
156impl From<::std::string::FromUtf8Error> for Error {
157 fn from(err: ::std::string::FromUtf8Error) -> Error {
158 new_error(ErrorKind::Utf8(err))
159 }
160}
161
162impl From<ErrorKind> for Error {
163 fn from(kind: ErrorKind) -> Error {
164 new_error(kind)
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use wasm_bindgen_test::wasm_bindgen_test;
171
172 use super::*;
173
174 #[test]
175 #[wasm_bindgen_test]
176 fn test_error_rendering() {
177 assert_eq!(
178 "InvalidAlgorithmName",
179 Error::from(ErrorKind::InvalidAlgorithmName).to_string()
180 );
181 }
182}