5 个版本
0.1.4 | 2024 年 4 月 9 日 |
---|---|
0.1.3 | 2023 年 12 月 27 日 |
0.1.2 | 2023 年 2 月 22 日 |
0.1.1 | 2023 年 1 月 12 日 |
0.1.0 | 2023 年 1 月 8 日 |
#46 在 Cargo 插件
229 每月下载量
57KB
991 行
cargo-generate-type
此二进制文件作为 cargo
的 自定义命令 使用,分析带标题的定界符(CSV、TSV)文件,并生成适当的 Rust 代码以干净地解析数据。生成的代码包装了 csv
crate 以执行 CSV 解析。您可以通过运行以下命令来安装此实用程序:
cargo install cargo-generate-type
此工具的输出旨在在处理定界符数据时使您的生活更加轻松——只需将其指向文件(或计划在生产中处理的代表文件)并将生成的代码集成到您的项目中即可。
cargo-generate-type
读取指定的文件;确定每列的适当类型,对于整数,将类型限制为适应范围的所需最小大小;并生成使读取这些数据更加方便的代码
$ head -5 iris.csv
sepal length in cm,sepal width in cm,petal length in cm,petal width in cm,class
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
$ cargo generate-type iris.csv
Generated "iris.rs"
这会生成一个 Iris
结构体
#[derive(Clone, Debug)]
pub struct Iris {
pub sepal_length_in_cm: f64,
pub sepal_width_in_cm: f64,
pub petal_length_in_cm: f64,
pub petal_width_in_cm: f64,
pub class: String,
}
它还生成了一个 impl Iris
,该结构体知道如何加载数据、解析数据并处理输入中的错误。
用法
您必须传入定界文件的路径。默认情况下,此文件的名称将成为生成的结构体名称(尽管进行了一些规范化)和输出源文件。例如,"iris.csv" 将生成一个包含在 iris.rs 中的 Iris
结构体。"shareholder_report.csv" 将生成 ShareholderReport
。您可以使用 --typename name
参数来指定结构体名称,并使用 --output-file outfile
指定要创建的文件。如果文件已存在,除非您使用 --force
标志,否则不会覆盖。
存在标题行可以让此工具生成适当的列名。如果您的数据缺少标题行,您可以通过传递 --no-header
来实现。这将计算输入文件第一行的列数,并以 column_{索引}
的格式插入列名。然后,您可以从您的 IDE 中选择重命名这些列。
模式检测
运行此工具时,它将处理(部分)您的输入文件,以尝试理解模式,包括所有列的列名和数据类型。
默认情况下,它将处理输入的前 100 行以猜测类型。您可以通过指定非负整数值 n
的 --rows n
来覆盖此操作。如果您使用 --rows 0
,它将使用整个输入文件。
列的类型推断大致遵循以下过程:
- 如果一个列始终为空,它将被视为单元类型(
()
)。 - 如果一个列曾经有空白值,它将被视为
Option<T>
类型,其中T
是决定的数据类型。 - 如果值始终为 "true" 或 "false",则该列将被视为
bool
。 - 如果值始终为整数类型,将跟踪看到的值范围,并根据最小值和最大值,该列将属于以下之一:
i8
,i16
,i32
,i64
,u8
,u16
,u32
,u64
。 - 如果值始终为数值,则该列将被视为
f64
。 - 否则,使用
String
。
目前,字符串值将被分配,而不是使用指向底层 csv::StringRecord
的 &'a str
引用。这可能会很快被 Cow<'_, str>
替换以减少分配。
错误处理
生成的代码可以以三种不同的方式处理意外的输入,这些方式由 --error handling-type
参数指定
--error ignore
将静默忽略输入中的任何错误,跳过缺失列或具有意外类型的行。--error panic
将对任何具有无效输入的行引发恐慌。--error result
将返回一个Result<T, E>
,其中T
是表示您数据的类型,而E
则涵盖了底层的csv
错误 以及意外的输入类型。这是未指定时的默认行为。
字符串处理
默认情况下,文本列将被处理为拥有 String
。对于大量输入或基数较低的列,所发生的内存分配可能过多。0.1.3 版本提供了 --strings
参数,可能的值为 owned
(默认值)、static
和 enum
。
使用 --strings static
,将看到的唯一字符串集合进行配置文件分析,生成的代码将为您提供 &'static str
而不是 String
,从而减少内存分配(并允许生成的结构体 #[derive(Copy)]
)。
使用 --strings enum
也做同样的事情,除了定义一个辅助枚举,使用 impl std::str::FromStr
将输入文本解析为该枚举。此枚举以及该类型的结构体也是 Copy
。
还有一个 --max-strings n
参数(其中 n 的默认值为 20);如果看到的唯一值超过 n,则代码生成失败,以避免为高基数数据生成过多的代码。
使用说明
因为这个二进制文件是作为 Cargo 自定义命令的,所以它被调用为 cargo generate-type
。请注意,这是带有 generate-type
子命令的 cargo
程序。Cargo 将此子命令作为参数传递给二进制文件,并将其忽略。因为期望此参数,如果您尝试运行 cargo-generate-type
,则必须向其传递一个虚拟参数。
./cargo-generate-type generate-type shareholder_report.csv --error result
# ^^^^^^^^^^^^^ or any bogus argument is fine
附加文档
您可以在输入 ".csv" 文件旁边创建一个 ".def" 文件,该文件将生成类型的字段的文档。例如,对于从 "iris.csv" 生成的上述 Iris
数据类型,您可以创建一个类似下面的 "iris.def" 文件
This represents [Fisher's Iris data set](https://en.wikipedia.org/wiki/Iris_flower_data_set)
[sepal length in cm]
The length of the flower's sepal, in centimeters.
[sepal width in cm]
The width of the flower's sepal, in centimeters.
[petal length in cm]
The length of the flower's petal, in centimeters.
[petal width in cm]
The width of the flower's petal, in centimeters.
[class]
The species of flower, one of: Iris-setosa, Iris-virginica, Iris-versicolor.
在生成代码时,将生成以下具有文档的类型
#[derive(Clone, Debug)]
/// This represents [Fisher's Iris data set](https://en.wikipedia.org/wiki/Iris_flower_data_set)
pub struct Iris {
/// The length of the flower's sepal, in centimeters.
pub sepal_length_in_cm: f64,
/// The width of the flower's sepal, in centimeters.
pub sepal_width_in_cm: f64,
/// The length of the flower's petal, in centimeters.
pub petal_length_in_cm: f64,
/// The width of the flower's petal, in centimeters.
pub petal_width_in_cm: f64,
/// The species of flower, one of: Iris-setosa, Iris-virginica, Iris-versicolor.
pub class: String,
}
输入修剪
某些输入文件可能具有空格填充的内容,尽管它们是分隔的。例如
sepal length in cm,sepal width in cm,petal length in cm,petal width in cm,class
5.1 ,3.5 ,1.4 ,0.2 ,Iris-setosa
4.9 ,3.0 ,1.4 ,0.2 ,Iris-setosa
4.7 ,3.2 ,1.3 ,0.2 ,Iris-setosa
4.6 ,3.1 ,1.5 ,0.2 ,Iris-setosa
5.0 ,3.6 ,1.4 ,0.2 ,Iris-setosa
在这种情况下,由于值不会解析为浮点数,它们将被错误地视为字符串。如果您传递 --trim-input
开关,则将在尝试解析之前修剪值。此开关默认情况下未启用。
依赖关系
~2.4–3.5MB
~51K SLoC