#[cfg(feature = "ciborium")]
use core::convert::Infallible;
use core::fmt;
use crate::alloc::String;
#[cfg(feature = "ciborium")]
pub(crate) type CborDeError<E = anyhow::Error> = ciborium::de::Error<E>;
#[cfg(feature = "ciborium")]
pub(crate) type CborSerError<E = Infallible> = ciborium::ser::Error<E>;
#[derive(Debug)]
#[non_exhaustive]
pub enum ParseError {
InvalidTokenStructure,
InvalidBase64Encoding,
MalformedHeader(serde_json::Error),
UnsupportedContentType(String),
}
impl fmt::Display for ParseError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidTokenStructure => formatter.write_str("invalid token structure"),
Self::InvalidBase64Encoding => write!(formatter, "invalid base64 decoding"),
Self::MalformedHeader(err) => write!(formatter, "malformed token header: {err}"),
Self::UnsupportedContentType(ty) => {
write!(formatter, "unsupported content type: {ty}")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::MalformedHeader(err) => Some(err),
_ => None,
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ValidationError {
AlgorithmMismatch {
expected: String,
actual: String,
},
InvalidSignatureLen {
expected: usize,
actual: usize,
},
MalformedSignature(anyhow::Error),
InvalidSignature,
MalformedClaims(serde_json::Error),
#[cfg(feature = "ciborium")]
#[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
MalformedCborClaims(CborDeError),
NoClaim(Claim),
Expired,
NotMature,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Claim {
Expiration,
NotBefore,
}
impl fmt::Display for Claim {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::Expiration => "exp",
Self::NotBefore => "nbf",
})
}
}
impl fmt::Display for ValidationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AlgorithmMismatch { expected, actual } => write!(
formatter,
"token algorithm ({actual}) differs from expected ({expected})"
),
Self::InvalidSignatureLen { expected, actual } => write!(
formatter,
"invalid signature length: expected {expected} bytes, got {actual} bytes"
),
Self::MalformedSignature(err) => write!(formatter, "malformed token signature: {err}"),
Self::InvalidSignature => formatter.write_str("signature has failed verification"),
Self::MalformedClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
#[cfg(feature = "ciborium")]
Self::MalformedCborClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
Self::NoClaim(claim) => write!(
formatter,
"claim `{claim}` requested during validation is not present in the token"
),
Self::Expired => formatter.write_str("token has expired"),
Self::NotMature => formatter.write_str("token is not yet ready"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ValidationError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::MalformedSignature(err) => Some(err.as_ref()),
Self::MalformedClaims(err) => Some(err),
#[cfg(feature = "ciborium")]
Self::MalformedCborClaims(err) => Some(err),
_ => None,
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum CreationError {
Header(serde_json::Error),
Claims(serde_json::Error),
#[cfg(feature = "ciborium")]
#[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
CborClaims(CborSerError),
}
impl fmt::Display for CreationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Header(err) => write!(formatter, "cannot serialize header: {err}"),
Self::Claims(err) => write!(formatter, "cannot serialize claims: {err}"),
#[cfg(feature = "ciborium")]
Self::CborClaims(err) => write!(formatter, "cannot serialize claims into CBOR: {err}"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for CreationError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Header(err) | Self::Claims(err) => Some(err),
#[cfg(feature = "ciborium")]
Self::CborClaims(err) => Some(err),
}
}
}