1use std::fmt;
4
5pub type IndicatorResult<T> = Result<T, IndicatorError>;
7
8#[derive(Debug, Clone, PartialEq)]
10pub enum IndicatorError {
11 InsufficientData {
16 required: usize,
18 actual: usize,
20 },
21
22 InvalidParameter(String),
26
27 Calculation(String),
32
33 NotInitialized(String),
37
38 InvalidPrice(String),
42
43 InvalidInput(String),
47
48 DivisionByZero,
50}
51
52impl fmt::Display for IndicatorError {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match self {
55 IndicatorError::InsufficientData { required, actual } => {
56 write!(
57 f,
58 "Insufficient data: need at least {required} data points, got {actual}"
59 )
60 }
61 IndicatorError::InvalidParameter(msg) => write!(f, "Invalid parameter: {msg}"),
62 IndicatorError::Calculation(msg) => write!(f, "Calculation error: {msg}"),
63 IndicatorError::NotInitialized(msg) => write!(f, "Not initialized: {msg}"),
64 IndicatorError::InvalidPrice(msg) => write!(f, "Invalid price: {msg}"),
65 IndicatorError::InvalidInput(msg) => write!(f, "Invalid input: {msg}"),
66 IndicatorError::DivisionByZero => write!(f, "Division by zero"),
67 }
68 }
69}
70
71impl std::error::Error for IndicatorError {}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_error_display() {
79 let err = IndicatorError::InsufficientData {
80 required: 20,
81 actual: 10,
82 };
83 assert_eq!(
84 err.to_string(),
85 "Insufficient data: need at least 20 data points, got 10"
86 );
87
88 let err = IndicatorError::InvalidParameter("period must be > 0".to_string());
89 assert_eq!(err.to_string(), "Invalid parameter: period must be > 0");
90
91 let err = IndicatorError::DivisionByZero;
92 assert_eq!(err.to_string(), "Division by zero");
93 }
94}