Skip to main content

edgefirst_decoder/
error.rs

1// SPDX-FileCopyrightText: Copyright 2025 Au-Zone Technologies
2// SPDX-License-Identifier: Apache-2.0
3
4use core::fmt;
5
6pub type DecoderResult<T, E = DecoderError> = std::result::Result<T, E>;
7
8#[derive(Debug)]
9pub enum DecoderError {
10    /// An internal error occurred
11    Internal(String),
12    /// An operation was requested that is not supported
13    NotSupported(String),
14    /// An invalid tensor shape was given
15    InvalidShape(String),
16    /// An error occurred while parsing YAML
17    Yaml(serde_yaml::Error),
18    /// An error occurred while parsing YAML
19    Json(serde_json::Error),
20    /// Attmpted to use build a decoder without configuration
21    NoConfig,
22    /// The provide decoder configuration was invalid
23    InvalidConfig(String),
24    /// An error occurred with ndarray shape operations
25    NDArrayShape(ndarray::ShapeError),
26}
27
28impl fmt::Display for DecoderError {
29    /// Formats the error for display
30    /// # Arguments
31    /// * `f` - The formatter to write to
32    /// # Returns
33    /// A result indicating success or failure
34    /// # Examples
35    /// ```rust
36    /// use edgefirst_decoder::DecoderError;
37    /// let err = DecoderError::InvalidConfig("The config was invalid".to_string());
38    /// println!("{}", err);
39    /// ```
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(f, "{self:?}")
42    }
43}
44
45impl std::error::Error for DecoderError {}
46
47impl From<serde_yaml::Error> for DecoderError {
48    fn from(err: serde_yaml::Error) -> Self {
49        DecoderError::Yaml(err)
50    }
51}
52
53impl From<serde_json::Error> for DecoderError {
54    fn from(err: serde_json::Error) -> Self {
55        DecoderError::Json(err)
56    }
57}
58
59impl From<ndarray::ShapeError> for DecoderError {
60    fn from(err: ndarray::ShapeError) -> Self {
61        DecoderError::NDArrayShape(err)
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_decoder_error_display() {
71        let e = DecoderError::Internal("something broke".to_string());
72        let msg = e.to_string();
73        assert!(!msg.is_empty());
74        assert!(
75            msg.contains("Internal") && msg.contains("something broke"),
76            "unexpected Internal message: {msg}"
77        );
78
79        let e = DecoderError::NotSupported("yolov99".to_string());
80        let msg = e.to_string();
81        assert!(!msg.is_empty());
82        assert!(
83            msg.contains("NotSupported") && msg.contains("yolov99"),
84            "unexpected NotSupported message: {msg}"
85        );
86
87        let e = DecoderError::InvalidShape("expected 3D".to_string());
88        let msg = e.to_string();
89        assert!(!msg.is_empty());
90        assert!(
91            msg.contains("InvalidShape") && msg.contains("expected 3D"),
92            "unexpected InvalidShape message: {msg}"
93        );
94
95        let e = DecoderError::NoConfig;
96        let msg = e.to_string();
97        assert!(!msg.is_empty());
98        assert!(
99            msg.contains("NoConfig"),
100            "unexpected NoConfig message: {msg}"
101        );
102
103        let e = DecoderError::InvalidConfig("missing field".to_string());
104        let msg = e.to_string();
105        assert!(!msg.is_empty());
106        assert!(
107            msg.contains("InvalidConfig") && msg.contains("missing field"),
108            "unexpected InvalidConfig message: {msg}"
109        );
110    }
111}