use std::error::Error;
use std::fmt;
use qubit_budget::ResourceQuantity;
use qubit_budget::json::JsonResource;
use super::JsonDecodeContext;
use super::JsonDecodeError;
use super::JsonNumberTokenError;
use super::JsonValidatedLimit;
#[must_use]
#[non_exhaustive]
pub enum JsonValidatedDecodeError<E, R = JsonResource, Q = usize>
where
Q: ResourceQuantity,
{
Decode {
error: JsonDecodeError<R, Q>,
context: Option<JsonDecodeContext>,
},
Policy {
source: E,
offset: usize,
},
ExactSafeInteger {
source: JsonNumberTokenError,
offset: usize,
},
Limit {
limit: JsonValidatedLimit,
maximum: usize,
observed: usize,
offset: usize,
},
}
impl<E, R, Q> fmt::Debug for JsonValidatedDecodeError<E, R, Q>
where
R: fmt::Debug,
Q: ResourceQuantity,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Decode { error, context } => f
.debug_struct("Decode")
.field("error", error)
.field("context", context)
.finish(),
Self::Policy { offset, .. } => f.debug_struct("Policy").field("offset", offset).finish_non_exhaustive(),
Self::ExactSafeInteger { source, offset } => f
.debug_struct("ExactSafeInteger")
.field("source", source)
.field("offset", offset)
.finish(),
Self::Limit {
limit,
maximum,
observed,
offset,
} => f
.debug_struct("Limit")
.field("limit", limit)
.field("maximum", maximum)
.field("observed", observed)
.field("offset", offset)
.finish(),
}
}
}
impl<E, R, Q> fmt::Display for JsonValidatedDecodeError<E, R, Q>
where
R: fmt::Debug,
Q: ResourceQuantity,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Decode { error, context } => {
write!(f, "JSON decode failed ({context:?}): {error}")
}
Self::Policy { offset, .. } => {
write!(f, "JSON number policy rejected token at byte {offset}")
}
Self::ExactSafeInteger { source, offset } => {
write!(f, "exact safe integer conversion failed at byte {offset}: {source:?}")
}
Self::Limit {
limit,
maximum,
observed,
offset,
} => write!(
f,
"JSON limit {limit:?} exceeded at byte {offset}: maximum {maximum}, observed {observed}"
),
}
}
}
impl<E, R, Q> Error for JsonValidatedDecodeError<E, R, Q>
where
E: Error + 'static,
R: fmt::Debug + 'static,
Q: ResourceQuantity + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Decode { error, .. } => Some(error),
Self::Policy { source, .. } => Some(source),
Self::ExactSafeInteger { source, .. } => Some(source),
Self::Limit { .. } => None,
}
}
}