qtrade_indicators/indicator_error.rs
1//! Shared error type used uniformly by all indicator calculation functions.
2/*!
3Defines the [`IndicatorError`] enum returned by every `calculate_*` function
4in this crate.
5
6| Variant | Condition | Returned by |
7|---------|-----------|-------------|
8| `EmptyData` | Any input slice is empty | All `calculate_*` functions |
9| `DifferentDataLength` | Multiple input slices have mismatched lengths | `calculate_median_price`, `calculate_tr`, `calculate_atr`, `calculate_supertrend`, `calculate_wf` |
10| `ImproperDataLength` | Input data length is insufficient for the computation period | All MA functions, `calculate_atr`, `calculate_wf` |
11| `ImproperSetting` | Configuration is invalid (e.g. zero period, zero/negative factor) | All `calculate_*` functions that accept a `Setting*` struct |
12
13# Example
14
15```rust
16use qtrade_indicators::indicator_error::IndicatorError;
17
18fn check_length(data: &[f64], period: usize) -> Result<(), IndicatorError> {
19 if data.len() <= period {
20 return Err(IndicatorError::ImproperDataLength);
21 }
22 Ok(())
23}
24```
25*/
26
27use std::fmt;
28use std::error::Error;
29
30/// Errors returned by indicator calculation functions.
31#[derive(Debug)]
32pub enum IndicatorError {
33 /// One or more input slices are empty.
34 EmptyData,
35 /// Multiple input slices have mismatched lengths.
36 DifferentDataLength,
37 /// Input data is too short for the requested period / factor.
38 ImproperDataLength,
39 /// Configuration is invalid (e.g. zero period, zero/negative factor).
40 ImproperSetting,
41}
42impl fmt::Display for IndicatorError {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 let s = match self {
45 IndicatorError::EmptyData => "Input data can not be empty",
46 IndicatorError::DifferentDataLength => {
47 "Input data can not have a different length than input"
48 }
49 IndicatorError::ImproperDataLength => "Improper data length",
50 IndicatorError::ImproperSetting => "Improper setting",
51 };
52
53 write!(f, "{}", s)
54 }
55}
56impl Error for IndicatorError {}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_indicator_error_display_empty_data() {
64 let err = IndicatorError::EmptyData;
65 assert_eq!(err.to_string(), "Input data can not be empty");
66 }
67
68 #[test]
69 fn test_indicator_error_display_different_length() {
70 let err = IndicatorError::DifferentDataLength;
71 assert_eq!(
72 err.to_string(),
73 "Input data can not have a different length than input"
74 );
75 }
76
77 #[test]
78 fn test_indicator_error_display_improper_length() {
79 let err = IndicatorError::ImproperDataLength;
80 assert_eq!(err.to_string(), "Improper data length");
81 }
82
83 #[test]
84 fn test_indicator_error_display_improper_setting() {
85 let err = IndicatorError::ImproperSetting;
86 assert_eq!(err.to_string(), "Improper setting");
87 }
88
89 #[test]
90 fn test_indicator_error_implements_error_trait() {
91 fn assert_error<T: std::error::Error>() {}
92 assert_error::<IndicatorError>();
93 }
94}