pix_brcode_parser/
error.rs

1//! Error types for PIX BR Code parsing
2
3use thiserror::Error;
4
5/// Errors that can occur during BR Code parsing and validation
6#[derive(Error, Debug, PartialEq)]
7pub enum BRCodeError {
8    /// Invalid or malformed QR code format
9    #[error("Invalid QR code format: {0}")]
10    InvalidFormat(String),
11    
12    /// Missing required field
13    #[error("Missing required field: {0}")]
14    MissingField(String),
15    
16    /// Invalid field length
17    #[error("Invalid field length for tag {tag}: expected {expected}, got {actual}")]
18    InvalidFieldLength {
19        tag: String,
20        expected: usize,
21        actual: usize,
22    },
23    
24    /// Invalid field value
25    #[error("Invalid field value for tag {tag}: {value}")]
26    InvalidFieldValue {
27        tag: String,
28        value: String,
29    },
30    
31    /// CRC16 checksum validation failed
32    #[error("CRC16 checksum validation failed")]
33    InvalidChecksum,
34    
35    /// Invalid PIX key format
36    #[error("Invalid PIX key format: {0}")]
37    InvalidPixKey(String),
38    
39    /// Invalid GUI (should be "br.gov.bcb.pix")
40    #[error("Invalid GUI: expected 'br.gov.bcb.pix', got '{0}'")]
41    InvalidGui(String),
42    
43    /// Invalid currency code (should be "986" for BRL)
44    #[error("Invalid currency code: expected '986', got '{0}'")]
45    InvalidCurrency(String),
46    
47    /// Invalid country code (should be "BR")
48    #[error("Invalid country code: expected 'BR', got '{0}'")]
49    InvalidCountryCode(String),
50    
51    /// Invalid payload format indicator
52    #[error("Invalid payload format indicator: expected '01', got '{0}'")]
53    InvalidPayloadFormat(String),
54    
55    /// Field value too long
56    #[error("Field value too long for tag {tag}: max {max_length}, got {actual_length}")]
57    FieldTooLong {
58        tag: String,
59        max_length: usize,
60        actual_length: usize,
61    },
62    
63    /// Parsing error for numeric fields
64    #[error("Failed to parse numeric value: {0}")]
65    ParseNumericError(String),
66    
67    /// Unsupported QR code version or features
68    #[error("Unsupported feature: {0}")]
69    UnsupportedFeature(String),
70    
71    /// TLV parsing error
72    #[error("TLV parsing error: {0}")]
73    TlvParsingError(String),
74}
75
76impl BRCodeError {
77    /// Create a new invalid format error
78    pub fn invalid_format<T: Into<String>>(msg: T) -> Self {
79        Self::InvalidFormat(msg.into())
80    }
81    
82    /// Create a new missing field error
83    pub fn missing_field<T: Into<String>>(field: T) -> Self {
84        Self::MissingField(field.into())
85    }
86    
87    /// Create a new invalid field value error
88    pub fn invalid_field_value<T: Into<String>, V: Into<String>>(tag: T, value: V) -> Self {
89        Self::InvalidFieldValue {
90            tag: tag.into(),
91            value: value.into(),
92        }
93    }
94    
95    /// Create a new field too long error
96    pub fn field_too_long<T: Into<String>>(tag: T, max_length: usize, actual_length: usize) -> Self {
97        Self::FieldTooLong {
98            tag: tag.into(),
99            max_length,
100            actual_length,
101        }
102    }
103}
104
105pub type Result<T> = std::result::Result<T, BRCodeError>;