pix-brcode-parser 0.1.0

A Rust library for parsing and validating Brazilian PIX QR codes (BR Code) following EMV QRCPS standard
Documentation
# PIX BR Code Parser

Uma biblioteca Rust para análise e validação de códigos QR PIX (BR Code) brasileiros seguindo o padrão EMV QRCPS.

[![Crates.io](https://img.shields.io/crates/v/pix-brcode-parser.svg)](https://crates.io/crates/pix-brcode-parser)
[![Documentation](https://docs.rs/pix-brcode-parser/badge.svg)](https://docs.rs/pix-brcode-parser)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE)

## Características

- ✅ Análise de códigos QR PIX estáticos e dinâmicos
- ✅ Validação de conformidade com EMV QRCPS
- ✅ Validação de checksum CRC16
- ✅ API ergonômica com structs tipadas
- ✅ Suporte opcional ao serde para serialização
- ✅ Análise zero-allocation para aplicações críticas de performance
- ✅ Geração de códigos QR PIX
- ✅ Classificação automática de tipos de chave PIX

## Instalação

Adicione ao seu `Cargo.toml`:

```toml
[dependencies]
pix-brcode-parser = "0.1.0"

# Para suporte a serialização
pix-brcode-parser = { version = "0.1.0", features = ["serde"] }
```

## Uso Rápido

### Analisando um Código QR PIX

```rust
use pix_brcode_parser::{parse_brcode, BRCodeError};

fn main() {
    let qr_string = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
    
    match parse_brcode(qr_string) {
        Ok(brcode) => {
            println!("✅ Código PIX válido!");
            println!("Chave PIX: {}", brcode.merchant_account_info.pix_key);
            println!("Tipo da Chave: {:?}", brcode.pix_key_type());
            println!("Comerciante: {}", brcode.merchant_name);
            println!("Cidade: {}", brcode.merchant_city);
            
            if let Some(amount) = &brcode.transaction_amount {
                println!("Valor: R$ {}", amount);
            } else {
                println!("Valor: A ser definido pelo usuário");
            }
            
            println!("Tipo: {}", if brcode.is_static() { "Estático" } else { "Dinâmico" });
        }
        Err(e) => {
            eprintln!("❌ Erro ao analisar código PIX: {}", e);
        }
    }
}
```

### Gerando um Código QR PIX

```rust
use pix_brcode_parser::{BRCode, MerchantAccountInfo, generate_brcode};

fn main() {
    let brcode = BRCode {
        payload_format_indicator: "01".to_string(),
        point_of_initiation_method: Some("11".to_string()), // Estático
        merchant_account_info: MerchantAccountInfo {
            gui: "br.gov.bcb.pix".to_string(),
            pix_key: "user@example.com".to_string(),
            description: Some("Pagamento por serviços".to_string()),
            url: None,
        },
        merchant_category_code: "0000".to_string(),
        transaction_currency: "986".to_string(), // BRL
        transaction_amount: Some("25.50".to_string()),
        country_code: "BR".to_string(),
        merchant_name: "ACME CORP".to_string(),
        merchant_city: "SAO PAULO".to_string(),
        additional_data: None,
        crc16: String::new(), // Será calculado automaticamente
    };
    
    match generate_brcode(&brcode) {
        Ok(qr_string) => {
            println!("Código QR gerado: {}", qr_string);
        }
        Err(e) => {
            eprintln!("Erro ao gerar código: {}", e);
        }
    }
}
```

## Exemplos de Códigos PIX

### Código PIX Estático com Valor Fixo

```rust
// QR Code com valor predefinido de R$ 10,00
let static_qr = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";

let brcode = parse_brcode(static_qr).unwrap();
assert_eq!(brcode.transaction_amount, Some("10.00".to_string()));
assert_eq!(brcode.merchant_name, "FULANO DE TAL");
assert_eq!(brcode.merchant_city, "BRASILIA");
```

### Diferentes Tipos de Chave PIX

```rust
use pix_brcode_parser::{parse_brcode, PixKeyType, classify_pix_key};

// Chave UUID
let uuid_key = "123e4567-e89b-12d3-a456-426614174000";
assert_eq!(classify_pix_key(uuid_key), PixKeyType::Uuid);

// Chave Email
let email_key = "usuario@exemplo.com";
assert_eq!(classify_pix_key(email_key), PixKeyType::Email);

// Chave Telefone
let phone_key = "+5511999999999";
assert_eq!(classify_pix_key(phone_key), PixKeyType::Phone);

// Chave CPF
let cpf_key = "12345678901";
assert_eq!(classify_pix_key(cpf_key), PixKeyType::Cpf);

// Chave CNPJ
let cnpj_key = "12345678000195";
assert_eq!(classify_pix_key(cnpj_key), PixKeyType::Cnpj);
```

### Tratamento de Erros

```rust
use pix_brcode_parser::{parse_brcode, BRCodeError};

let invalid_qr = "codigo_invalido";

match parse_brcode(invalid_qr) {
    Ok(brcode) => println!("Código válido: {:?}", brcode),
    Err(e) => match e {
        BRCodeError::InvalidChecksum => {
            println!("Checksum inválido - código pode estar corrompido");
        }
        BRCodeError::InvalidGui(gui) => {
            println!("GUI inválido: esperado 'br.gov.bcb.pix', encontrado: {}", gui);
        }
        BRCodeError::MissingField(field) => {
            println!("Campo obrigatório ausente: {}", field);
        }
        BRCodeError::InvalidFormat(msg) => {
            println!("Formato inválido: {}", msg);
        }
        _ => {
            println!("Erro: {}", e);
        }
    }
}
```

### Validação de Campos

```rust
use pix_brcode_parser::parse_brcode;

// Exemplo com nome do comerciante muito longo (máximo 25 caracteres)
let long_name_qr = "..."; // QR code com nome > 25 chars

match parse_brcode(long_name_qr) {
    Err(BRCodeError::FieldTooLong { tag, max_length, actual_length }) => {
        println!("Campo {} muito longo: máximo {}, atual {}", tag, max_length, actual_length);
    }
    _ => {}
}
```

### Serialização com Serde (Feature Opcional)

```rust
#[cfg(feature = "serde")]
{
    use serde_json;
    
    let qr_string = "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540510.005802BR5913FULANO DE TAL6008BRASILIA62070503***630436D9";
    let brcode = parse_brcode(qr_string).unwrap();
    
    // Serializar para JSON
    let json = serde_json::to_string(&brcode).unwrap();
    println!("JSON: {}", json);
    
    // Deserializar de JSON
    let brcode_from_json: BRCode = serde_json::from_str(&json).unwrap();
    assert_eq!(brcode, brcode_from_json);
}
```

## Estrutura dos Dados

### BRCode Principal

```rust
pub struct BRCode {
    pub payload_format_indicator: String,      // Sempre "01"
    pub point_of_initiation_method: Option<String>, // "11" = estático, "12" = dinâmico
    pub merchant_account_info: MerchantAccountInfo,
    pub merchant_category_code: String,        // Código da categoria do comerciante
    pub transaction_currency: String,          // "986" para BRL
    pub transaction_amount: Option<String>,    // Valor da transação
    pub country_code: String,                  // "BR"
    pub merchant_name: String,                 // Nome do comerciante (máx 25 chars)
    pub merchant_city: String,                 // Cidade (máx 15 chars)
    pub additional_data: Option<AdditionalData>,
    pub crc16: String,                        // Checksum CRC16
}
```

### Informações da Conta PIX

```rust
pub struct MerchantAccountInfo {
    pub gui: String,                          // "br.gov.bcb.pix"
    pub pix_key: String,                      // Chave PIX
    pub description: Option<String>,          // Descrição opcional
    pub url: Option<String>,                  // URL para QR dinâmicos
}
```

### Dados Adicionais

```rust
pub struct AdditionalData {
    pub bill_number: Option<String>,
    pub mobile_number: Option<String>,
    pub store_label: Option<String>,
    pub loyalty_number: Option<String>,
    pub reference_label: Option<String>,      // Etiqueta de referência
    pub customer_label: Option<String>,
    pub terminal_label: Option<String>,
    pub purpose_of_transaction: Option<String>,
    pub additional_consumer_data_request: Option<String>,
}
```

## Validações Implementadas

- **Checksum CRC16**: Validação completa usando CRC-16/CCITT-FALSE
-**GUI PIX**: Deve ser "br.gov.bcb.pix"
-**Código da Moeda**: Deve ser "986" (Real Brasileiro)
-**Código do País**: Deve ser "BR"
-**Indicador de Formato**: Deve ser "01"
-**Limites de Campo**: 
  - Nome do comerciante: máximo 25 caracteres
  - Cidade: máximo 15 caracteres
  - Etiqueta de referência: máximo 25 caracteres
-**Formato da Chave PIX**: Validação básica de caracteres

## Executando os Exemplos

```bash
# Exemplo de análise
cargo run --example parse_pix_qr

# Exemplo de geração
cargo run --example generate_pix_qr
```

## Executando os Testes

```bash
# Testes unitários
cargo test --lib

# Todos os testes
cargo test

# Com saída detalhada
cargo test -- --nocapture
```

## Compatibilidade

- **Rust**: 1.70+
- **Plataformas**: Windows, Linux, macOS
- **Arquiteturas**: x86_64, ARM64

## Licença

Dual licensed under MIT OR Apache-2.0.

## Contribuindo

Contribuições são bem-vindas! Por favor:

1. Fork o repositório
2. Crie uma branch para sua feature
3. Adicione testes para novas funcionalidades
4. Execute `cargo test` para garantir que tudo funciona
5. Envie um Pull Request

## Recursos Úteis

- [Manual BR Code - Banco Central]https://www.bcb.gov.br/content/estabilidadefinanceira/spb_docs/ManualBRCode.pdf
- [EMV QR Code Specification]https://www.emvco.com/emv-technologies/qrcodes/
- [PIX - Banco Central do Brasil]https://www.bcb.gov.br/estabilidadefinanceira/pix

---

*Esta biblioteca foi desenvolvida para facilitar a integração com o sistema PIX brasileiro, seguindo rigorosamente os padrões EMV QRCPS e as especificações do Banco Central do Brasil.*