use std::error::Error;
use std::fmt;
use std::io;
use std::sync::Arc;
use qubit_budget::BudgetError;
use qubit_budget::MeasuredBudgetError;
use qubit_budget::QuantityConversionError;
use qubit_budget::json::JsonResource;
use qubit_json::decode::JsonDecodeError;
use qubit_json::decode::JsonDecodeErrorSource;
use qubit_json::decode::JsonSyntaxError;
use crate::MetadataError;
#[derive(Debug)]
#[non_exhaustive]
#[must_use]
pub enum MetadataWireDecodeError {
Read {
kind: io::ErrorKind,
source: Option<Arc<io::Error>>,
},
Domain(
MetadataError,
),
UnsupportedVersion {
expected: u8,
actual: u8,
},
Budget(
BudgetError<JsonResource, usize>,
),
Quantity {
resource: JsonResource,
source: QuantityConversionError,
},
Syntax(
JsonSyntaxError,
),
InvalidLimits(
serde_json::Error,
),
#[cfg(feature = "filter")]
Filter(
MetadataError,
),
InvalidJson(
serde_json::Error,
),
Decode(
JsonDecodeError<JsonResource>,
),
}
impl fmt::Display for MetadataWireDecodeError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Read { kind, .. } => {
write!(formatter, "Failed to read metadata JSON input: {kind:?}")
}
Self::Domain(error) => fmt::Display::fmt(error, formatter),
Self::UnsupportedVersion { expected, actual } => write!(
formatter,
"Unsupported metadata wire version {actual}; expected {expected}"
),
Self::Budget(error) => fmt::Display::fmt(error, formatter),
Self::Quantity { source, .. } => fmt::Display::fmt(source, formatter),
Self::Syntax(error) => fmt::Display::fmt(error, formatter),
Self::InvalidLimits(error) => fmt::Display::fmt(error, formatter),
#[cfg(feature = "filter")]
Self::Filter(error) => fmt::Display::fmt(error, formatter),
Self::InvalidJson(error) => fmt::Display::fmt(error, formatter),
Self::Decode(error) => fmt::Display::fmt(error, formatter),
}
}
}
impl Error for MetadataWireDecodeError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Read { source, .. } => source.as_deref().map(|error| error as &(dyn Error + 'static)),
Self::Domain(error) => Some(error),
Self::UnsupportedVersion { .. } => None,
Self::Budget(error) => Some(error),
Self::Quantity { source, .. } => Some(source),
Self::Syntax(error) => Some(error),
Self::InvalidLimits(error) => Some(error),
#[cfg(feature = "filter")]
Self::Filter(error) => Some(error),
Self::InvalidJson(error) => Some(error),
Self::Decode(error) => Some(error),
}
}
}
impl From<JsonDecodeError<JsonResource>> for MetadataWireDecodeError {
fn from(error: JsonDecodeError<JsonResource>) -> Self {
match error.clone().into_source() {
JsonDecodeErrorSource::Read { kind, source, .. } => Self::Read { kind, source },
JsonDecodeErrorSource::Budget { source, .. } => match source {
MeasuredBudgetError::Budget(error) => Self::Budget(error),
MeasuredBudgetError::Quantity { resource, source } => Self::Quantity { resource, source },
},
JsonDecodeErrorSource::InvalidJson { syntax, .. } => Self::Syntax(syntax),
_ => Self::Decode(error),
}
}
}