ruuvi_decoders/
error.rs

1//! Error types for Ruuvi decoders
2
3use thiserror::Error;
4
5/// Result type alias for decoder operations
6pub type Result<T> = std::result::Result<T, DecodeError>;
7
8/// Errors that can occur during Ruuvi data decoding
9#[derive(Error, Debug, Clone, PartialEq)]
10pub enum DecodeError {
11    /// Invalid hex string format
12    #[error("Invalid hex string: {0}")]
13    InvalidHex(String),
14
15    /// Data length is invalid for the format
16    #[error("Invalid data length: {0}")]
17    InvalidLength(String),
18
19    /// Unsupported data format
20    #[error("Unsupported data format: 0x{0:02X}")]
21    UnsupportedFormat(u8),
22
23    /// Invalid data values (e.g., reserved values that indicate invalid readings)
24    #[error("Invalid data values: {0}")]
25    InvalidData(String),
26
27    /// Checksum or validation failed
28    #[error("Validation failed: {0}")]
29    ValidationFailed(String),
30
31    /// Decryption failed (for encrypted formats like E1)
32    #[error("Decryption failed: {0}")]
33    DecryptionFailed(String),
34
35    /// Missing required fields
36    #[error("Missing required field: {0}")]
37    MissingField(String),
38}
39
40impl DecodeError {
41    /// Create a new `InvalidLength` error
42    #[must_use]
43    pub fn invalid_length(expected: usize, actual: usize) -> Self {
44        Self::InvalidLength(format!("Expected {expected} bytes, got {actual}"))
45    }
46
47    /// Create a new `InvalidData` error for a specific field
48    #[must_use]
49    pub fn invalid_field(field: &str, value: &str) -> Self {
50        Self::InvalidData(format!("Invalid {field} value: {value}"))
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_error_display() {
60        let err = DecodeError::UnsupportedFormat(99);
61        assert_eq!(err.to_string(), "Unsupported data format: 0x63");
62
63        let err = DecodeError::invalid_length(24, 20);
64        assert_eq!(
65            err.to_string(),
66            "Invalid data length: Expected 24 bytes, got 20"
67        );
68
69        let err = DecodeError::invalid_field("temperature", "-163.84");
70        assert_eq!(
71            err.to_string(),
72            "Invalid data values: Invalid temperature value: -163.84"
73        );
74    }
75
76    #[test]
77    fn test_error_equality() {
78        let err1 = DecodeError::UnsupportedFormat(5);
79        let err2 = DecodeError::UnsupportedFormat(5);
80        let err3 = DecodeError::UnsupportedFormat(6);
81
82        assert_eq!(err1, err2);
83        assert_ne!(err1, err3);
84    }
85}