deribit_base/error/
conversions.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 22/7/25
5******************************************************************************/
6
7use crate::error::codes::DeribitErrorCode;
8use crate::error::types::DeribitError;
9
10// Conversion from DeribitErrorCode to DeribitError
11impl From<DeribitErrorCode> for DeribitError {
12    fn from(error_code: DeribitErrorCode) -> Self {
13        DeribitError::Api {
14            code: error_code.code(),
15            message: error_code.message().to_string(),
16        }
17    }
18}
19
20// Conversion from HTTP status codes to DeribitErrorCode
21impl From<u16> for DeribitErrorCode {
22    fn from(status: u16) -> Self {
23        match status {
24            400 => DeribitErrorCode::BadRequest,
25            401 => DeribitErrorCode::Unauthorized,
26            403 => DeribitErrorCode::Forbidden,
27            404 => DeribitErrorCode::NotFound,
28            429 => DeribitErrorCode::TooManyRequests,
29            500 => DeribitErrorCode::InternalServerError,
30            503 => DeribitErrorCode::TemporarilyUnavailable,
31            _ => DeribitErrorCode::Unknown(status as i32),
32        }
33    }
34}
35
36// Conversion from string error messages to DeribitError
37impl From<String> for DeribitError {
38    fn from(message: String) -> Self {
39        DeribitError::Connection(message)
40    }
41}
42
43impl From<&str> for DeribitError {
44    fn from(message: &str) -> Self {
45        DeribitError::Connection(message.to_string())
46    }
47}
48
49// Conversion from serde_json::Error to DeribitError
50impl From<serde_json::Error> for DeribitError {
51    fn from(error: serde_json::Error) -> Self {
52        DeribitError::Serialization(error.to_string())
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_error_code_to_deribit_error_conversion() {
62        let error_code = DeribitErrorCode::AuthorizationRequired;
63        let deribit_error: DeribitError = error_code.into();
64
65        match deribit_error {
66            DeribitError::Api { code, message } => {
67                assert_eq!(code, 10000);
68                assert_eq!(message, "authorization_required");
69            }
70            _ => panic!("Expected Api error"),
71        }
72    }
73
74    #[test]
75    fn test_http_status_to_error_code_conversion() {
76        // Test HTTP status to DeribitErrorCode conversion
77        let error_400 = DeribitErrorCode::from(400u16);
78        assert_eq!(error_400, DeribitErrorCode::BadRequest);
79        assert_eq!(error_400.code(), 11050); // BadRequest maps to 11050
80
81        let error_401 = DeribitErrorCode::from(401u16);
82        assert_eq!(error_401, DeribitErrorCode::Unauthorized);
83        assert_eq!(error_401.code(), 13009); // Unauthorized maps to 13009
84
85        let error_403 = DeribitErrorCode::from(403u16);
86        assert_eq!(error_403, DeribitErrorCode::Forbidden);
87        assert_eq!(error_403.code(), 13021); // Forbidden maps to 13021
88
89        let error_404 = DeribitErrorCode::from(404u16);
90        assert_eq!(error_404, DeribitErrorCode::NotFound);
91        assert_eq!(error_404.code(), 13020); // NotFound maps to 13020
92
93        let error_429 = DeribitErrorCode::from(429u16);
94        assert_eq!(error_429, DeribitErrorCode::TooManyRequests);
95        assert_eq!(error_429.code(), 10028); // TooManyRequests maps to 10028
96
97        let error_500 = DeribitErrorCode::from(500u16);
98        assert_eq!(error_500, DeribitErrorCode::InternalServerError);
99        assert_eq!(error_500.code(), 11094); // InternalServerError maps to 11094
100
101        let error_503 = DeribitErrorCode::from(503u16);
102        assert_eq!(error_503, DeribitErrorCode::TemporarilyUnavailable);
103        assert_eq!(error_503.code(), 13028); // TemporarilyUnavailable maps to 13028
104
105        // Test unknown status code
106        let error_418 = DeribitErrorCode::from(418u16);
107        assert_eq!(error_418, DeribitErrorCode::Unknown(418));
108        assert_eq!(error_418.code(), 418);
109
110        // Verify all have proper messages
111        for error in [
112            error_400, error_401, error_403, error_404, error_429, error_500, error_503, error_418,
113        ] {
114            assert!(!error.message().is_empty());
115        }
116    }
117
118    #[test]
119    fn test_string_to_deribit_error_conversion() {
120        let message = "Connection failed".to_string();
121        let error: DeribitError = message.clone().into();
122
123        match error {
124            DeribitError::Connection(msg) => {
125                assert_eq!(msg, message);
126            }
127            _ => panic!("Expected Connection error"),
128        }
129    }
130
131    #[test]
132    fn test_str_to_deribit_error_conversion() {
133        let message = "Connection timeout";
134        let error: DeribitError = message.into();
135
136        match error {
137            DeribitError::Connection(msg) => {
138                assert_eq!(msg, message);
139            }
140            _ => panic!("Expected Connection error"),
141        }
142    }
143
144    #[test]
145    fn test_serde_json_error_conversion() {
146        let invalid_json = r#"{"invalid": json}"#;
147        let json_error = serde_json::from_str::<serde_json::Value>(invalid_json).unwrap_err();
148        let deribit_error: DeribitError = json_error.into();
149
150        match deribit_error {
151            DeribitError::Serialization(message) => {
152                assert!(!message.is_empty());
153                assert!(message.contains("expected"));
154            }
155            _ => panic!("Expected Serialization error"),
156        }
157    }
158
159    #[test]
160    fn test_comprehensive_error_code_conversions() {
161        // Test various error codes to ensure they convert properly
162        let error_codes = vec![
163            DeribitErrorCode::Success,
164            DeribitErrorCode::Error,
165            DeribitErrorCode::QtyTooLow,
166            DeribitErrorCode::NotEnoughFunds,
167            DeribitErrorCode::InvalidAmount,
168            DeribitErrorCode::TooManyRequests,
169            DeribitErrorCode::Unknown(99999),
170        ];
171
172        for error_code in error_codes {
173            let deribit_error: DeribitError = error_code.clone().into();
174            match deribit_error {
175                DeribitError::Api { code, message } => {
176                    assert_eq!(code, error_code.code());
177                    assert_eq!(message, error_code.message());
178                }
179                _ => panic!("Expected Api error for {:?}", error_code),
180            }
181        }
182    }
183
184    #[test]
185    fn test_error_chain_conversions() {
186        // Test that we can chain conversions
187        let status_code: u16 = 401;
188        let error_code: DeribitErrorCode = status_code.into();
189        let deribit_error: DeribitError = error_code.into();
190
191        match deribit_error {
192            DeribitError::Api { code, message } => {
193                assert_eq!(code, 13009); // Unauthorized code
194                assert_eq!(message, "unauthorized");
195            }
196            _ => panic!("Expected Api error"),
197        }
198    }
199}