Skip to main content

optionstratlib_core/error/
common.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 8/1/25
5******************************************************************************/
6//! Target crate (ADR-0001 D6, roadmap M1-14): **core**. Owns `OperationErrorKind`.
7
8use thiserror::Error;
9
10/// Represents the types of errors that can occur during operations related to trading strategies or other processes.
11///
12/// This enum categorizes errors for better debugging and handling in a structured way.
13///
14/// # Variants
15///
16/// * `NotSupported` - Indicates that the requested operation is not supported for a given strategy type
17///   or context. Used when there's an incompatibility between an operation and its execution context.
18///
19/// * `InvalidParameters` - Reflects that the operation was provided with invalid or insufficient parameters
20///   that prevent successful execution. Used when input validation fails.
21///
22/// # Examples
23///
24/// ```
25/// use optionstratlib_core::error::OperationErrorKind;
26///
27/// // Creating a NotSupported error
28/// let error = OperationErrorKind::NotSupported {
29///     operation: "calculate_delta".to_string(),
30///     reason: "Not applicable for binary options".to_string()
31/// };
32///
33/// // Creating an InvalidParameters error
34/// let error = OperationErrorKind::InvalidParameters {
35///     operation: "calculate_premium".to_string(),
36///     reason: "Missing volatility input".to_string()
37/// };
38/// ```
39///
40/// # Use Cases
41///
42/// - Used in strategy implementations to signal operation compatibility issues
43/// - Used in validation layers to report problems with input parameters
44/// - Helps create clear error messages that guide users toward resolution
45///
46/// # Related Types
47///
48/// This error type is typically used alongside other specialized error enums in the
49/// error module, such as `StrategyError`, `OptionsError`, and others.
50#[derive(Error, Debug)]
51pub enum OperationErrorKind {
52    /// Operation not supported for this strategy or context
53    ///
54    /// Used when an operation cannot be performed due to incompatibility with
55    /// the target strategy type or other contextual constraints.
56    #[error("Operation '{operation}' is not supported for strategy '{reason}'")]
57    NotSupported {
58        /// The name of the operation that was attempted
59        operation: String,
60        /// A detailed explanation of why the operation is not supported
61        reason: String,
62    },
63
64    /// Invalid parameters for operation
65    ///
66    /// Used when the input parameters for an operation are invalid, insufficient,
67    /// or incompatible with the requirements of the operation.
68    #[error("Invalid parameters for operation '{operation}': {reason}")]
69    InvalidParameters {
70        /// The name of the operation that failed
71        operation: String,
72        /// A detailed explanation of why the parameters are invalid
73        reason: String,
74    },
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_operation_error_not_supported_display() {
83        let error = OperationErrorKind::NotSupported {
84            operation: "calculate_profit".to_string(),
85            reason: "IronCondor".to_string(),
86        };
87
88        assert_eq!(
89            error.to_string(),
90            "Operation 'calculate_profit' is not supported for strategy 'IronCondor'"
91        );
92    }
93
94    #[test]
95    fn test_operation_error_invalid_parameters_display() {
96        let error = OperationErrorKind::InvalidParameters {
97            operation: "validate_strikes".to_string(),
98            reason: "Strike prices must be positive".to_string(),
99        };
100
101        assert_eq!(
102            error.to_string(),
103            "Invalid parameters for operation 'validate_strikes': Strike prices must be positive"
104        );
105    }
106
107    #[test]
108    fn test_operation_error_debug() {
109        let error = OperationErrorKind::NotSupported {
110            operation: "calculate_profit".to_string(),
111            reason: "IronCondor".to_string(),
112        };
113
114        assert_eq!(
115            format!("{error:?}"),
116            "NotSupported { operation: \"calculate_profit\", reason: \"IronCondor\" }"
117        );
118    }
119
120    #[test]
121    fn test_operation_error_as_error() {
122        let error = OperationErrorKind::InvalidParameters {
123            operation: "validate_strikes".to_string(),
124            reason: "Strike prices must be positive".to_string(),
125        };
126
127        let error_ref: &dyn std::error::Error = &error;
128        assert_eq!(
129            error_ref.to_string(),
130            "Invalid parameters for operation 'validate_strikes': Strike prices must be positive"
131        );
132    }
133
134    #[test]
135    fn test_operation_error_kinds_distinct() {
136        let error1 = OperationErrorKind::NotSupported {
137            operation: "op".to_string(),
138            reason: "strat".to_string(),
139        };
140
141        let error2 = OperationErrorKind::InvalidParameters {
142            operation: "op".to_string(),
143            reason: "err".to_string(),
144        };
145
146        assert_ne!(format!("{error1:?}"), format!("{:?}", error2));
147    }
148
149    #[test]
150    fn test_operation_error_empty_strings() {
151        let error = OperationErrorKind::NotSupported {
152            operation: "".to_string(),
153            reason: "".to_string(),
154        };
155
156        assert_eq!(
157            error.to_string(),
158            "Operation '' is not supported for strategy ''"
159        );
160    }
161}