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 QuantizationInvalid {
39 field: &'static str,
43 expected: String,
45 got: String,
47 },
48 InsufficientCapacity {
51 needed: usize,
53 capacity: usize,
55 },
56 RegionOutOfBounds {
59 region: crate::Region,
61 bounds: (usize, usize),
63 },
64 BatchIndexOutOfBounds {
66 index: usize,
68 batch: usize,
70 },
71}
72
73impl From<std::io::Error> for Error {
74 fn from(err: std::io::Error) -> Self {
75 Error::IoError(err)
76 }
77}
78#[cfg(unix)]
79impl From<nix::Error> for Error {
80 fn from(err: nix::Error) -> Self {
81 Error::NixError(err)
82 }
83}
84
85#[cfg(feature = "ndarray")]
86impl From<ndarray::ShapeError> for Error {
87 fn from(err: ndarray::ShapeError) -> Self {
88 Error::NdArrayError(err)
89 }
90}
91
92impl std::fmt::Display for Error {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 match self {
95 Error::InsufficientCapacity { needed, capacity } => write!(
96 f,
97 "insufficient tensor capacity: need {needed} bytes, have {capacity}"
98 ),
99 Error::RegionOutOfBounds { region, bounds } => write!(
100 f,
101 "region {region:?} out of bounds for {}x{} frame",
102 bounds.0, bounds.1
103 ),
104 Error::BatchIndexOutOfBounds { index, batch } => write!(
105 f,
106 "batch index {index} out of bounds for batch size {batch}"
107 ),
108 #[cfg(target_os = "linux")]
109 Error::UnknownBufferType(magic) => write!(
110 f,
111 "UnknownBufferType: fd is on an unrecognized filesystem \
112 (magic {magic:#010x}); expected a DMA-BUF or tmpfs/shm fd"
113 ),
114 _ => write!(f, "{self:?}"),
115 }
116 }
117}
118
119impl std::error::Error for Error {}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_error_display() {
127 let e = Error::InvalidSize(0);
128 let msg = e.to_string();
129 assert!(!msg.is_empty());
130 assert!(
131 msg.contains("InvalidSize"),
132 "unexpected InvalidSize message: {msg}"
133 );
134
135 let e = Error::NotImplemented("foo".to_string());
136 let msg = e.to_string();
137 assert!(!msg.is_empty());
138 assert!(
139 msg.contains("NotImplemented") && msg.contains("foo"),
140 "unexpected NotImplemented message: {msg}"
141 );
142
143 let e = Error::ShapeMismatch("expected 3, got 4".to_string());
144 let msg = e.to_string();
145 assert!(!msg.is_empty());
146 assert!(
147 msg.contains("ShapeMismatch") && msg.contains("expected 3"),
148 "unexpected ShapeMismatch message: {msg}"
149 );
150
151 let e = Error::InvalidMemoryType("dma".to_string());
152 let msg = e.to_string();
153 assert!(!msg.is_empty());
154 assert!(
155 msg.contains("InvalidMemoryType") && msg.contains("dma"),
156 "unexpected InvalidMemoryType message: {msg}"
157 );
158
159 let e = Error::PboDisconnected;
160 let msg = e.to_string();
161 assert!(!msg.is_empty());
162 assert!(
163 msg.contains("PboDisconnected"),
164 "unexpected PboDisconnected message: {msg}"
165 );
166
167 let e = Error::PboMapped;
168 let msg = e.to_string();
169 assert!(!msg.is_empty());
170 assert!(
171 msg.contains("PboMapped"),
172 "unexpected PboMapped message: {msg}"
173 );
174
175 let e = Error::InvalidShape("bad shape".to_string());
176 let msg = e.to_string();
177 assert!(!msg.is_empty());
178 assert!(
179 msg.contains("InvalidShape") && msg.contains("bad shape"),
180 "unexpected InvalidShape message: {msg}"
181 );
182
183 let e = Error::InvalidArgument("negative".to_string());
184 let msg = e.to_string();
185 assert!(!msg.is_empty());
186 assert!(
187 msg.contains("InvalidArgument") && msg.contains("negative"),
188 "unexpected InvalidArgument message: {msg}"
189 );
190
191 let e = Error::InvalidOperation("read-only".to_string());
192 let msg = e.to_string();
193 assert!(!msg.is_empty());
194 assert!(
195 msg.contains("InvalidOperation") && msg.contains("read-only"),
196 "unexpected InvalidOperation message: {msg}"
197 );
198
199 let e = Error::IoError(std::io::Error::new(
200 std::io::ErrorKind::NotFound,
201 "file missing",
202 ));
203 let msg = e.to_string();
204 assert!(!msg.is_empty());
205 assert!(
206 msg.contains("IoError") && msg.contains("file missing"),
207 "unexpected IoError message: {msg}"
208 );
209 }
210
211 #[test]
212 fn insufficient_capacity_message() {
213 let e = Error::InsufficientCapacity {
214 needed: 100,
215 capacity: 64,
216 };
217 let msg = format!("{e}");
218 assert!(
219 msg.contains("100") && msg.contains("64"),
220 "unexpected message: {msg}"
221 );
222 }
223}