pix-brcode-parser 0.1.0

A Rust library for parsing and validating Brazilian PIX QR codes (BR Code) following EMV QRCPS standard
Documentation
//! Error types for PIX BR Code parsing

use thiserror::Error;

/// Errors that can occur during BR Code parsing and validation
#[derive(Error, Debug, PartialEq)]
pub enum BRCodeError {
    /// Invalid or malformed QR code format
    #[error("Invalid QR code format: {0}")]
    InvalidFormat(String),
    
    /// Missing required field
    #[error("Missing required field: {0}")]
    MissingField(String),
    
    /// Invalid field length
    #[error("Invalid field length for tag {tag}: expected {expected}, got {actual}")]
    InvalidFieldLength {
        tag: String,
        expected: usize,
        actual: usize,
    },
    
    /// Invalid field value
    #[error("Invalid field value for tag {tag}: {value}")]
    InvalidFieldValue {
        tag: String,
        value: String,
    },
    
    /// CRC16 checksum validation failed
    #[error("CRC16 checksum validation failed")]
    InvalidChecksum,
    
    /// Invalid PIX key format
    #[error("Invalid PIX key format: {0}")]
    InvalidPixKey(String),
    
    /// Invalid GUI (should be "br.gov.bcb.pix")
    #[error("Invalid GUI: expected 'br.gov.bcb.pix', got '{0}'")]
    InvalidGui(String),
    
    /// Invalid currency code (should be "986" for BRL)
    #[error("Invalid currency code: expected '986', got '{0}'")]
    InvalidCurrency(String),
    
    /// Invalid country code (should be "BR")
    #[error("Invalid country code: expected 'BR', got '{0}'")]
    InvalidCountryCode(String),
    
    /// Invalid payload format indicator
    #[error("Invalid payload format indicator: expected '01', got '{0}'")]
    InvalidPayloadFormat(String),
    
    /// Field value too long
    #[error("Field value too long for tag {tag}: max {max_length}, got {actual_length}")]
    FieldTooLong {
        tag: String,
        max_length: usize,
        actual_length: usize,
    },
    
    /// Parsing error for numeric fields
    #[error("Failed to parse numeric value: {0}")]
    ParseNumericError(String),
    
    /// Unsupported QR code version or features
    #[error("Unsupported feature: {0}")]
    UnsupportedFeature(String),
    
    /// TLV parsing error
    #[error("TLV parsing error: {0}")]
    TlvParsingError(String),
}

impl BRCodeError {
    /// Create a new invalid format error
    pub fn invalid_format<T: Into<String>>(msg: T) -> Self {
        Self::InvalidFormat(msg.into())
    }
    
    /// Create a new missing field error
    pub fn missing_field<T: Into<String>>(field: T) -> Self {
        Self::MissingField(field.into())
    }
    
    /// Create a new invalid field value error
    pub fn invalid_field_value<T: Into<String>, V: Into<String>>(tag: T, value: V) -> Self {
        Self::InvalidFieldValue {
            tag: tag.into(),
            value: value.into(),
        }
    }
    
    /// Create a new field too long error
    pub fn field_too_long<T: Into<String>>(tag: T, max_length: usize, actual_length: usize) -> Self {
        Self::FieldTooLong {
            tag: tag.into(),
            max_length,
            actual_length,
        }
    }
}

pub type Result<T> = std::result::Result<T, BRCodeError>;