edgefirst_tensor/
error.rs1pub type Result<T, E = Error> = std::result::Result<T, E>;
5
6#[derive(Debug)]
7pub enum Error {
8 IoError(std::io::Error),
9 #[cfg(unix)]
10 NixError(nix::Error),
11 NotImplemented(String),
12 InvalidSize(usize),
13 ShapeMismatch(String),
14 #[cfg(target_os = "linux")]
15 UnknownDeviceType(u64, u64),
16 #[cfg(target_os = "linux")]
24 UnknownBufferType(u32),
25 InvalidMemoryType(String),
26 PboDisconnected,
28 PboMapped,
30 #[cfg(feature = "ndarray")]
31 NdArrayError(ndarray::ShapeError),
32 InvalidShape(String),
33 InvalidArgument(String),
34 InvalidOperation(String),
35 PartialWriteRequiresReadWrite(String),
43 QuantizationInvalid {
47 field: &'static str,
51 expected: String,
53 got: String,
55 },
56 InsufficientCapacity {
59 needed: usize,
61 capacity: usize,
63 },
64 RegionOutOfBounds {
67 region: crate::Region,
69 bounds: (usize, usize),
71 },
72 BatchIndexOutOfBounds {
74 index: usize,
76 batch: usize,
78 },
79}
80
81impl From<std::io::Error> for Error {
82 fn from(err: std::io::Error) -> Self {
83 Error::IoError(err)
84 }
85}
86#[cfg(unix)]
87impl From<nix::Error> for Error {
88 fn from(err: nix::Error) -> Self {
89 Error::NixError(err)
90 }
91}
92
93#[cfg(feature = "ndarray")]
94impl From<ndarray::ShapeError> for Error {
95 fn from(err: ndarray::ShapeError) -> Self {
96 Error::NdArrayError(err)
97 }
98}
99
100impl std::fmt::Display for Error {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 match self {
103 Error::InsufficientCapacity { needed, capacity } => write!(
104 f,
105 "insufficient tensor capacity: need {needed} bytes, have {capacity}"
106 ),
107 Error::RegionOutOfBounds { region, bounds } => write!(
108 f,
109 "region {region:?} out of bounds for {}x{} frame",
110 bounds.0, bounds.1
111 ),
112 Error::BatchIndexOutOfBounds { index, batch } => write!(
113 f,
114 "batch index {index} out of bounds for batch size {batch}"
115 ),
116 #[cfg(target_os = "linux")]
117 Error::UnknownBufferType(magic) => write!(
118 f,
119 "UnknownBufferType: fd is on an unrecognized filesystem \
120 (magic {magic:#010x}); expected a DMA-BUF or tmpfs/shm fd"
121 ),
122 _ => write!(f, "{self:?}"),
123 }
124 }
125}
126
127impl std::error::Error for Error {}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_error_display() {
135 let e = Error::InvalidSize(0);
136 let msg = e.to_string();
137 assert!(!msg.is_empty());
138 assert!(
139 msg.contains("InvalidSize"),
140 "unexpected InvalidSize message: {msg}"
141 );
142
143 let e = Error::NotImplemented("foo".to_string());
144 let msg = e.to_string();
145 assert!(!msg.is_empty());
146 assert!(
147 msg.contains("NotImplemented") && msg.contains("foo"),
148 "unexpected NotImplemented message: {msg}"
149 );
150
151 let e = Error::ShapeMismatch("expected 3, got 4".to_string());
152 let msg = e.to_string();
153 assert!(!msg.is_empty());
154 assert!(
155 msg.contains("ShapeMismatch") && msg.contains("expected 3"),
156 "unexpected ShapeMismatch message: {msg}"
157 );
158
159 let e = Error::InvalidMemoryType("dma".to_string());
160 let msg = e.to_string();
161 assert!(!msg.is_empty());
162 assert!(
163 msg.contains("InvalidMemoryType") && msg.contains("dma"),
164 "unexpected InvalidMemoryType message: {msg}"
165 );
166
167 let e = Error::PboDisconnected;
168 let msg = e.to_string();
169 assert!(!msg.is_empty());
170 assert!(
171 msg.contains("PboDisconnected"),
172 "unexpected PboDisconnected message: {msg}"
173 );
174
175 let e = Error::PboMapped;
176 let msg = e.to_string();
177 assert!(!msg.is_empty());
178 assert!(
179 msg.contains("PboMapped"),
180 "unexpected PboMapped message: {msg}"
181 );
182
183 let e = Error::InvalidShape("bad shape".to_string());
184 let msg = e.to_string();
185 assert!(!msg.is_empty());
186 assert!(
187 msg.contains("InvalidShape") && msg.contains("bad shape"),
188 "unexpected InvalidShape message: {msg}"
189 );
190
191 let e = Error::InvalidArgument("negative".to_string());
192 let msg = e.to_string();
193 assert!(!msg.is_empty());
194 assert!(
195 msg.contains("InvalidArgument") && msg.contains("negative"),
196 "unexpected InvalidArgument message: {msg}"
197 );
198
199 let e = Error::PartialWriteRequiresReadWrite("retry with ReadWrite".to_string());
200 let msg = e.to_string();
201 assert!(!msg.is_empty());
202 assert!(
203 msg.contains("PartialWriteRequiresReadWrite") && msg.contains("retry with ReadWrite"),
204 "unexpected PartialWriteRequiresReadWrite message: {msg}"
205 );
206
207 let e = Error::InvalidOperation("read-only".to_string());
208 let msg = e.to_string();
209 assert!(!msg.is_empty());
210 assert!(
211 msg.contains("InvalidOperation") && msg.contains("read-only"),
212 "unexpected InvalidOperation message: {msg}"
213 );
214
215 let e = Error::IoError(std::io::Error::new(
216 std::io::ErrorKind::NotFound,
217 "file missing",
218 ));
219 let msg = e.to_string();
220 assert!(!msg.is_empty());
221 assert!(
222 msg.contains("IoError") && msg.contains("file missing"),
223 "unexpected IoError message: {msg}"
224 );
225 }
226
227 #[test]
228 fn insufficient_capacity_message() {
229 let e = Error::InsufficientCapacity {
230 needed: 100,
231 capacity: 64,
232 };
233 assert_eq!(
234 e.to_string(),
235 "insufficient tensor capacity: need 100 bytes, have 64"
236 );
237 }
238
239 #[test]
240 fn region_out_of_bounds_message_names_the_frame() {
241 let region = crate::Region::new(2, 3, 8, 8);
242 let e = Error::RegionOutOfBounds {
243 region,
244 bounds: (4, 5),
245 };
246 assert_eq!(
247 e.to_string(),
248 format!("region {region:?} out of bounds for 4x5 frame")
249 );
250 }
251
252 #[test]
253 fn batch_index_out_of_bounds_message_names_index_and_size() {
254 let e = Error::BatchIndexOutOfBounds { index: 9, batch: 4 };
255 assert_eq!(
256 e.to_string(),
257 "batch index 9 out of bounds for batch size 4"
258 );
259 }
260
261 #[cfg(target_os = "linux")]
262 #[test]
263 fn unknown_buffer_type_message_names_the_magic() {
264 let e = Error::UnknownBufferType(0x1234);
265 assert_eq!(
266 e.to_string(),
267 "UnknownBufferType: fd is on an unrecognized filesystem (magic 0x00001234); \
268 expected a DMA-BUF or tmpfs/shm fd"
269 );
270 }
271}