Metadata-Version: 2.4
Name: rs-turboyaml
Version: 0.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Text Processing :: Markup
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
License-File: LICENSE
Summary: A YAML 1.2 subset parser built for speed, written in Rust.
Keywords: yaml,parser,rust,fast,serialization
Author-email: "lemon-nades.net" <alex.riehm@gmail.com>
License-Expression: BSD-2-Clause
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://git.lemon-nades.net/Alrie/turboyaml
Project-URL: Issues, https://git.lemon-nades.net/Alrie/turboyaml/issues
Project-URL: Repository, https://git.lemon-nades.net/Alrie/turboyaml

# TurboYAML

Subset of YAML 1.2, built for parsing speed. A Rust parser with Rust and Python bindings.

**Valid TurboYAML is always valid YAML 1.2.** The reverse need not hold — so parse with TurboYAML and fall back to a full YAML parser when you hit something it deliberately doesn't support.

## Why

TurboYAML tries to trade YAML's feature richness for speed, while keeping a useful featue set alive. 
On typical config and data it parses roughly **25–50× faster than PyYAML's libyaml C extension**, producing native Python objects (`dict` / `list` / `str` / `int` / `float` / `bool` / `None`) directly — no intermediate tree.

| Profile | turboyaml (Python) | PyYAML (libyaml) | speedup |
|---|---|---|---|
| Flat records | 11M lines/s | 360k lines/s | 31× |
| Deep tree | 3.9M lines/s | 99k lines/s | 39× |
| Inline flow collections | 1.7M lines/s | 32k lines/s | 53× |
| Block scalars | 6.9M lines/s | 210k lines/s | 33× |

*Measured on one machine; reproduce with `cargo run --release --features gen --bin perf_test && python perf_test.py`.*

## Install

```sh
pip install rs-turboyaml
```

The PyPI distribution is `rs-turboyaml`; the import name is `turboyaml`.

## Usage

### Python

```python
import turboyaml

obj = turboyaml.load(text)   # → dict / list / str / int / float / bool / None
```

Catch `UnsupportedFeatureError` to fall back to a full parser when a document uses
something TurboYAML doesn't cover:

```python
try:
    obj = turboyaml.load(text)
except turboyaml.UnsupportedFeatureError:
    import yaml
    obj = yaml.safe_load(text)
```

### Rust

```rust
let value = turboyaml::parse(input)?;
```

## Supported

- Block **mappings** and **sequences**, arbitrarily nested
- Compact notation — `- key: value`, `- - nested`
- **Scalar type inference**: `null`/`~`, `True`/`False`, integers (decimal / `0x` / `0o`), floats (incl. `.inf` / `.nan`), strings
- **Double-quoted** strings (single line, literal content)
- **Flow collections** — `[1, 2]`, `{a: 1}` — single-line, nestable
- **Block scalars** — `|` literal and `>` folded, with `+` / `-` chomping
- `#` comments
- Any scalar type as a mapping key (`42:`, `True:`, `null:`)
- Optional duplicate-key rejection — `load(text, strict=True)` / `parse_strict`

### Notable differences from full YAML 1.2

- **2-space indentation only** — no tabs, no other widths.
- **Python-convention booleans**: `True`/`False` are bool; lowercase `true`/`false` are **strings** (as are YAML 1.1's `yes`/`no`/`on`/`off`).
- **No escape sequences** in quoted strings — content is literal UTF-8.
- **One document per stream**; UTF-8 only, no BOM.

## Not supported

These raise a typed `UnsupportedFeatureError` — distinct from a malformed-input `ParseError` — so the fallback pattern above can recover them cleanly:

- Anchors and aliases — `&anchor`, `*alias`
- Tags — `!!str`, `!custom`
- Document markers (`---`, `...`) and directives (`%YAML`)
- Explicit block indentation indicators — `|2`

Multi-document streams and multi-line quoted strings are also out of scope (for multi-line text, use a block scalar).

## Status

Alpha. The base feature set plus block scalars are implemented and tested — including a differential fuzz of folding/chomping against PyYAML. YAML 1.1 boolean tokens are the one remaining roadmap item. See [spec.md](spec.md) for the normative specification.

Built with [PyO3](https://pyo3.rs) + [maturin](https://maturin.rs).

