1use alloc::string::String;
4use core::ops::Range;
5
6#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
8pub enum IndexKind {
9 Element,
11
12 Dimension,
14}
15
16impl IndexKind {
17 pub fn name(&self) -> &'static str {
19 match self {
20 IndexKind::Element => "element",
21 IndexKind::Dimension => "dimension",
22 }
23 }
24}
25
26#[derive(Debug, PartialEq, Eq, Clone, Hash)]
28pub enum BoundsError {
29 Generic(String),
31
32 Index {
34 kind: IndexKind,
36
37 index: isize,
39
40 bounds: Range<isize>,
42 },
43}
44
45impl BoundsError {
46 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#[derive(Debug, Clone, PartialEq, Eq)]
79pub enum ExpressionError {
80 ParseError {
82 message: String,
84 source: String,
86 },
87
88 InvalidExpression {
90 message: String,
92 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 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 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}