burn_std/
errors.rs

1//! # Common Burn Errors
2
3use alloc::string::String;
4use core::ops::Range;
5
6/// Describes the kind of an index.
7#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
8pub enum IndexKind {
9    /// The index of an element in a dimension.
10    Element,
11
12    /// The index of a dimension.
13    Dimension,
14}
15
16impl IndexKind {
17    /// Get the display name of the kind.
18    pub fn name(&self) -> &'static str {
19        match self {
20            IndexKind::Element => "element",
21            IndexKind::Dimension => "dimension",
22        }
23    }
24}
25
26/// Access Bounds Error.
27#[derive(Debug, PartialEq, Eq, Clone, Hash)]
28pub enum BoundsError {
29    /// Generic bounds error.
30    Generic(String),
31
32    /// Index out of bounds.
33    Index {
34        /// The kind of index that was out of bounds.
35        kind: IndexKind,
36
37        /// The index that was out of bounds.
38        index: isize,
39
40        /// The range of valid indices.
41        bounds: Range<isize>,
42    },
43}
44
45impl BoundsError {
46    /// Create a new index error.
47    pub fn index(kind: IndexKind, index: isize, bounds: Range<isize>) -> Self {
48        Self::Index {
49            kind,
50            index,
51            bounds,
52        }
53    }
54}
55
56impl core::fmt::Display for BoundsError {
57    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
58        match self {
59            Self::Generic(msg) => write!(f, "BoundsError: {}", msg),
60            Self::Index {
61                kind,
62                index,
63                bounds: range,
64            } => write!(
65                f,
66                "BoundsError: {} {} out of bounds: {:?}",
67                kind.name(),
68                index,
69                range
70            ),
71        }
72    }
73}
74
75impl core::error::Error for BoundsError {}
76
77/// Common Expression Error.
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub enum ExpressionError {
80    /// Parse Error.
81    ParseError {
82        /// The error message.
83        message: String,
84        /// The source expression.
85        source: String,
86    },
87
88    /// Invalid Expression.
89    InvalidExpression {
90        /// The error message.
91        message: String,
92        /// The source expression.
93        source: String,
94    },
95}
96
97impl core::fmt::Display for ExpressionError {
98    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
99        match self {
100            Self::ParseError { message, source } => {
101                write!(f, "ExpressionError: ParseError: {} ({})", message, source)
102            }
103            Self::InvalidExpression { message, source } => write!(
104                f,
105                "ExpressionError: InvalidExpression: {} ({})",
106                message, source
107            ),
108        }
109    }
110}
111
112impl core::error::Error for ExpressionError {}
113
114impl ExpressionError {
115    /// Constructs a new [`ExpressionError::ParseError`].
116    ///
117    /// This function is a utility for creating instances where a parsing error needs to be represented,
118    /// encapsulating a descriptive error message and the source of the error.
119    ///
120    /// # Parameters
121    ///
122    /// - `message`: A value that can be converted into a `String`, representing a human-readable description
123    ///   of the parsing error.
124    /// - `source`: A value that can be converted into a `String`, typically identifying the origin or
125    ///   input that caused the parsing error.
126    pub fn parse_error(message: impl Into<String>, source: impl Into<String>) -> Self {
127        Self::ParseError {
128            message: message.into(),
129            source: source.into(),
130        }
131    }
132
133    /// Creates a new [`ExpressionError::InvalidExpression`].
134    ///
135    /// # Parameters
136    /// - `message`: A detailed message describing the nature of the invalid expression.
137    ///   Accepts any type that can be converted into a `String`.
138    /// - `source`: The source or context in which the invalid expression occurred.
139    ///   Accepts any type that can be converted into a `String`.
140    pub fn invalid_expression(message: impl Into<String>, source: impl Into<String>) -> Self {
141        Self::InvalidExpression {
142            message: message.into(),
143            source: source.into(),
144        }
145    }
146}
147#[cfg(test)]
148mod tests {
149    use super::*;
150    use alloc::format;
151    use alloc::string::ToString;
152
153    #[test]
154    fn test_bounds_error_display() {
155        assert_eq!(
156            format!("{}", BoundsError::Generic("test".to_string())),
157            "BoundsError: test"
158        );
159        assert_eq!(
160            format!(
161                "{}",
162                BoundsError::Index {
163                    kind: IndexKind::Element,
164                    index: 1,
165                    bounds: 0..2
166                }
167            ),
168            "BoundsError: element 1 out of bounds: 0..2"
169        );
170    }
171
172    #[test]
173    fn test_parse_error() {
174        let err = ExpressionError::parse_error("test", "source");
175        assert_eq!(
176            format!("{:?}", err),
177            "ParseError { message: \"test\", source: \"source\" }"
178        );
179    }
180
181    #[test]
182    fn test_invalid_expression() {
183        let err = ExpressionError::invalid_expression("test", "source");
184        assert_eq!(
185            format!("{:?}", err),
186            "InvalidExpression { message: \"test\", source: \"source\" }"
187        );
188    }
189}