Skip to main content

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}