Skip to main content

shape_ast/error/
impls.rs

1//! Trait implementations for error types
2//!
3//! This module contains Clone and builder implementations
4//! for error-related types.
5
6use super::types::{ErrorNote, ShapeError, SourceLocation};
7
8impl ErrorNote {
9    pub fn new(message: impl Into<String>, _line: usize, _column: usize) -> Self {
10        Self {
11            message: message.into(),
12            location: None,
13        }
14    }
15}
16
17impl SourceLocation {
18    /// Add a hint/suggestion (e.g., "did you mean `foo`?")
19    pub fn with_hint(mut self, hint: impl Into<String>) -> Self {
20        self.hints.push(hint.into());
21        self
22    }
23
24    /// Add multiple hints
25    pub fn with_hints(mut self, hints: impl IntoIterator<Item = impl Into<String>>) -> Self {
26        self.hints.extend(hints.into_iter().map(Into::into));
27        self
28    }
29
30    /// Add a note showing related location (e.g., "first defined here:")
31    pub fn with_note(mut self, note: ErrorNote) -> Self {
32        self.notes.push(note);
33        self
34    }
35
36    /// Add multiple notes
37    pub fn with_notes(mut self, notes: impl IntoIterator<Item = ErrorNote>) -> Self {
38        self.notes.extend(notes);
39        self
40    }
41}
42
43/// Implement Clone manually since thiserror doesn't derive it
44impl Clone for ShapeError {
45    fn clone(&self) -> Self {
46        match self {
47            ShapeError::StructuredParse(e) => ShapeError::StructuredParse(e.clone()),
48            ShapeError::ParseError { message, location } => ShapeError::ParseError {
49                message: message.clone(),
50                location: location.clone(),
51            },
52            ShapeError::LexError { message, location } => ShapeError::LexError {
53                message: message.clone(),
54                location: location.clone(),
55            },
56            ShapeError::TypeError(e) => ShapeError::TypeError(e.clone()),
57            ShapeError::SemanticError { message, location } => ShapeError::SemanticError {
58                message: message.clone(),
59                location: location.clone(),
60            },
61            ShapeError::RuntimeError { message, location } => ShapeError::RuntimeError {
62                message: message.clone(),
63                location: location.clone(),
64            },
65            ShapeError::VMError(e) => ShapeError::VMError(e.clone()),
66            ShapeError::ControlFlow(e) => ShapeError::ControlFlow(e.clone()),
67            ShapeError::PatternError {
68                message,
69                pattern_name,
70            } => ShapeError::PatternError {
71                message: message.clone(),
72                pattern_name: pattern_name.clone(),
73            },
74            ShapeError::DataError {
75                message,
76                symbol,
77                timeframe,
78            } => ShapeError::DataError {
79                message: message.clone(),
80                symbol: symbol.clone(),
81                timeframe: timeframe.clone(),
82            },
83            ShapeError::ModuleError {
84                message,
85                module_path,
86            } => ShapeError::ModuleError {
87                message: message.clone(),
88                module_path: module_path.clone(),
89            },
90            ShapeError::IoError(e) => {
91                // io::Error doesn't implement Clone, so we create a new one
92                ShapeError::IoError(std::io::Error::new(e.kind(), e.to_string()))
93            }
94            ShapeError::SimulationError {
95                message,
96                simulation_name,
97            } => ShapeError::SimulationError {
98                message: message.clone(),
99                simulation_name: simulation_name.clone(),
100            },
101            ShapeError::DataProviderError { message, provider } => ShapeError::DataProviderError {
102                message: message.clone(),
103                provider: provider.clone(),
104            },
105            ShapeError::TestError { message, test_name } => ShapeError::TestError {
106                message: message.clone(),
107                test_name: test_name.clone(),
108            },
109            ShapeError::ConfigError { message } => ShapeError::ConfigError {
110                message: message.clone(),
111            },
112            ShapeError::StreamError {
113                message,
114                stream_name,
115            } => ShapeError::StreamError {
116                message: message.clone(),
117                stream_name: stream_name.clone(),
118            },
119            ShapeError::CacheError { message } => ShapeError::CacheError {
120                message: message.clone(),
121            },
122            ShapeError::AlignmentError { message, ids } => ShapeError::AlignmentError {
123                message: message.clone(),
124                ids: ids.clone(),
125            },
126            ShapeError::MultiError(errors) => ShapeError::MultiError(errors.clone()),
127            ShapeError::Interrupted { snapshot_hash } => ShapeError::Interrupted {
128                snapshot_hash: snapshot_hash.clone(),
129            },
130            ShapeError::Custom(e) => ShapeError::Custom(e.clone()),
131        }
132    }
133}