edgefirst_decoder/
error.rs1use core::fmt;
7
8pub type DecoderResult<T, E = DecoderError> = std::result::Result<T, E>;
10
11#[derive(Debug)]
12pub enum DecoderError {
13 Internal(String),
15 NotSupported(String),
17 InvalidShape(String),
19 Yaml(serde_yaml::Error),
21 Json(serde_json::Error),
23 NoConfig,
25 InvalidConfig(String),
27 NDArrayShape(ndarray::ShapeError),
29 DtypeMismatch {
31 expected: edgefirst_tensor::DType,
32 actual: edgefirst_tensor::DType,
33 role: &'static str,
34 level: usize,
35 },
36 QuantMissing {
41 dtype: edgefirst_tensor::DType,
42 role: &'static str,
43 level: usize,
44 },
45 KernelDispatchUnreachable(String),
49 ForcedKernelUnavailable {
52 tier: &'static str,
53 missing_feature: &'static str,
54 },
55 Tensor(edgefirst_tensor::Error),
58}
59
60impl fmt::Display for DecoderError {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 DecoderError::Tensor(e) => write!(f, "Tensor({e})"),
75 _ => write!(f, "{self:?}"),
76 }
77 }
78}
79
80impl std::error::Error for DecoderError {}
81
82impl DecoderError {
83 pub fn cpu_access_denied(&self) -> Option<&edgefirst_tensor::Error> {
86 match self {
87 DecoderError::Tensor(e) => e.cpu_access_denied(),
88 _ => None,
89 }
90 }
91
92 pub(crate) fn from_map(
95 e: edgefirst_tensor::Error,
96 other: impl FnOnce(edgefirst_tensor::Error) -> DecoderError,
97 ) -> DecoderError {
98 match e {
99 e @ edgefirst_tensor::Error::CpuAccessDenied { .. } => DecoderError::Tensor(e),
100 e => other(e),
101 }
102 }
103}
104
105impl From<edgefirst_tensor::Error> for DecoderError {
106 fn from(err: edgefirst_tensor::Error) -> Self {
107 DecoderError::Tensor(err)
108 }
109}
110
111impl From<serde_yaml::Error> for DecoderError {
112 fn from(err: serde_yaml::Error) -> Self {
113 DecoderError::Yaml(err)
114 }
115}
116
117impl From<serde_json::Error> for DecoderError {
118 fn from(err: serde_json::Error) -> Self {
119 DecoderError::Json(err)
120 }
121}
122
123impl From<ndarray::ShapeError> for DecoderError {
124 fn from(err: ndarray::ShapeError) -> Self {
125 DecoderError::NDArrayShape(err)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_decoder_error_display() {
135 let e = DecoderError::Internal("something broke".to_string());
136 let msg = e.to_string();
137 assert!(!msg.is_empty());
138 assert!(
139 msg.contains("Internal") && msg.contains("something broke"),
140 "unexpected Internal message: {msg}"
141 );
142
143 let e = DecoderError::NotSupported("yolov99".to_string());
144 let msg = e.to_string();
145 assert!(!msg.is_empty());
146 assert!(
147 msg.contains("NotSupported") && msg.contains("yolov99"),
148 "unexpected NotSupported message: {msg}"
149 );
150
151 let e = DecoderError::InvalidShape("expected 3D".to_string());
152 let msg = e.to_string();
153 assert!(!msg.is_empty());
154 assert!(
155 msg.contains("InvalidShape") && msg.contains("expected 3D"),
156 "unexpected InvalidShape message: {msg}"
157 );
158
159 let e = DecoderError::NoConfig;
160 let msg = e.to_string();
161 assert!(!msg.is_empty());
162 assert!(
163 msg.contains("NoConfig"),
164 "unexpected NoConfig message: {msg}"
165 );
166
167 let e = DecoderError::InvalidConfig("missing field".to_string());
168 let msg = e.to_string();
169 assert!(!msg.is_empty());
170 assert!(
171 msg.contains("InvalidConfig") && msg.contains("missing field"),
172 "unexpected InvalidConfig message: {msg}"
173 );
174 }
175}