serde_nt
NestedText (de)serialization for serde.
NestedText is a human-friendly configuration and data format: key: value
dictionaries, - item lists and > text blocks, with no quoting and no
escaping, and with every leaf stored as a string. This crate maps that data
model onto Rust types through serde, in both directions.
- Parses straight into your types, borrowed (
&str,Cow<'_, str>) or owned. - Writes back with a stable, human-readable layout (2-space indent,
>blocks for multiline values, multiline keys for keys that cannot be written inline). - Reports errors with the same message text and line numbers as the reference NestedText implementation.
- Passes the complete official NestedText test suite (see Conformance).
Install
Usage
use ;
let text = r#"
host: example.com
port: 8080
debug: no
tag_li:
- alpha
- beta
"#;
let conf: Conf = from_str?;
assert_eq!;
assert!;
let out = to_string?;
assert_eq!;
# Ok::
Public API:
| Item | Purpose |
|---|---|
from_str::<T>(&str) |
parse NestedText text into T |
to_string(&T) |
serialize T into NestedText text |
from_value, to_value, dumps |
the same two directions over an already-parsed value tree |
Error, Result |
error type, carries the document error with its line number |
Type mapping
- Strings map to strings, and are parsed into numbers, booleans,
charand otherFromStrtypes on demand; output usesitoa/zmij. Option<T>: an empty value isNone, a present value isSome.- Lists, maps, tuples and structs map to NestedText lists and dictionaries.
- Enums map to a string or to a single-entry dictionary, so both unit and data-carrying variants work.
#[serde(untagged)]and#[serde(borrow)]are supported; borrowed deserialization avoids copying strings.
Writing rules
- Indent is 2 spaces; multiline values are written as
>blocks. - Keys that cannot be written inline (embedded
:, leading/trailing spaces, tabs, newlines) become multiline keys. \r\nand bare\rare normalized to\non write.
Errors
NestedText has no schema, so every error is a document error and is reported by
line. Error messages are kept 1:1 with the reference implementation, e.g.
invalid indentation., duplicate key: name., expected ‘:’, found ‘}’.,
extra characters after closing delimiter: ‘b]’., and the line numbers agree
with the reference on all official test cases.
Conformance
The official NestedText test suite
(nestedtext_tests) is part of
this repository and run on every build:
- all 148 cases: 68 invalid documents and 80 valid documents (5 of which load to
nullfor empty or comment-only input); - invalid documents: the error message and the line number are compared with the reference value of every case;
- valid documents: the parsed result is compared with the reference output, and
additionally round-tripped through
to_stringback intofrom_str.
Performance
Measured against nested-text on
a 200-entry nested dictionary, aarch64 (Apple M-series), release profile, time
and allocations per operation:
| Operation | serde_nt |
nested-text |
Allocations |
|---|---|---|---|
| parse into Rust types | 168 µs borrowed, 220 µs owned | 728 µs | 638 / 2,438 vs 17,682 |
| serialize to text | 153 µs | 489 µs | 4 vs 10,415 |
Limitations
- Byte arrays are not supported: NestedText has no binary type.
- Dictionary keys must serialize to strings; a list or dictionary used as a key is an error.
License
Apache-2.0.
serde_nt(中文)
NestedText 的 serde 序列化 / 反序列化。
NestedText 是面向人类的配置与数据格式:key: value 字典、- item 列表、> text
多行块,无引号无转义,叶子一律为字符串。本 crate 通过 serde 在该数据模型与
Rust 类型之间双向映射。
- 直接解析到目标类型,支持借用(
&str、Cow<'_, str>)与拥有两种模式。 - 写回布局稳定可读:2 空格缩进、多行值写
>块、无法单行写出的键写多行键。 - 错误文案与行号同官方实现逐字一致。
- 官方 NestedText 测试集全量通过(见「一致性」)。
安装
用法
见上方英文示例:serde_nt::from_str 解析、serde_nt::to_string 写回;
另有 from_value / to_value / dumps,在已解析的值树上做同一组双向转换。
类型映射
- 字符串原样;数字、布尔、
char及实现了FromStr的类型按字符串解析, 输出用itoa/zmij。 Option<T>:空值为None,有值为Some。- 列表、映射、元组、struct 对应 NT 列表与字典。
- 枚举对应字符串或单键字典,单元变体与带数据变体都可用。
- 支持
#[serde(untagged)]与#[serde(borrow)],借用反序列化零拷贝。
写回规则
- 缩进 2 空格;多行值写
>块。 - 不能单行写出的键(含
:、首尾空白、制表符、换行)改写为多行键。 \r\n与裸\r统一归一为\n。
错误
NestedText 无 schema,所有错误都是文档错误并按行报告。文案与官方实现逐字一致,
如 invalid indentation.、duplicate key: name.、expected ‘:’, found ‘}’.、
extra characters after closing delimiter: ‘b]’.;官方测试集覆盖的全部用例中行号也一致。
一致性
官方 NestedText 测试集
(nestedtext_tests)随仓库内置,
每次构建全量跑:
- 148 个用例:68 个非法、80 个合法(其中 5 个空文档/纯注释输入解析为
null); - 非法文档:错误文案与行号逐个同官方真值比对;
- 合法文档:解析结果同官方真值比对,并额外做写回往返(解析 → 写回 → 再解析)。
性能
与 nested-text 对比
(200 条嵌套字典,aarch64 Apple M 系列,release 构建,每次操作耗时与分配次数):
| 操作 | serde_nt |
nested-text |
分配次数 |
|---|---|---|---|
| 解析为 Rust 类型 | 168 µs(借用)/ 220 µs(拥有) | 728 µs | 638 / 2,438 vs 17,682 |
| 序列化为文本 | 153 µs | 489 µs | 4 vs 10,415 |
限制
- 不支持字节数组:NestedText 没有二进制类型。
- 字典键必须序列化为字符串;用列表或字典作键会报错。
许可
Apache-2.0。