9 个版本

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

#36#stateful

每月 31 次下载
用于 xylem

Apache-2.0 协议

54KB
1.5K SLoC

xylem

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

Xylem 是 Rust 的有状态类型转换框架。

概念

Xylem 提供了 [Xylem] trait,与 [std::convert::TryFrom] trait 类似,但有以下不同之处

有状态上下文

[Xylem::convert] 传递一个可变的 [Context],在整个转换过程中允许有状态操作。有关详细信息,请参阅 [Context] 文档。

固定的转换源

与 [std::convert::TryFrom] 不同, [Xylem] 将转换源类型作为关联类型 [Xylem::From] 而不是泛型参数。这意味着每个类型只能在给定的 [Schema] 下从恰好一种其他特定类型进行转换。

模式

[Xylem] 接受一个类型参数 S ("schema"),它充当命名空间,定义了转换规则集。这允许不同的下游 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分别声明在自己的crate中,所以Xylem<S>不被视为外部特质,因此为std类型实现自定义转换规则不会导致错误E0220错误E0119

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

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

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

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

Xylem

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

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

id特性

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

Id类型接受两个泛型参数,SX。类型S只是schema类型,而类型X是标识的主题。X还必须实现Identifiable特质,它有一个关联类型Identifiable::Scope,用于为ID提供命名空间。声明Id字段必须位于X下,并且X必须作为(传递性)子项出现在作用域中。对X的ID的进一步引用也必须作为作用域的传递性子项出现,因为作用域在解析完成后会被丢弃。

带有参数new = true标记声明ID。如果ID在作用域结束后要跨作用域引用,也标记track = true。引用ID不需要标记,但如果它们用于导入作用域,则应标记为import = true

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

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

依赖关系

~1.5MB
~35K SLoC