lightstreamer_rs/utils/
error.rs

1use std::error::Error;
2use std::fmt;
3
4/// Exception thrown when an illegal or inappropriate argument is passed to a method.
5///
6/// This exception indicates that a method has been passed an illegal or inappropriate argument.
7/// It is similar to Java's IllegalArgumentException.
8#[derive(Debug)]
9pub struct IllegalArgumentException(String);
10
11impl IllegalArgumentException {
12    /// Creates a new IllegalArgumentException with the specified detail message.
13    ///
14    /// # Arguments
15    /// * `msg` - The detail message explaining the reason for the exception
16    ///
17    /// # Returns
18    /// A new IllegalArgumentException instance with the specified message
19    pub fn new(msg: &str) -> IllegalArgumentException {
20        IllegalArgumentException(msg.to_string())
21    }
22}
23
24impl fmt::Display for IllegalArgumentException {
25    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26        write!(f, "{}", self.0)
27    }
28}
29
30impl Error for IllegalArgumentException {
31    fn description(&self) -> &str {
32        &self.0
33    }
34}
35
36/// Exception thrown when a method is invoked at an illegal or inappropriate time.
37///
38/// This exception indicates that a method has been invoked at an inappropriate time
39/// or that the object is in an inappropriate state for the requested operation.
40/// It is similar to Java's IllegalStateException.
41#[derive(Debug)]
42pub struct IllegalStateException {
43    details: String,
44}
45
46impl IllegalStateException {
47    /// Creates a new IllegalStateException with the specified detail message.
48    ///
49    /// # Arguments
50    /// * `msg` - The detail message explaining the reason for the exception
51    ///
52    /// # Returns
53    /// A new IllegalStateException instance with the specified message
54    pub fn new(msg: &str) -> IllegalStateException {
55        IllegalStateException {
56            details: msg.to_string(),
57        }
58    }
59}
60
61impl fmt::Display for IllegalStateException {
62    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63        write!(f, "{}", self.details)
64    }
65}
66
67impl Error for IllegalStateException {
68    fn description(&self) -> &str {
69        &self.details
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use std::error::Error;
77
78    // Test trait implementations for IllegalArgumentException
79    #[test]
80    fn test_illegal_argument_exception_creation() {
81        // Create exception with a test message
82        let error_msg = "Test error message";
83        let exception = IllegalArgumentException::new(error_msg);
84
85        // Test that the message is stored correctly
86        assert_eq!(exception.0, error_msg);
87
88        // Test Debug implementation
89        let debug_output = format!("{:?}", exception);
90        assert!(debug_output.contains(error_msg));
91
92        // Test Display implementation
93        let display_output = format!("{}", exception);
94        assert_eq!(display_output, error_msg);
95
96        // Test Error trait implementation
97        let description = exception.to_string();
98        assert_eq!(description, error_msg);
99    }
100
101    // Test trait implementations for IllegalStateException
102    #[test]
103    fn test_illegal_state_exception_creation() {
104        // Create exception with a test message
105        let error_msg = "Test state error";
106        let exception = IllegalStateException::new(error_msg);
107
108        // Test that the message is stored correctly
109        assert_eq!(exception.details, error_msg);
110
111        // Test Debug implementation
112        let debug_output = format!("{:?}", exception);
113        assert!(debug_output.contains(error_msg));
114
115        // Test Display implementation
116        let display_output = format!("{}", exception);
117        assert_eq!(display_output, error_msg);
118
119        // Test Error trait implementation
120        let description = exception.to_string();
121        assert_eq!(description, error_msg);
122    }
123
124    // Test error propagation with ? operator
125    #[test]
126    fn test_error_propagation() {
127        // Helper function that returns IllegalArgumentException
128        fn function_that_fails() -> Result<(), IllegalArgumentException> {
129            Err(IllegalArgumentException::new("Test propagation"))
130        }
131
132        // Function that propagates the error
133        fn propagate_error() -> Result<(), Box<dyn Error>> {
134            function_that_fails()?;
135            Ok(())
136        }
137
138        // Test that the error is propagated correctly
139        let result = propagate_error();
140        assert!(result.is_err());
141        if let Err(boxed_error) = result {
142            let error_message = boxed_error.to_string();
143            assert_eq!(error_message, "Test propagation");
144        }
145    }
146
147    // Test conversion between error types
148    #[test]
149    fn test_error_conversion() {
150        // Create an IllegalArgumentException
151        let arg_exception = IllegalArgumentException::new("Invalid argument");
152
153        // Convert to a Box<dyn Error>
154        let boxed_error: Box<dyn Error> = Box::new(arg_exception);
155
156        // Check that the error message is preserved
157        assert_eq!(boxed_error.to_string(), "Invalid argument");
158
159        // Create an IllegalStateException
160        let state_exception = IllegalStateException::new("Invalid state");
161
162        // Convert to a Box<dyn Error>
163        let boxed_error: Box<dyn Error> = Box::new(state_exception);
164
165        // Check that the error message is preserved
166        assert_eq!(boxed_error.to_string(), "Invalid state");
167    }
168
169    // Test error as a return type
170    #[test]
171    fn test_error_as_return_type() {
172        // Function that returns different error types based on input
173        fn may_fail(value: i32) -> Result<(), Box<dyn Error>> {
174            if value < 0 {
175                Err(Box::new(IllegalArgumentException::new(
176                    "Value cannot be negative",
177                )))
178            } else if value > 100 {
179                Err(Box::new(IllegalStateException::new("Value too large")))
180            } else {
181                Ok(())
182            }
183        }
184
185        // Test negative value (should return IllegalArgumentException)
186        let result = may_fail(-10);
187        assert!(result.is_err());
188        if let Err(error) = result {
189            assert_eq!(error.to_string(), "Value cannot be negative");
190        }
191
192        // Test large value (should return IllegalStateException)
193        let result = may_fail(150);
194        assert!(result.is_err());
195        if let Err(error) = result {
196            assert_eq!(error.to_string(), "Value too large");
197        }
198
199        // Test valid value (should return Ok)
200        let result = may_fail(50);
201        assert!(result.is_ok());
202    }
203
204    // Test using errors with the std::error::Error trait
205    #[test]
206    fn test_error_trait_methods() {
207        // Test with IllegalArgumentException
208        let arg_exception = IllegalArgumentException::new("Test error");
209        let error: &dyn Error = &arg_exception;
210
211        // Test source method (should be None since we don't have a cause)
212        assert!(error.source().is_none());
213
214        // Test description method directly
215        assert_eq!(arg_exception.to_string(), "Test error");
216
217        // Test with IllegalStateException
218        let state_exception = IllegalStateException::new("Test state error");
219        let error: &dyn Error = &state_exception;
220
221        // Test source method (should be None since we don't have a cause)
222        assert!(error.source().is_none());
223
224        // Test description method directly
225        assert_eq!(state_exception.to_string(), "Test state error");
226    }
227
228    // Test Debug formatting for both error types
229    #[test]
230    fn test_debug_formatting() {
231        // Test IllegalArgumentException
232        let arg_exception = IllegalArgumentException::new("Test arg error");
233        let debug_str = format!("{:?}", arg_exception);
234        assert!(debug_str.contains("IllegalArgumentException"));
235        assert!(debug_str.contains("Test arg error"));
236
237        // Test IllegalStateException
238        let state_exception = IllegalStateException::new("Test state error");
239        let debug_str = format!("{:?}", state_exception);
240        assert!(debug_str.contains("IllegalStateException"));
241        assert!(debug_str.contains("Test state error"));
242    }
243}