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}