1#[cfg(feature = "ciborium")]
4use core::convert::Infallible;
5use core::fmt;
6
7use crate::alloc::String;
8
9#[cfg(feature = "ciborium")]
10pub(crate) type CborDeError<E = anyhow::Error> = ciborium::de::Error<E>;
11#[cfg(feature = "ciborium")]
12pub(crate) type CborSerError<E = Infallible> = ciborium::ser::Error<E>;
13
14#[derive(Debug)]
16#[non_exhaustive]
17pub enum ParseError {
18 InvalidTokenStructure,
23 InvalidBase64Encoding,
25 MalformedHeader(serde_json::Error),
27 UnsupportedContentType(String),
34}
35
36impl fmt::Display for ParseError {
37 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 Self::InvalidTokenStructure => formatter.write_str("invalid token structure"),
40 Self::InvalidBase64Encoding => write!(formatter, "invalid base64 decoding"),
41 Self::MalformedHeader(err) => write!(formatter, "malformed token header: {err}"),
42 Self::UnsupportedContentType(ty) => {
43 write!(formatter, "unsupported content type: {ty}")
44 }
45 }
46 }
47}
48
49#[cfg(feature = "std")]
50impl std::error::Error for ParseError {
51 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
52 match self {
53 Self::MalformedHeader(err) => Some(err),
54 _ => None,
55 }
56 }
57}
58
59#[derive(Debug)]
61#[non_exhaustive]
62pub enum ValidationError {
63 AlgorithmMismatch {
65 expected: String,
67 actual: String,
69 },
70 InvalidSignatureLen {
72 expected: usize,
74 actual: usize,
76 },
77 MalformedSignature(anyhow::Error),
79 InvalidSignature,
81 MalformedClaims(serde_json::Error),
83 #[cfg(feature = "ciborium")]
85 #[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
86 MalformedCborClaims(CborDeError),
87 NoClaim(Claim),
89 Expired,
91 NotMature,
93}
94
95#[derive(Debug, Clone, PartialEq, Eq)]
97#[non_exhaustive]
98pub enum Claim {
99 Expiration,
101 NotBefore,
103}
104
105impl fmt::Display for Claim {
106 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
107 formatter.write_str(match self {
108 Self::Expiration => "exp",
109 Self::NotBefore => "nbf",
110 })
111 }
112}
113
114impl fmt::Display for ValidationError {
115 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
116 match self {
117 Self::AlgorithmMismatch { expected, actual } => write!(
118 formatter,
119 "token algorithm ({actual}) differs from expected ({expected})"
120 ),
121 Self::InvalidSignatureLen { expected, actual } => write!(
122 formatter,
123 "invalid signature length: expected {expected} bytes, got {actual} bytes"
124 ),
125 Self::MalformedSignature(err) => write!(formatter, "malformed token signature: {err}"),
126 Self::InvalidSignature => formatter.write_str("signature has failed verification"),
127 Self::MalformedClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
128 #[cfg(feature = "ciborium")]
129 Self::MalformedCborClaims(err) => write!(formatter, "cannot deserialize claims: {err}"),
130 Self::NoClaim(claim) => write!(
131 formatter,
132 "claim `{claim}` requested during validation is not present in the token"
133 ),
134 Self::Expired => formatter.write_str("token has expired"),
135 Self::NotMature => formatter.write_str("token is not yet ready"),
136 }
137 }
138}
139
140#[cfg(feature = "std")]
141impl std::error::Error for ValidationError {
142 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
143 match self {
144 Self::MalformedSignature(err) => Some(err.as_ref()),
145 Self::MalformedClaims(err) => Some(err),
146 #[cfg(feature = "ciborium")]
147 Self::MalformedCborClaims(err) => Some(err),
148 _ => None,
149 }
150 }
151}
152
153#[derive(Debug)]
155#[non_exhaustive]
156pub enum CreationError {
157 Header(serde_json::Error),
159 Claims(serde_json::Error),
161 #[cfg(feature = "ciborium")]
163 #[cfg_attr(docsrs, doc(cfg(feature = "ciborium")))]
164 CborClaims(CborSerError),
165}
166
167impl fmt::Display for CreationError {
168 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
169 match self {
170 Self::Header(err) => write!(formatter, "cannot serialize header: {err}"),
171 Self::Claims(err) => write!(formatter, "cannot serialize claims: {err}"),
172 #[cfg(feature = "ciborium")]
173 Self::CborClaims(err) => write!(formatter, "cannot serialize claims into CBOR: {err}"),
174 }
175 }
176}
177
178#[cfg(feature = "std")]
179impl std::error::Error for CreationError {
180 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
181 match self {
182 Self::Header(err) | Self::Claims(err) => Some(err),
183 #[cfg(feature = "ciborium")]
184 Self::CborClaims(err) => Some(err),
185 }
186 }
187}