basexx 0.2.0

basexx utilities. base32, base64, base58, base56...
Documentation
# Design Document - basexx

## 1. Architecture

The `basexx` library follows a modular architecture, with each encoding scheme implemented in its own module. A central `lib.rs` file serves as the main entry point, exporting the public APIs for each module.

### 1.1. Module Structure

The primary modules correspond to the different base encodings:

- `base64`
- `base58`
- `base56`
- `base32`
- `ags`

Additionally, variant implementations exist in separate modules:

- `base64g`
- `base58b`
- `base58r`
- `base32i`

Each module encapsulates the logic for its specific encoding and decoding scheme.

### 1.2. Performance Optimization with SIMD

For performance-critical encodings like Base64 and Base32, the library employs a strategy of runtime CPU feature detection to select the most optimal implementation. The hierarchy of implementations is as follows:

1.  **AVX2:** If the CPU supports AVX2, the AVX2-optimized implementation is used.
2.  **SSSE3:** If AVX2 is not available but SSSE3 is, the SSSE3-optimized version is used.
3.  **Scalar:** If neither AVX2 nor SSSE3 is supported, a fallback scalar implementation is used.

This dynamic dispatch is handled within the main function of each base module (e.g., `Base64::encode`), which checks for CPU features using `is_x86_feature_detected!`. The SIMD-specific code is located in sub-modules within each base's module directory (e.g., `src/base64/base64_avx2.rs`).

## 2. Data Structures

- **`AsciiGraphicSet` (`ags.rs`):** This struct is a core component used by many of the encoding modules. It holds the character set for a given base and provides methods for converting between binary data and the ASCII representation.

- **`BaseXX` Structs (e.g., `Base64`):** Each encoding scheme has a primary struct (e.g., `Base64`, `Base58`) that serves as the main interface for encoding and decoding. These structs typically hold an `AsciiGraphicSet` instance configured with the correct character map for that base.

## 3. Public API

The public API for each encoding scheme is consistent. For a given `BaseXX` struct, the following methods are typically provided:

- **`new()`:** Creates a new instance with the default character set.
- **`with_str(a: &str)` / `with_slice(a: &[u8])`:** Creates a new instance with a custom character set.
- **`encode(a: &[u8]) -> Result<String, EncodeError>`:** Encodes a byte slice into a string.
- **`decode(a: &str) -> Result<Vec<u8>, DecodeError>`:** Decodes a string into a byte vector.

## 4. Error Handling

The library defines two primary error enums:

- **`EncodeError`:** For errors that occur during the encoding process (e.g., an invalid character in the input).
- **`DecodeError`:** For errors that occur during decoding (e.g., invalid byte sequence, incorrect length).

## 5. Feature Flags

The design incorporates the use of feature flags to control optional functionality and dependencies:

- **`rug`:** Conditionally compiles the `base58r` module and includes the `rug` dependency.
- **`bench`, `abench`, `ubench`, `nobench`:** Control the compilation of benchmarking code.
- **`aligned_data`:** Enables functionality related to aligned data structures.

## 6. Testing and Benchmarking

The project has a clear structure for tests and benchmarks:

- **Unit Tests:** Located within each module, often in a `tests` sub-module.
- **Integration Tests:** In the `tests/` directory.
- **Benchmarks:** In the `benches/` directory and also within each module, conditionally compiled with the `bench`-related feature flags.