use std::error::Error as StdError;
use std::fmt;
#[derive(Debug)]
pub struct Error(Box<ErrorKind>);
pub(crate) fn new(kind: ErrorKind) -> Error {
Error(Box::new(kind))
}
#[derive(Debug)]
pub enum ErrorKind {
Serialize(serde_json::error::Error),
Encryption(nkeys::error::Error),
Decode(base64::DecodeError),
UTF8(std::string::FromUtf8Error),
Token(String),
InvalidCapability,
WasmElement(parity_wasm::elements::Error),
IO(std::io::Error),
InvalidModuleHash,
ExpiredToken,
TokenTooEarly,
InvalidAlgorithm,
}
impl Error {
pub fn kind(&self) -> &ErrorKind {
&self.0
}
pub fn into_kind(self) -> ErrorKind {
*self.0
}
}
impl StdError for Error {
fn description(&self) -> &str {
match *self.0 {
ErrorKind::Serialize(_) => "Serialization failure",
ErrorKind::Encryption(_) => "Encryption failure",
ErrorKind::Decode(_) => "Decode failure",
ErrorKind::UTF8(_) => "UTF8 failure",
ErrorKind::Token(_) => "JWT failure",
ErrorKind::InvalidCapability => "Invalid Capability",
ErrorKind::WasmElement(_) => "WebAssembly element",
ErrorKind::IO(_) => "I/O error",
ErrorKind::InvalidModuleHash => "Invalid Module Hash",
ErrorKind::ExpiredToken => "Token has expired",
ErrorKind::TokenTooEarly => "Token cannot be used yet",
ErrorKind::InvalidAlgorithm => "Invalid JWT algorithm",
}
}
fn cause(&self) -> Option<&dyn StdError> {
match *self.0 {
ErrorKind::Serialize(ref err) => Some(err),
ErrorKind::Encryption(ref err) => Some(err),
ErrorKind::Decode(ref err) => Some(err),
ErrorKind::UTF8(ref err) => Some(err),
ErrorKind::Token(_) => None,
ErrorKind::InvalidCapability => None,
ErrorKind::WasmElement(ref err) => Some(err),
ErrorKind::IO(ref err) => Some(err),
ErrorKind::InvalidModuleHash => None,
ErrorKind::ExpiredToken => None,
ErrorKind::TokenTooEarly => None,
ErrorKind::InvalidAlgorithm => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self.0 {
ErrorKind::Serialize(ref err) => write!(f, "Serialization error: {}", err),
ErrorKind::Encryption(ref err) => write!(f, "Encryption error: {}", err),
ErrorKind::Decode(ref err) => write!(f, "Decode error: {}", err),
ErrorKind::UTF8(ref err) => write!(f, "UTF8 error: {}", err),
ErrorKind::Token(ref err) => write!(f, "JWT error: {}", err),
ErrorKind::InvalidCapability => write!(f, "Invalid capability"),
ErrorKind::WasmElement(ref err) => write!(f, "Wasm Element error: {}", err),
ErrorKind::IO(ref err) => write!(f, "I/O error: {}", err),
ErrorKind::InvalidModuleHash => write!(f, "Invalid module hash"),
ErrorKind::ExpiredToken => write!(f, "Module token has expired"),
ErrorKind::TokenTooEarly => write!(f, "Module cannot be used yet"),
ErrorKind::InvalidAlgorithm => {
write!(f, "Invalid JWT algorithm. WASCAP only supports Ed25519")
}
}
}
}
impl From<std::io::Error> for Error {
fn from(source: std::io::Error) -> Error {
Error(Box::new(ErrorKind::IO(source)))
}
}
impl From<parity_wasm::elements::Error> for Error {
fn from(source: parity_wasm::elements::Error) -> Error {
Error(Box::new(ErrorKind::WasmElement(source)))
}
}
impl From<serde_json::error::Error> for Error {
fn from(source: serde_json::error::Error) -> Error {
Error(Box::new(ErrorKind::Serialize(source)))
}
}
impl From<base64::DecodeError> for Error {
fn from(source: base64::DecodeError) -> Error {
Error(Box::new(ErrorKind::Decode(source)))
}
}
impl From<nkeys::error::Error> for Error {
fn from(source: nkeys::error::Error) -> Error {
Error(Box::new(ErrorKind::Encryption(source)))
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(source: std::string::FromUtf8Error) -> Error {
Error(Box::new(ErrorKind::UTF8(source)))
}
}