Skip to content

Commit

Permalink
Turn KeyDecodingError enum into struct with source err as trait object
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Stas <patrik.stas@absa.africa>
  • Loading branch information
Patrik-Stas committed Jan 11, 2024
1 parent cbb6fef commit b70fb26
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 43 deletions.
2 changes: 1 addition & 1 deletion did_core/did_doc/src/schema/types/jsonwebkey.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
collections::HashMap,
error::Error,
fmt::{self, Display, Formatter},
str::FromStr,
};
use std::error::Error;

use serde::{Deserialize, Serialize};
use serde_json::Value;
Expand Down
90 changes: 67 additions & 23 deletions did_core/did_doc/src/schema/verification_method/error.rs
Original file line number Diff line number Diff line change
@@ -1,48 +1,92 @@
use std::{
error::Error,
fmt,
fmt::{Display, Formatter},
};

use thiserror::Error;
use crate::schema::types::jsonwebkey::JsonWebKeyError;

use crate::schema::types::multibase::MultibaseWrapperError;
use crate::schema::types::{jsonwebkey::JsonWebKeyError, multibase::MultibaseWrapperError};

#[derive(Debug, Error)]
pub enum KeyDecodingError {
#[error("Json decoding error: ${0}")]
JsonError(serde_json::Error),
#[error("Pem decoding error: ${0}")]
PemError(pem::PemError),
#[error("Unsupported key error: ${0}")]
UnsupportedPublicKeyField(&'static str),
#[error("Base 58 decoding error: ${0}")]
Base58DecodeError(bs58::decode::Error),
#[error("Base 64 decoding error: ${0}")]
Base64DecodeError(base64::DecodeError),
#[error("Hex decoding error: ${0}")]
HexDecodeError(hex::FromHexError),
#[error("Jwk decoding error: ${0}")]
JwkDecodeError(JsonWebKeyError),
#[error("Multibase decoding error ${0}")]
MultibaseError(MultibaseWrapperError),
pub struct KeyDecodingError {
reason: &'static str,
#[source]
source: Option<Box<dyn Error + Sync + Send>>,
}

impl KeyDecodingError {
pub fn new(reason: &'static str) -> Self {
KeyDecodingError {
reason,
source: None,
}
}
}

impl Display for KeyDecodingError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match &self.source {
Some(source) => write!(
f,
"KeyDecodingError, reason: {}, source: {}",
self.reason, source
),
None => write!(f, "KeyDecodingError, reason: {}", self.reason),
}
}
}

impl From<pem::PemError> for KeyDecodingError {
fn from(error: pem::PemError) -> Self {
KeyDecodingError::PemError(error)
KeyDecodingError {
reason: "Failed to decode PEM",
source: Some(Box::new(error)),
}
}
}

impl From<bs58::decode::Error> for KeyDecodingError {
fn from(error: bs58::decode::Error) -> Self {
KeyDecodingError::Base58DecodeError(error)
KeyDecodingError {
reason: "Failed to decode base58",
source: Some(Box::new(error)),
}
}
}

impl From<base64::DecodeError> for KeyDecodingError {
fn from(error: base64::DecodeError) -> Self {
KeyDecodingError::Base64DecodeError(error)
KeyDecodingError {
reason: "Failed to decode base64",
source: Some(Box::new(error)),
}
}
}

impl From<hex::FromHexError> for KeyDecodingError {
fn from(error: hex::FromHexError) -> Self {
KeyDecodingError::HexDecodeError(error)
KeyDecodingError {
reason: "Failed to decode hex value",
source: Some(Box::new(error)),
}
}
}

impl From<MultibaseWrapperError> for KeyDecodingError {
fn from(error: MultibaseWrapperError) -> Self {
KeyDecodingError {
reason: "Failed to decode multibase value",
source: Some(Box::new(error)),
}
}
}

impl From<JsonWebKeyError> for KeyDecodingError {
fn from(error: JsonWebKeyError) -> Self {
KeyDecodingError {
reason: "Failed to decode JWK",
source: Some(Box::new(error)),
}
}
}
39 changes: 20 additions & 19 deletions did_core/did_doc/src/schema/verification_method/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,10 @@ impl PublicKeyField {
PublicKeyField::Multibase {
public_key_multibase,
} => {
let multibase = Multibase::from_str(public_key_multibase)
.map_err(KeyDecodingError::MultibaseError)?;
let multibase = Multibase::from_str(public_key_multibase)?;
Ok(multibase.as_ref().to_vec())
}
PublicKeyField::Jwk { public_key_jwk } => Ok(public_key_jwk
.to_vec()
.map_err(KeyDecodingError::JwkDecodeError)?),
PublicKeyField::Jwk { public_key_jwk } => Ok(public_key_jwk.to_vec()?),
PublicKeyField::Base58 { public_key_base58 } => {
Ok(bs58::decode(public_key_base58).into_vec()?)
}
Expand All @@ -51,9 +48,9 @@ impl PublicKeyField {
PublicKeyField::Pem { public_key_pem } => {
Ok(pem::parse(public_key_pem.as_bytes())?.contents().to_vec())
}
PublicKeyField::Pgp { public_key_pgp: _ } => {
Err(KeyDecodingError::UnsupportedPublicKeyField("publicKeyPgp"))
}
PublicKeyField::Pgp { public_key_pgp: _ } => Err(KeyDecodingError::new(
"PGP public key decoding not supported",
)),
}
}

Expand All @@ -65,6 +62,8 @@ impl PublicKeyField {

#[cfg(test)]
mod tests {
use std::error::Error;

use super::*;

static PUBLIC_KEY_MULTIBASE: &str = "z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc";
Expand Down Expand Up @@ -124,12 +123,13 @@ mod tests {
let public_key_field = PublicKeyField::Base58 {
public_key_base58: "abcdefghijkl".to_string(),
};
let err = public_key_field.key_decoded().unwrap_err();
assert!(
matches!(err, KeyDecodingError::Base58DecodeError(_)),
"Expected Base58DecodeError, got {:?}",
err
);
let err = public_key_field.key_decoded().expect_err("Expected error");
println!("Error: {}", err);
assert!(err
.source()
.expect("Error was expected to has source set up.")
.is::<bs58::decode::Error>());
assert!(err.to_string().contains("Failed to decode base58"));
}

#[test]
Expand All @@ -138,10 +138,11 @@ mod tests {
public_key_pem: "abcdefghijkl".to_string(),
};
let err = public_key_field.key_decoded().unwrap_err();
assert!(
matches!(err, KeyDecodingError::PemError(_)),
"Expected PemError, got {:?}",
err
);
println!("Error: {}", err);
assert!(err
.source()
.expect("Error was expected to has source set up.")
.is::<pem::PemError>());
assert!(err.to_string().contains("Failed to decode PEM"));
}
}

0 comments on commit b70fb26

Please sign in to comment.