Skip to main content

edgefirst_tensor/
error.rs

1// SPDX-FileCopyrightText: Copyright 2025 Au-Zone Technologies
2// SPDX-License-Identifier: Apache-2.0
3
4pub 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    InvalidMemoryType(String),
17    /// The GL context backing a PBO tensor has been destroyed.
18    PboDisconnected,
19    /// The PBO buffer is currently mapped and cannot be used for GL operations.
20    PboMapped,
21    #[cfg(feature = "ndarray")]
22    NdArrayError(ndarray::ShapeError),
23    InvalidShape(String),
24    InvalidArgument(String),
25    InvalidOperation(String),
26}
27
28impl From<std::io::Error> for Error {
29    fn from(err: std::io::Error) -> Self {
30        Error::IoError(err)
31    }
32}
33#[cfg(unix)]
34impl From<nix::Error> for Error {
35    fn from(err: nix::Error) -> Self {
36        Error::NixError(err)
37    }
38}
39
40#[cfg(feature = "ndarray")]
41impl From<ndarray::ShapeError> for Error {
42    fn from(err: ndarray::ShapeError) -> Self {
43        Error::NdArrayError(err)
44    }
45}
46
47impl std::fmt::Display for Error {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "{self:?}")
50    }
51}
52
53impl std::error::Error for Error {}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_error_display() {
61        let e = Error::InvalidSize(0);
62        let msg = e.to_string();
63        assert!(!msg.is_empty());
64        assert!(
65            msg.contains("InvalidSize"),
66            "unexpected InvalidSize message: {msg}"
67        );
68
69        let e = Error::NotImplemented("foo".to_string());
70        let msg = e.to_string();
71        assert!(!msg.is_empty());
72        assert!(
73            msg.contains("NotImplemented") && msg.contains("foo"),
74            "unexpected NotImplemented message: {msg}"
75        );
76
77        let e = Error::ShapeMismatch("expected 3, got 4".to_string());
78        let msg = e.to_string();
79        assert!(!msg.is_empty());
80        assert!(
81            msg.contains("ShapeMismatch") && msg.contains("expected 3"),
82            "unexpected ShapeMismatch message: {msg}"
83        );
84
85        let e = Error::InvalidMemoryType("dma".to_string());
86        let msg = e.to_string();
87        assert!(!msg.is_empty());
88        assert!(
89            msg.contains("InvalidMemoryType") && msg.contains("dma"),
90            "unexpected InvalidMemoryType message: {msg}"
91        );
92
93        let e = Error::PboDisconnected;
94        let msg = e.to_string();
95        assert!(!msg.is_empty());
96        assert!(
97            msg.contains("PboDisconnected"),
98            "unexpected PboDisconnected message: {msg}"
99        );
100
101        let e = Error::PboMapped;
102        let msg = e.to_string();
103        assert!(!msg.is_empty());
104        assert!(
105            msg.contains("PboMapped"),
106            "unexpected PboMapped message: {msg}"
107        );
108
109        let e = Error::InvalidShape("bad shape".to_string());
110        let msg = e.to_string();
111        assert!(!msg.is_empty());
112        assert!(
113            msg.contains("InvalidShape") && msg.contains("bad shape"),
114            "unexpected InvalidShape message: {msg}"
115        );
116
117        let e = Error::InvalidArgument("negative".to_string());
118        let msg = e.to_string();
119        assert!(!msg.is_empty());
120        assert!(
121            msg.contains("InvalidArgument") && msg.contains("negative"),
122            "unexpected InvalidArgument message: {msg}"
123        );
124
125        let e = Error::InvalidOperation("read-only".to_string());
126        let msg = e.to_string();
127        assert!(!msg.is_empty());
128        assert!(
129            msg.contains("InvalidOperation") && msg.contains("read-only"),
130            "unexpected InvalidOperation message: {msg}"
131        );
132
133        let e = Error::IoError(std::io::Error::new(
134            std::io::ErrorKind::NotFound,
135            "file missing",
136        ));
137        let msg = e.to_string();
138        assert!(!msg.is_empty());
139        assert!(
140            msg.contains("IoError") && msg.contains("file missing"),
141            "unexpected IoError message: {msg}"
142        );
143    }
144}