9个版本

0.2.7 2021年11月18日
0.2.6 2021年11月17日
0.1.0 2021年11月7日

#1480数据库接口

Apache-2.0

51KB
671

xylem

GitHub actions crates.io crates.io docs.rs GitHub GitHub

XYlem 是一个针对 Rust 的有状态类型转换框架。

概念

XYlem 提供了类似于 std::convert::TryFrom 特性的 Xylem 特性,但有以下不同

有状态上下文

Xylem::convert 传递一个可变的 Context,使得在整个转换过程中可以进行有状态的运算。有关详细信息,请参阅 Context 文档。

固定的转换源

std::convert::TryFrom 不同,Xylem 将转换源类型作为关联类型 Xylem::From 而不是泛型参数。这意味着每种类型只能根据给定的 Schema 从另一个特定类型进行转换。

模式

Xylem 接受类型参数 S ("模式"),它作为命名空间定义了一组转换规则。这允许不同的下游 crate 定义自己的转换规则而不会相互冲突。例如,如果 crate foo 想将 boolString 转换,而 crate bar 想将 booli32 转换,它们可以分别定义模式类型 foo::Xylembar::Xylem,然后分别实现

impl Xylem<foo::Schema> for bool {
    type From = String;
    // fn convert() omitted
}
impl Xylem<bar::Schema> for bool {
    type From = i32;
    // fn convert() omitted
}

此外,由于 foo::Schemabar::Schema 分别声明在其自己的包中,Xylem<S> 不被视为外部特性,因此为 [std] 类型实现自定义转换规则不会导致 错误 E0220错误 E0119

要使用 xylem 定义的默认转换规则,让模式实现 SchemaExt 特性。为此提供了一个方便的宏 declare_schema

xylem::declare_schema!(Schema: xylem::SchemaExt);

// we defined a schema type called `Schema`.

建议将 Schema 用作模式名称,并在包级别声明它,因为 Xylem 宏使用 crate::Schema 作为默认的模式类型。

Xylem

Xylem 提供了一个 Xylem 宏,该宏从一个结构体或枚举推导出相应的 Xylem::From 类型,通过将每个类型替换为其对应的 Xylem::From 类型,以及一个 Xylem 实现。有关详细信息,请参阅 Xylem 文档。

请注意字段顺序很重要,因为 xylem 类型转换是状态性的,即先前的转换可能会影响后续的转换。

id 功能

启用 id 功能后,xylem 提供了 [Id] 类型,这是 xylem 的动机用例:反序列化一个通过字符串 ID 引用其他字段的配置文件,将每个声明 ID 替换为存储其出现顺序的整数,并将每个引用 ID 替换为声明 ID 的出现顺序。

Id 类型接受两个泛型参数,SX。类型 S 仅是模式类型,而类型 X 是识别的主体。类型 X 还必须实现 Identifiable 特性,该特性有一个关联类型 Identifiable::Scope,用于为 ID 提供命名空间。必须将声明的 [Id] 字段声明在 X 下,并且 X 必须作为 (传递性) 子元素出现在范围内。对 X ID 的进一步引用也必须作为传递性子元素出现在范围内,因为当范围完成解析时,范围会被丢弃。

声明的ID用参数new = true标记。如果ID在作用域下降后需要交叉引用,也用track = true标记。引用ID不需要标记,但如果它们用于导入作用域,则应标记为import = true

有关示例用法,请参阅tests/id.rstests/cross_id.rs

请注意,xylem支持前瞻性ID并不是其设计目标。由于xylem具有状态性,ID仅在声明被扫描时进行索引。目前没有计划实现多次遍历来预先索引ID。

依赖关系

~2MB
~41K SLoC