Rust Core¶
The native accelerator is a PyO3 crate at src/crxml_core/.
Crate structure¶
src/crxml_core/
├── Cargo.toml
└── src/
├── lib.rs # CrxmlReader class + thin columnar FFI wrappers
└── xml/ # Crystal Reports XML adapter for rypipe-core
├── decoder.rs # CrystalXmlDecoder implements RecordParser
├── splitter.rs # CrystalXmlSplitter implements Splitter
├── error.rs # adapter error type
└── mod.rs
lib.rs: streaming engine and columnar wrappers¶
lib.rs now contains two parts:
CrxmlReader: the streaming XML parser (remains in crxml).- Thin columnar FFI wrappers:
#[pyfunction]entry points (read_to_columnar,read_to_columnar_multi,read_to_columnar_par,read_to_columnar_bounded) that build anrypipe_core::ExecutionPlanand delegate parsing torypipe-corethrough the embedded Crystal Reports XML adapter insrc/xml/.
CrxmlReader¶
A single Python-exposed class:
#[pyclass]
struct CrxmlReader {
source: PathBuf,
row_tag: String,
buf: Vec<u8>,
inner_buf: Vec<u8>,
}
__iter__, returnsself__next__, reads the next row as aPyDict
The reader walks the XML stream, finds <row_tag> elements, and extracts
field key/value pairs from nested <Field> and <Text> elements.
Dependencies¶
| Crate | Purpose |
|---|---|
pyo3 |
Python bindings |
quick-xml |
Streaming XML reader |
arrow |
Arrow C Data Interface export |
mimalloc |
Fast allocator (replaces system malloc, ~27% CPU savings) |
rypipe-core |
Generic columnar/parallel/bounded engine (from crates.io) |
memchr |
Fast substring scans for the XML splitter |
simdutf8 |
SIMD UTF-8 validation for the XML decoder |
thiserror |
Adapter error derives |
The rypipe-core crate is a versioned dependency resolved from crates.io
(see src/crxml_core/Cargo.toml):
No sibling checkout is required to build crxml. To hack on the engine itself,
clone rypipe separately and point the
dependency at your checkout with a cargo [patch] entry.
Building¶
The pyproject.toml [tool.maturin] section controls the build:
Code style¶
- Rust 2021 edition
cargo fmtfor formattingcargo clippy, no warnings allowed- Unsafe code is denied by default (
#![deny(unsafe_code)])