use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
pub enum BRCodeError {
#[error("Invalid QR code format: {0}")]
InvalidFormat(String),
#[error("Missing required field: {0}")]
MissingField(String),
#[error("Invalid field length for tag {tag}: expected {expected}, got {actual}")]
InvalidFieldLength {
tag: String,
expected: usize,
actual: usize,
},
#[error("Invalid field value for tag {tag}: {value}")]
InvalidFieldValue {
tag: String,
value: String,
},
#[error("CRC16 checksum validation failed")]
InvalidChecksum,
#[error("Invalid PIX key format: {0}")]
InvalidPixKey(String),
#[error("Invalid GUI: expected 'br.gov.bcb.pix', got '{0}'")]
InvalidGui(String),
#[error("Invalid currency code: expected '986', got '{0}'")]
InvalidCurrency(String),
#[error("Invalid country code: expected 'BR', got '{0}'")]
InvalidCountryCode(String),
#[error("Invalid payload format indicator: expected '01', got '{0}'")]
InvalidPayloadFormat(String),
#[error("Field value too long for tag {tag}: max {max_length}, got {actual_length}")]
FieldTooLong {
tag: String,
max_length: usize,
actual_length: usize,
},
#[error("Failed to parse numeric value: {0}")]
ParseNumericError(String),
#[error("Unsupported feature: {0}")]
UnsupportedFeature(String),
#[error("TLV parsing error: {0}")]
TlvParsingError(String),
}
impl BRCodeError {
pub fn invalid_format<T: Into<String>>(msg: T) -> Self {
Self::InvalidFormat(msg.into())
}
pub fn missing_field<T: Into<String>>(field: T) -> Self {
Self::MissingField(field.into())
}
pub fn invalid_field_value<T: Into<String>, V: Into<String>>(tag: T, value: V) -> Self {
Self::InvalidFieldValue {
tag: tag.into(),
value: value.into(),
}
}
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>;