2 个版本
| 0.1.1 | 2021 年 8 月 25 日 |
|---|---|
| 0.1.0 | 2021 年 8 月 24 日 |
#1356 在 编码
56KB
1.5K SLoC
serde_dynamic_typing
欢迎来到 serde_dynamic_typing 🎉
此crate实现了一个简化的与 serde 兼容的类型模型,它以简化的形式表示各种Rust数据结构,并允许动态运行时检查。此类型模型也可用作自定义序列化器等的中间表示。
为什么?
由于Rust编译器擦除了大部分类型信息,这使得运行时检查和修改基本上变得不可能。虽然有一些强大的方式,如 Any 特性或 serde,但是前者主要用于实现动态接口,而后者旨在提供预定义静态数据结构的(反)序列化。
serde_dynamic_typing 处于中间位置:一方面,它类似于 Any,因为它提供了一个简化的类型模型,可以用于在运行时动态构建和检查几乎任意复杂的数据结构。另一方面,它力求与 serde 和 serde_derive 兼容,因此您可以转换现有的Rust类型和结构体到 AnyValue 以及反之。
此外,它还可以作为 serde 的简单抽象层:虽然 serde 非常灵活和高效,但它也要求更复杂的类型模型和实现。如果您只想编写一个简单的(反)序列化器,而不需要 serde 提供的完整效率和功能,则 serde_dynamic_typing 可以大大简化实现。
详细信息和示例
整个数据模型基于几个核心类型和一个基于枚举的“通用”值类型。
简化的类型有
Boolean代表布尔值Bytes代表字节容器,如Vec<u8>、[u8]或[u8; N]Enumeration代表具有可选关联值的 Rust 原生enumFloat代表浮点数Integer代表整数类型Map代表类似BTreeMap的映射类型,也用于表示具有命名字段的struct和enum值Sequence代表序列类型,如Vec<...>、[...]或[...; N],具有任意值,也用于表示具有元组字段的struct和enumUtf8String代表类似String、str或char的 UTF-8 字符串类型
此外,还有一个“泛型”枚举类型 AnyValue,可以存储上述类型的任何值。
例如,一个类似的结构体
#[derive(Serialize, Deserialize)]
struct ByteContainer {
#[serde(with = "serde_bytes")]
bytes: Vec<u8>
}
表示为
AnyValue::Map([
(
AnyValue::Utf8String(Utf8String::from("bytes")), // <- map key
AnyValue::Bytes(Bytes::from(/* value of `bytes` */)) // <- associated value
)
])
依赖关系
~125–365KB