qubit_value/value_wire/
value_wire_decode_error.rs1use qubit_budget::BudgetError;
13use qubit_budget::MeasuredBudgetError;
14use qubit_budget::QuantityConversionError;
15use qubit_budget::json::JsonResource;
16use qubit_json::decode::JsonDecodeError;
17use qubit_json::decode::JsonDecodeErrorSource;
18use qubit_json::decode::JsonSyntaxError;
19use serde_json::Error as JsonError;
20use serde_json::error::Category;
21use thiserror::Error;
22
23#[non_exhaustive]
37#[must_use]
38#[derive(Debug, Error)]
39pub enum ValueWireDecodeError {
40 #[error("V1 JSON wire resource budget exceeded: {0}")]
42 Budget(
43 #[source]
45 BudgetError<JsonResource, usize>,
46 ),
47
48 #[error("V1 JSON wire resource quantity conversion failed for {resource:?}: {source}")]
51 Quantity {
52 resource: JsonResource,
54 #[source]
56 source: QuantityConversionError,
57 },
58
59 #[error("invalid V1 JSON wire syntax: {0}")]
61 Syntax(
62 #[source]
64 JsonSyntaxError,
65 ),
66
67 #[error("unsupported qubit-value wire version {actual}; expected {expected}")]
69 UnsupportedVersion {
70 expected: u8,
72
73 actual: u8,
75 },
76
77 #[error("failed to decode V1 JSON wire input: {0}")]
79 InvalidJson(
80 #[source]
82 JsonError,
83 ),
84}
85
86impl ValueWireDecodeError {
87 fn deserialize(category: Category, line: usize, column: usize) -> Self {
99 let error = <JsonError as serde::de::Error>::custom(format_args!(
100 "JSON deserialization failed ({category:?}) at line {line}, column {column}"
101 ));
102 Self::InvalidJson(error)
103 }
104}
105
106impl From<JsonDecodeError<JsonResource, usize>> for ValueWireDecodeError {
107 #[inline]
108 fn from(error: JsonDecodeError<JsonResource>) -> Self {
109 let line = error.line().unwrap_or(0);
110 let column = error.column().unwrap_or(0);
111 match error.into_source() {
112 JsonDecodeErrorSource::Budget { source, .. } => match source {
113 MeasuredBudgetError::Budget(error) => Self::Budget(error),
114 MeasuredBudgetError::Quantity { resource, source } => Self::Quantity { resource, source },
115 },
116 JsonDecodeErrorSource::InvalidJson { syntax, .. } => Self::Syntax(syntax),
117 JsonDecodeErrorSource::EmptyInput { .. }
118 | JsonDecodeErrorSource::InvalidUtf8 { .. }
119 | JsonDecodeErrorSource::UnexpectedTopLevel { .. }
120 | JsonDecodeErrorSource::Deserialize { .. } => Self::deserialize(Category::Data, line, column),
121 }
122 }
123}
124
125impl From<JsonError> for ValueWireDecodeError {
126 #[inline]
127 fn from(error: JsonError) -> Self {
128 let category = error.classify();
129 let line = error.line();
130 let column = error.column();
131 Self::deserialize(category, line, column)
132 }
133}