Documentos fiscais brasileiros (NF-e / NFC-e) com a segurança de tipos e performance do Rust. Uma lib, todos os runtimes via FFI.
A História
O sped-nfe em PHP é a referência do mercado — 2.400+ stars, usado em produção por milhares de empresas no Brasil. Portamos ele primeiro para TypeScript no projeto FinOpenPOS.
Mas a pergunta ficou: e se em vez de manter uma versão por linguagem, a gente escrevesse uma única vez em Rust e exportasse via FFI para Python, Node.js, WebAssembly, Android, iOS?
O fiscal-rs nasceu dessa ideia. Portamos 640+ testes do PHP/TypeScript primeiro, depois implementamos até todos passarem. Zero float-point drift (centavos como inteiros), typestate pattern no InvoiceBuilder, newtypes validados, assinatura XML-DSig nativa sem hacks de child_process.
No caminho, contribuímos de volta: enviamos 370 testes para o sped-nfe original (PR #1313, mergeado), elevando a cobertura de 40% para 86,5%. Durante esse processo, encontramos e corrigimos bugs latentes que estavam lá há anos. Não é só paridade — é evolução mútua.
Funcionalidades
Modelos 55 e 65 com builder typestate: Draft → Built → Signed. Erros impossíveis em tempo de compilação.
Certificado A1 (PFX) com OpenSSL nativo. XML-DSig, C14N, RSA-SHA1 — sem shell scripts.
URLs por estado, envelopes SOAP, parsers de resposta, client HTTP async com mTLS.
Valores monetários em centavos (i64). Alíquotas em Rate/Rate4. Sem surpresas de ponto flutuante.
TaxId, Gtin, Ncm, Cfop — parse, don't validate. Estados inválidos irrepresentáveis.
Uma lib Rust → PyO3, napi-rs, wasm-bindgen, UniFFI. Qualquer runtime, uma única base de código.
Performance
Docker containers idênticos: 1 CPU, 512 MB RAM. Mesmas operações, mesmos dados. Metodologia completa →
| Operação | Rust | Bun | PHP | Rust vs PHP |
|---|---|---|---|---|
| invoice_builder | 27 µs | 49 µs | 427 µs | 16x |
| sign_xml | 996 µs | 1.9 ms | 3.4 ms | 3.4x |
| tag_nested_item | 3.0 µs | 7.0 µs | 9.7 µs | 3.2x |
| serialize_icms00 | 829 ns | 1.0 µs | 3.3 µs | 4.0x |
| tag_simple_text | 122 ns | 224 ns | 1.0 µs | 8.5x |
| escape_xml_clean | 40 ns | 111 ns | 124 ns | 3.1x |
Comparação
| Feature | nfe | Rust-Nfe-API | Fiscalidade | fiscal-rs |
|---|---|---|---|---|
| NF-e (modelo 55) | Structs | Parse | Transmit | ✓ |
| NFC-e (modelo 65) | — | ✓ | ? | ✓ |
| Geração XML 4.00 | — | ✓ | — | ✓ |
| SEFAZ mTLS | — | — | ✓ | ✓ |
| Certificado PFX/X.509 | — | — | ✓ | ✓ |
| XMLDSig C14N | — | — | ✓ | ✓ |
| Todos os impostos | — | — | — | ✓ |
| Contingência | — | — | — | ✓ |
| QR Code NFC-e | — | — | — | ✓ |
| Eventos (cancel/CCe) | — | — | — | ✓ |
| TXT → XML | — | — | — | ✓ |
| Testes | Few | Some | Some | 739+ |
Quick Start
fiscal-rs é open source e aceita contribuições. Dê uma estrela, abra uma issue, ou envie um PR.