pix_brcode_parser/
lib.rs

1//! # PIX BR Code Parser
2//!
3//! Uma biblioteca Rust para análise e validação de códigos QR PIX (BR Code) brasileiros 
4//! seguindo o padrão EMV QRCPS (QR Code Payment System).
5//!
6//! ## Características
7//!
8//! - Análise de códigos QR PIX estáticos e dinâmicos
9//! - Validação de conformidade com EMV QRCPS
10//! - Validação de checksum CRC16
11//! - API ergonômica com structs tipadas
12//! - Suporte opcional ao serde para serialização
13//! - Análise zero-allocation para aplicações críticas de performance
14//! - Geração de códigos QR PIX
15//! - Classificação automática de tipos de chave PIX
16//!
17//! ## Início Rápido
18//!
19//! ### Analisando um Código PIX
20//!
21//! ```rust
22//! use pix_brcode_parser::{parse_brcode, BRCodeError};
23//!
24//! let qr_string = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
25//! 
26//! match parse_brcode(qr_string) {
27//!     Ok(brcode) => {
28//!         println!("✅ Código PIX válido!");
29//!         println!("Chave PIX: {}", brcode.merchant_account_info.pix_key);
30//!         println!("Tipo da Chave: {:?}", brcode.pix_key_type());
31//!         println!("Comerciante: {}", brcode.merchant_name);
32//!         println!("Cidade: {}", brcode.merchant_city);
33//!         
34//!         if let Some(amount) = &brcode.transaction_amount {
35//!             println!("Valor: R$ {}", amount);
36//!         } else {
37//!             println!("Valor: A ser definido pelo usuário");
38//!         }
39//!     }
40//!     Err(e) => eprintln!("❌ Erro ao analisar código PIX: {}", e),
41//! }
42//! ```
43//!
44//! ### Gerando um Código PIX
45//!
46//! ```rust
47//! use pix_brcode_parser::{BRCode, MerchantAccountInfo, generate_brcode};
48//!
49//! let brcode = BRCode {
50//!     payload_format_indicator: "01".to_string(),
51//!     point_of_initiation_method: Some("11".to_string()), // Estático
52//!     merchant_account_info: MerchantAccountInfo {
53//!         gui: "br.gov.bcb.pix".to_string(),
54//!         pix_key: "user@example.com".to_string(),
55//!         description: Some("Pagamento por serviços".to_string()),
56//!         url: None,
57//!     },
58//!     merchant_category_code: "0000".to_string(),
59//!     transaction_currency: "986".to_string(), // BRL
60//!     transaction_amount: Some("25.50".to_string()),
61//!     country_code: "BR".to_string(),
62//!     merchant_name: "ACME CORP".to_string(),
63//!     merchant_city: "SAO PAULO".to_string(),
64//!     additional_data: None,
65//!     crc16: String::new(), // Será calculado automaticamente
66//! };
67//! 
68//! match generate_brcode(&brcode) {
69//!     Ok(qr_string) => {
70//!         println!("Código QR gerado: {}", qr_string);
71//!     }
72//!     Err(e) => {
73//!         eprintln!("Erro ao gerar código: {}", e);
74//!     }
75//! }
76//! ```
77//!
78//! ### Tipos de Chave PIX
79//!
80//! ```rust
81//! use pix_brcode_parser::{classify_pix_key, PixKeyType};
82//!
83//! // Diferentes tipos de chave PIX suportados
84//! assert_eq!(classify_pix_key("123e4567-e89b-12d3-a456-426614174000"), PixKeyType::Uuid);
85//! assert_eq!(classify_pix_key("usuario@exemplo.com"), PixKeyType::Email);
86//! assert_eq!(classify_pix_key("+5511999999999"), PixKeyType::Phone);
87//! assert_eq!(classify_pix_key("12345678901"), PixKeyType::Cpf);
88//! assert_eq!(classify_pix_key("12345678000195"), PixKeyType::Cnpj);
89//! ```
90//!
91//! ## Tratamento de Erros
92//!
93//! ```rust
94//! use pix_brcode_parser::{parse_brcode, BRCodeError};
95//!
96//! match parse_brcode("codigo_invalido") {
97//!     Err(BRCodeError::InvalidChecksum) => {
98//!         println!("Checksum inválido - código pode estar corrompido");
99//!     }
100//!     Err(BRCodeError::InvalidGui(gui)) => {
101//!         println!("GUI inválido: esperado 'br.gov.bcb.pix', encontrado: {}", gui);
102//!     }
103//!     Err(BRCodeError::MissingField(field)) => {
104//!         println!("Campo obrigatório ausente: {}", field);
105//!     }
106//!     _ => {}
107//! }
108//! ```
109//!
110//! ## Validações
111//!
112//! Esta biblioteca implementa todas as validações necessárias:
113//!
114//! - **Checksum CRC16**: Validação completa usando CRC-16/CCITT-FALSE
115//! - **GUI PIX**: Deve ser "br.gov.bcb.pix"
116//! - **Código da Moeda**: Deve ser "986" (Real Brasileiro)  
117//! - **Código do País**: Deve ser "BR"
118//! - **Limites de Campo**: Nome do comerciante (25 chars), cidade (15 chars)
119//! - **Formato da Chave PIX**: Validação de caracteres e formato
120
121pub mod error;
122pub mod parser;
123pub mod types;
124pub mod validation;
125
126pub use error::BRCodeError;
127pub use parser::{parse_brcode, generate_brcode};
128pub use types::*;
129pub use validation::validate_crc16;
130
131/// Parse a PIX BR Code string into a structured format
132pub fn parse(input: &str) -> Result<BRCode, BRCodeError> {
133    parse_brcode(input)
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn test_valid_static_pix_qr() {
142        let qr = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
143        let result = parse_brcode(qr);
144        assert!(result.is_ok());
145    }
146
147    #[test]
148    fn test_invalid_crc() {
149        let qr = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***6304ABCD";
150        let result = parse_brcode(qr);
151        assert!(matches!(result, Err(BRCodeError::InvalidChecksum)));
152    }
153}