qubit_metadata/
metadata_wire_decode_error.rs1use std::error::Error;
11use std::fmt;
12
13use qubit_budget::BudgetError;
14use qubit_budget::MeasuredBudgetError;
15use qubit_budget::QuantityConversionError;
16use qubit_budget::json::JsonResource;
17use qubit_json::decode::JsonDecodeError;
18use qubit_json::decode::JsonDecodeErrorSource;
19use qubit_json::decode::JsonSyntaxError;
20use serde::de::Error as DeError;
21
22use crate::MetadataError;
23
24#[derive(Debug)]
35#[non_exhaustive]
36#[must_use]
37pub enum MetadataWireDecodeError {
38 Domain(MetadataError),
41 UnsupportedVersion {
43 expected: u8,
45 actual: u8,
47 },
48 Budget(BudgetError<JsonResource, usize>),
50 Quantity {
53 resource: JsonResource,
55 source: QuantityConversionError,
58 },
59 Syntax(JsonSyntaxError),
61 InvalidLimits(serde_json::Error),
63 #[cfg(feature = "filter")]
65 Filter(MetadataError),
66 InvalidJson(
69 serde_json::Error,
71 ),
72}
73
74impl fmt::Display for MetadataWireDecodeError {
75 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 Self::Domain(error) => fmt::Display::fmt(error, formatter),
79 Self::UnsupportedVersion { expected, actual } => write!(
80 formatter,
81 "Unsupported metadata wire version {actual}; expected {expected}"
82 ),
83 Self::Budget(error) => fmt::Display::fmt(error, formatter),
84 Self::Quantity { source, .. } => fmt::Display::fmt(source, formatter),
85 Self::Syntax(error) => fmt::Display::fmt(error, formatter),
86 Self::InvalidLimits(error) => fmt::Display::fmt(error, formatter),
87 #[cfg(feature = "filter")]
88 Self::Filter(error) => fmt::Display::fmt(error, formatter),
89 Self::InvalidJson(error) => fmt::Display::fmt(error, formatter),
90 }
91 }
92}
93
94impl Error for MetadataWireDecodeError {
95 fn source(&self) -> Option<&(dyn Error + 'static)> {
97 match self {
98 Self::Domain(error) => Some(error),
99 Self::UnsupportedVersion { .. } => None,
100 Self::Budget(error) => Some(error),
101 Self::Quantity { source, .. } => Some(source),
102 Self::Syntax(error) => Some(error),
103 Self::InvalidLimits(error) => Some(error),
104 #[cfg(feature = "filter")]
105 Self::Filter(error) => Some(error),
106 Self::InvalidJson(error) => Some(error),
107 }
108 }
109}
110
111impl From<JsonDecodeError<JsonResource>> for MetadataWireDecodeError {
112 fn from(error: JsonDecodeError<JsonResource>) -> Self {
114 let kind = error.kind();
115 let line = error.line().unwrap_or(0);
116 let column = error.column().unwrap_or(0);
117 match error.into_source() {
118 JsonDecodeErrorSource::Budget { source, .. } => match source {
119 MeasuredBudgetError::Budget(error) => Self::Budget(error),
120 MeasuredBudgetError::Quantity { resource, source } => Self::Quantity { resource, source },
121 },
122 JsonDecodeErrorSource::InvalidJson { syntax, .. } => Self::Syntax(syntax),
123 JsonDecodeErrorSource::EmptyInput { .. }
124 | JsonDecodeErrorSource::InvalidUtf8 { .. }
125 | JsonDecodeErrorSource::UnexpectedTopLevel { .. }
126 | JsonDecodeErrorSource::Deserialize { .. } => Self::InvalidJson(<serde_json::Error as DeError>::custom(
127 format_args!("JSON decoding failed ({kind:?}) at line {line}, column {column}",),
128 )),
129 }
130 }
131}