AIDotNet.Toon
0.1.3
dotnet add package AIDotNet.Toon --version 0.1.3
NuGet\Install-Package AIDotNet.Toon -Version 0.1.3
<PackageReference Include="AIDotNet.Toon" Version="0.1.3" />
<PackageVersion Include="AIDotNet.Toon" Version="0.1.3" />
<PackageReference Include="AIDotNet.Toon" />
paket add AIDotNet.Toon --version 0.1.3
#r "nuget: AIDotNet.Toon, 0.1.3"
#:package AIDotNet.Toon@0.1.3
#addin nuget:?package=AIDotNet.Toon&version=0.1.3
#tool nuget:?package=AIDotNet.Toon&version=0.1.3
AIDotNet.Toon
Token-Oriented Object Notation(TOON)的 .NET 实现,对齐 https://github.com/toon-format/toon 规范,提供与 System.Text.Json 一致的 API 体验与选项模型。
- 高性能编码:对象、原子数组行内、对象数组表格等路径已实现
- 解码管线:扫描/解析/验证处于进行中,当前支持原子值回读
- 设计遵循“最少分配、可读优先”的工程取舍
C#.ToonSerializer · C#.ToonSerializerOptions · C#.Encoders.EncodeValue() · C#.Primitives.EncodePrimitive() · C#.LineWriter
徽章
- NuGet: AIDotNet.Toon
- 目标框架:net8.0 / net9.0 / net10.0(见 src/AIDotNet.Toon/AIDotNet.Toon.csproj)
- 许可证:MIT
目录
安装
NuGet(待发布):
dotnet add package AIDotNet.Toon
源代码方式:
- 将目录
src/AIDotNet.Toon添加到解决方案,或以子模块方式引入 - 在你的 csproj 中开启包 Readme(已在本项目配置):参阅 src/AIDotNet.Toon/AIDotNet.Toon.csproj
快速开始
序列化为 TOON:
using Toon;
var options = new ToonSerializerOptions
{
Indent = 2,
Delimiter = ToonDelimiter.Comma,
Strict = true,
LengthMarker = null
};
var data = new
{
users = new[]
{
new { name = "alice", age = 30 },
new { name = "bob", age = 25 }
},
tags = new[] { "a", "b", "c" },
numbers = new[] { 1, 2, 3 }
};
string toonText = ToonSerializer.Serialize(data, options);
// users[2]{name,age}:
// 1,alice
// 2,bob
// tags[3]: a,b,c
// numbers[3]: 1,2,3
从 TOON 反序列化为 .NET(当前仅原子值稳定,其它结构将随解码器完善):
using Toon;
var s = ToonSerializer.Deserialize<string>("hello", options); // "hello"
var n = ToonSerializer.Deserialize<double>("3.1415", options); // 3.1415
相关 API: C#.ToonSerializer.Serialize() · C#.ToonSerializer.Deserialize()
API 与选项
公共 API:
- 泛型序列化:C#.ToonSerializer.Serialize()
- 显式类型序列化:C#.ToonSerializer.Serialize()
- 泛型反序列化:C#.ToonSerializer.Deserialize()
- 显式类型反序列化:C#.ToonSerializer.Deserialize()
- 字节 API:
- 流 API:
- Indent:每级缩进空格数,默认 2
- Delimiter:分隔符,枚举 C#.ToonDelimiter(Comma / Tab / Pipe)
- Strict:解码严格模式(缩进/空行/多余项等校验),默认 true
- LengthMarker:数组长度标记,仅支持
#或 null,默认 null - JsonOptions:直通 System.Text.Json 的 C#.JsonSerializerOptions,默认启用命名浮点字面量,并注册将
NaN/±Infinity写出为null的转换器: C#.DoubleNamedFloatToNullConverter / C#.SingleNamedFloatToNullConverter
默认实例:C#.ToonSerializerOptions.Default
编码规则与格式
对象:
- 逐键输出:C#.Encoders.EncodeObject() 与 C#.Encoders.EncodeKeyValuePair()
- 键名:安全则裸写,否则加引号:C#.Primitives.EncodeKey()
- 空对象:仅输出
key:
原子数组(行内):
对象数组(表格):
- 抽取表头:C#.Encoders.ExtractTabularHeader()
- 表头与数据行输出:C#.Encoders.EncodeArrayOfObjectsAsTabular() · C#.Encoders.WriteTabularRows()
混合/复杂数组(回退为列表):
原子/字符串:
- 原子编码:C#.Primitives.EncodePrimitive()
- 字符串加引号规则:C#.Primitives.EncodeStringLiteral()
- 数值规则:
NaN/±Infinity -> null、-0 -> 0、其余沿用 C#.JsonElement.GetRawText()
行与缩进:
示例片段
简单对象:
var obj = new { a = 1, b = "x" };
var toon = ToonSerializer.Serialize(obj);
// a: 1
// b: x
原子数组(默认逗号分隔):
var arr = new[] { 1, 2, 3 };
ToonSerializer.Serialize(arr); // "[3]: 1,2,3"
对象数组(表格):
var rows = new[] { new { id = 1, name = "alice" }, new { id = 2, name = "bob" } };
ToonSerializer.Serialize(rows);
// [2]{id,name}:
// 1,alice
// 2,bob
字节与流:
// 字节
var bytes = ToonSerializer.SerializeToUtf8Bytes(rows);
var rowsFromBytes = ToonSerializer.Deserialize<List<Dictionary<string, object>>>(bytes);
// 流
using var ms = new MemoryStream();
ToonSerializer.Serialize(rows, ms); // 写入 UTF-8(无 BOM),保持流打开
ms.Position = 0;
var rowsFromStream = ToonSerializer.Deserialize<List<Dictionary<string, object>>>(ms);
特殊数值处理:
ToonSerializer.Serialize(new { v = double.NaN }); // "v: null"
ToonSerializer.Serialize(new { v = double.PositiveInfinity }); // "v: null"
ToonSerializer.Serialize(new { v = BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000)) }); // "v: 0"
相关断言可见测试:tests/AIDotNet.Toon.Tests/EncodeTests.cs
性能与实现细节
本实现尽量减少分配与不必要的分支,同时保持输出可读性:
- 缩进缓存: C#.LineWriter.Push() 维护
_indentCache,避免重复构造 - 去 LINQ:表头检测/数据行写出等路径使用普通枚举器遍历:C#.Encoders.ExtractTabularHeader() · C#.Encoders.WriteTabularRows()
- 复用拼接:原子数组与表格行采用逐段 Append:C#.Primitives.EncodeAndJoinPrimitives() · C#.Encoders.WriteTabularRows()
- 原文数值:优先使用 C#.JsonElement.GetRawText() 保证精度;快速路径规范化
-0
发布建议:使用 Release 构建;可考虑 R2R/ReadyToRun 提升启动性能。
对齐 TypeScript 规范
- 语法/渲染规则参考 upstream 规范与实现:
- 规范与参考实现:https://github.com/toon-format/toon
- .NET 版模块映射:
- Encoder: C#.ToonEncoder.Encode() → C#.Encoders.EncodeValue()
- Decoder: C#.ToonDecoder.DecodeToJsonString()(占位,逐步完善)
版本支持
- 运行时:.NET 8/9/10
- 平台:Windows / Linux / macOS
- 包元数据与 Readme 集成:见 src/AIDotNet.Toon/AIDotNet.Toon.csproj
路线图
- 解码:扫描(Scanner)/解析(Parser)/校验(Validation)/解码器(Decoders)
- 严格模式错误模型:提供行列与上下文的 C#.ToonFormatException
- 归一化策略(Normalize):日期/集合等的跨语言一致性
- 文档与示例完善,发布 NuGet 包
开发与测试
- 运行测试:
dotnet test
- 本地打包:
dotnet pack -c Release
- 重要源文件:
贡献
欢迎提交 Issue/PR。请尽量:
- 保持公共 API 与 System.Text.Json 风格一致
- 在优化时以可读性/真实收益为先
- 为新增路径与边界条件补充单元测试
许可
MIT © AIDotNet.Toon Contributors
致谢:感谢 upstream 项目 https://github.com/toon-format/toon 的设计与实现参考。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on AIDotNet.Toon:
| Package | Downloads |
|---|---|
|
AIDotNet.Toon.Benchmarks
Package Description |
|
|
AIDotNet.Toon.ModelBenchmarks
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.