datalogic_rs/error/
serde.rs1use super::Error;
6use super::kind::ErrorKind;
7use serde::ser::{Serialize, SerializeMap, Serializer};
8use std::fmt;
9
10impl fmt::Display for Error {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write_kind_message(f, &self.kind)?;
14 if let Some(op) = self.operator() {
15 write!(f, " (in operator: {})", op)?;
16 }
17 Ok(())
18 }
19}
20
21fn write_kind_message(f: &mut fmt::Formatter<'_>, kind: &ErrorKind) -> fmt::Result {
26 match kind {
27 ErrorKind::InvalidOperator(op) => write!(f, "Invalid operator: {}", op),
28 ErrorKind::InvalidArguments(msg) => write!(f, "Invalid arguments: {}", msg),
29 ErrorKind::VariableNotFound(var) => write!(f, "Variable not found: {}", var),
30 ErrorKind::InvalidContextLevel(level) => write!(f, "Invalid context level: {}", level),
31 ErrorKind::TypeError(msg) => write!(f, "Type error: {}", msg),
32 ErrorKind::ArithmeticError(msg) => write!(f, "Arithmetic error: {}", msg),
33 ErrorKind::Custom(err) => write!(f, "{}", err),
34 ErrorKind::ParseError(msg) => write!(f, "Parse error: {}", msg),
35 ErrorKind::Thrown(val) => {
36 #[cfg(feature = "serde_json")]
37 {
38 let json = crate::serde_bridge::owned_to_serde(val);
39 write!(f, "Thrown: {}", json)
40 }
41 #[cfg(not(feature = "serde_json"))]
42 {
43 write!(f, "Thrown: {:?}", val)
44 }
45 }
46 ErrorKind::FormatError(msg) => write!(f, "Format error: {}", msg),
47 ErrorKind::IndexOutOfBounds { index, length } => write!(
48 f,
49 "Index {} out of bounds for array of length {}",
50 index, length
51 ),
52 ErrorKind::ConfigurationError(msg) => write!(f, "Configuration error: {}", msg),
53 #[cfg(feature = "budget")]
54 ErrorKind::BudgetExceeded { budget, spent } => write!(
55 f,
56 "Operation budget exceeded: {} operations charged against a budget of {}",
57 spent, budget
58 ),
59 }
60}
61
62impl std::error::Error for Error {
63 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
86 match &self.kind {
87 ErrorKind::Custom(err) => Some(err.as_ref()),
88 _ => None,
89 }
90 }
91}
92
93#[cfg(feature = "serde_json")]
94#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
95impl From<serde_json::Error> for Error {
96 fn from(err: serde_json::Error) -> Self {
97 Error::parse_error(err.to_string())
98 }
99}
100
101impl From<datavalue::ParseError> for Error {
102 fn from(err: datavalue::ParseError) -> Self {
103 Error::parse_error(err.to_string())
104 }
105}
106
107impl From<ErrorKind> for Error {
108 #[inline]
109 fn from(kind: ErrorKind) -> Self {
110 Error::new(kind)
111 }
112}
113
114impl Serialize for Error {
115 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
116 let mut map = serializer.serialize_map(None)?;
119 map.serialize_entry("type", self.tag())?;
120 map.serialize_entry("message", &KindDisplay(&self.kind))?;
126 match &self.kind {
127 ErrorKind::VariableNotFound(name) => map.serialize_entry("variable", name)?,
128 ErrorKind::InvalidContextLevel(level) => map.serialize_entry("level", level)?,
129 ErrorKind::Thrown(value) => map.serialize_entry("thrown", value)?,
130 ErrorKind::IndexOutOfBounds { index, length } => {
131 map.serialize_entry("index", index)?;
132 map.serialize_entry("length", length)?;
133 }
134 #[cfg(feature = "budget")]
135 ErrorKind::BudgetExceeded { budget, spent } => {
136 map.serialize_entry("budget", budget)?;
137 map.serialize_entry("spent", spent)?;
138 }
139 _ => {}
140 }
141 if let Some(op) = self.operator() {
142 map.serialize_entry("operator", op)?;
143 }
144 let ids = self.node_ids();
145 if !ids.is_empty() {
146 map.serialize_entry("node_ids", ids)?;
147 }
148 map.end()
149 }
150}
151
152pub(crate) struct KindDisplay<'a>(pub(crate) &'a ErrorKind);
155
156impl<'a> fmt::Display for KindDisplay<'a> {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 write_kind_message(f, self.0)
159 }
160}
161
162impl Serialize for KindDisplay<'_> {
163 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
166 serializer.collect_str(self)
167 }
168}