# TOON Python API

TOON (Token-Oriented Object Notation) 是一个紧凑的、人类可读的数据格式，专为减少传递给大型语言模型的令牌使用量而设计。相比 JSON 格式，TOON 可以减少 30-60% 的令牌使用量。

本项目提供了一个 Python API 工具库，后端采用 Rust 实现，通过 PyO3 提供高性能的 Python 绑定。

## 特性

- ✅ **编码和解码**：支持 Python 对象与 TOON 格式之间的双向转换
- ✅ **表格格式优化**：自动识别统一结构的对象数组，使用表格格式压缩
- ✅ **多种数组格式**：支持内联数组、表格数组、列表数组和数组的数组
- ✅ **嵌套结构**：完全支持嵌套对象和数组
- ✅ **自定义选项**：支持自定义缩进、分隔符和长度标记
- ✅ **高性能**：Rust 后端提供快速的编码/解码性能

## 安装

### 方式一：从源码安装（推荐）

```bash
# 直接使用 pip 从源码安装
pip install .

# 或者从 Git 仓库安装
pip install git+https://github.com/your-username/tost.git
```

**前置要求：**
- Python 3.8+
- Rust 1.70+ (pip 会自动安装 maturin 用于构建)
- Cargo (Rust 构建工具)

### 方式二：开发模式安装

```bash
# 安装 Rust (如果尚未安装)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装 maturin
pip install maturin

# 开发模式安装 (推荐用于开发)
maturin develop

# 或者构建轮子文件
maturin build --release
```

## 使用示例

### 基本编码

```python
from tost import encode

# 简单对象
obj = {
    "id": 123,
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "active": True
}

result = encode(obj)
print(result)
# 输出:
# id: 123
# name: Ada Lovelace
# email: ada@example.com
# active: true
```

### 表格格式数组

```python
from tost import encode

# 表格格式数组（自动优化）
products = {
    "items": [
        {"sku": "LAPTOP-15", "qty": 5, "price": 899.99},
        {"sku": "MOUSE-BT", "qty": 25, "price": 29.99},
        {"sku": "KEYBOARD-MX", "qty": 12, "price": 149.00}
    ]
}

result = encode(products)
print(result)
# 输出:
# items[3]{sku,qty,price}:
#   LAPTOP-15,5,899.99
#   MOUSE-BT,25,29.99
#   KEYBOARD-MX,12,149
```

### 内联数组

```python
from tost import encode

# 内联数组（原始类型数组）
tags = {
    "tags": ["javascript", "typescript", "nodejs", "llm"]
}

result = encode(tags)
print(result)
# 输出:
# tags[4]: javascript,typescript,nodejs,llm
```

### 嵌套结构

```python
from tost import encode

order = {
    "orderId": "ORD-2025-001",
    "customer": {
        "name": "John Smith",
        "email": "john@example.com"
    },
    "items": [
        {"product": "Widget A", "quantity": 2, "price": 19.99},
        {"product": "Widget B", "quantity": 1, "price": 34.50}
    ],
    "total": 74.48,
    "tags": ["priority", "gift-wrap"]
}

result = encode(order)
print(result)
# 输出:
# orderId: ORD-2025-001
# customer:
#   name: John Smith
#   email: john@example.com
# items[2]{product,quantity,price}:
#   Widget A,2,19.99
#   Widget B,1,34.5
# total: 74.48
# tags[2]: priority,gift-wrap
```

### 解码

```python
from tost import decode

tost_str = """
id: 123
name: Ada Lovelace
active: true
items[2]{sku,qty}:
  A1,2
  B2,1
"""

result = decode(tost_str)
print(result)
# 输出:
# {
#     'id': 123,
#     'name': 'Ada Lovelace',
#     'active': True,
#     'items': [
#         {'sku': 'A1', 'qty': 2},
#         {'sku': 'B2', 'qty': 1}
#     ]
# }
```

### 自定义选项

```python
from tost import encode

obj = {
    "items": [
        {"sku": "A1", "qty": 2},
        {"sku": "B2", "qty": 1}
    ]
}

# 自定义缩进、分隔符和长度标记
result = encode(
    obj,
    indent=4,           # 4 空格缩进
    delimiter="|",       # 使用管道符作为分隔符
    length_marker="#"     # 使用 # 作为长度标记
)
print(result)
# 输出:
# items[#2|]{sku|qty}:
#     A1|2
#     B2|1
```

## API 参考

### `encode(obj, indent=2, delimiter=",", length_marker=None)`

将 Python 对象编码为 TOON 格式字符串。

**参数：**
- `obj`: 要编码的 Python 对象（dict、list、原始类型等）
- `indent` (int, 可选): 每个缩进级别的空格数（默认：2）
- `delimiter` (str, 可选): 数组值和表格行的分隔符（默认：','）
- `length_marker` (str, 可选): 数组长度前缀标记（例如：'#'）

**返回：**
- `str`: TOON 格式的字符串

**示例：**
```python
result = encode({"id": 123, "name": "Alice"})
result = encode(obj, indent=4, delimiter="|", length_marker="#")
```

### `decode(tost_str)`

将 TOON 格式字符串解码为 Python 对象。

**参数：**
- `tost_str` (str): TOON 格式的字符串

**返回：**
- Python 对象（dict、list 或原始类型）

**示例：**
```python
obj = decode("id: 123\nname: Alice")
```

## TOON 格式说明

### 对象格式

```
key: value
```

### 表格数组格式

当数组中的所有对象具有相同的键且所有值都是原始类型时，使用表格格式：

```
items[N]{field1,field2,field3}:
  value1,value2,value3
  value4,value5,value6
```

### 内联数组格式

原始类型数组使用内联格式：

```
tags[N]: value1,value2,value3
```

### 列表格式

混合或非统一数组使用列表格式：

```
items[N]:
  - value1
  - key: value
    other: value2
  - value3
```

### 数组的数组格式

```
pairs[N]:
  - [M]: value1,value2
  - [M]: value3,value4
```

### 根级数组

当根级值是数组时，使用无键名的头部形式：

```
[N]{field1,field2}:
  value1,value2
  value3,value4
```

或对于原始类型数组：

```
[N]: value1,value2,value3
```

## 项目结构

```
tost/
├── Cargo.toml              # Rust 工作空间配置
├── pyproject.toml          # Python 包配置
├── README.md                # 项目文档
├── rust/                    # Rust 核心库
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs          # 主库文件（包含 PyO3 绑定）
│       ├── encode.rs       # TOON 编码实现
│       └── decode.rs        # TOON 解码实现
└── python/                  # Python 包
    ├── src/
    │   └── tost/           # Python 包
    │       ├── __init__.py
    │       └── tost.py     # Python 接口封装
    └── tests/              # Python 测试
        └── test_tost.py
```

## 开发

### 运行测试

```bash
# Rust 测试
cd rust
cargo test

# Python 测试
cd python
pytest tests/
```

### 构建

```bash
# 开发模式
maturin develop

# 发布模式
maturin build --release
```

## 许可证

MIT License

## 参考

- [TOON 格式规范](https://github.com/toon-format/toon)
- [PyO3 文档](https://pyo3.rs/)
- [maturin 文档](https://maturin.rs/)
