#枚举 #csv #代码生成 #命令行 #变体名称 #文件格式 #相关常量

bin+lib csvenum

从命令行生成与关联常量相关的枚举的代码

5 个版本

0.1.4 2024年3月21日
0.1.3 2024年3月16日
0.1.2 2024年3月14日
0.1.1 2024年3月13日
0.1.0 2024年3月13日

#207 in 数据结构

MIT/Apache

145KB
3K SLoC

csvenum

文档 更新日志

命令行界面 (CLI) 用于从 csv 表生成 Rust 枚举和相关常量。

为什么?

如果您曾经需要声明很多常量,您会知道这可能需要查看数据集并将值复制到代码中。

所以这里有一个代码生成器来帮助创建具有相关常量的枚举。

只需在 .csv 中声明一个表格,生成即可。

您可以直接获取这个文件,例如 这个,添加类型信息即可。

如果您想将数据与现有枚举相关联,您可能想查看 strum

用法

由于这个包旨在加速 Rust 开发,因此它作为 cargo install 提供。

请注意,它处于积极开发中,因此请检查更新并报告您可能遇到的问题。

cargo install csvenum

安装后,在 .csv 中创建如下表格

ENUM        , &str      , usize     ,  (f64 , f64)

Country     , ISO3      , Numeric   ,  Lat_Lon

Sweden      , SWE       , 752       ,  (60.128161 , 18.643501)

Vietnam     , VDR       , 704       ,  (14.058324 , 108.277199)

Brazil      , BRA       , 076       ,  (-14.235004 , -51.92528)

要生成代码,请将文件名传递给 CLI。这里 countries.csv

csvenum countries.csv

生成的枚举将位于传递 .csv 的目录中名为 country.rs 的文件中。

在代码中,现在您可以按如下方式访问值

    let countries = Country::get_all_variants();
    for country in countries {
        println!("{}", country);
        println!("{}", country.as_iso3());
    }    

将输出

Sweden, ISO3 = SWE , Numeric = 752 , Lat_Lon = (60.128161 , 18.643501) 
SWE
Vietnam, ISO3 = VDR , Numeric = 704 , Lat_Lon = (14.058324 , 108.277199) 
VDR
Brazil, ISO3 = BRA , Numeric = 076 , Lat_Lon = (-14.235004 , -51.92528) 
BRA

有关表格格式、CLI 选项和功能列表的详细信息,请参阅下文。

输出示例可以在 这里 找到。

表格格式

用于代码生成的 csvenum 表格始终具有以下形状。

  • 第一行:指定列值的类型,从单词 ENUM 开始。

  • 第二行:指定枚举的名称和列名称,在这里称为属性。

  • 第三行及以后:数据。

数据将是行,首先是变体名称,然后是每个属性的值。

示例

ENUM,      &str,       usize,      [usize; 3]        <-- Column types

GPIOpin,    Address,    Value,      Numbers          <-- Enum name followed by the property names

PIN0,       0x00,       42,         [1,5,7]          <-- Variant name and associated values
PIN1,       0x02,       56,         [8,4,2]
PIN2,       0x04,       68,         [12,3,2]

请注意,在嵌套字段中,当它们用适当的符号括起来时,可以使用逗号。

  • 字符串/正则表达式: ""

  • 元组: ()

  • 数组: []

大多数软件会以引号导出的带有嵌套逗号的字段,因此元组将是 "(1,2)"。这对于解析器来说是完全可行的。

列中的重复值将被收集到一个包含所有对应变体的数组中。

目前,表格仅限于只包含常量值(即具有常量初始化器的类型),但计划为其他类型提供 OnceLock / Lazy 实现。

此外,为了避免麻烦,对值嵌套深度有一个任意但合理的限制。

请注意,属性名称必须遵循有效的 Rust 变量命名规则。

在表格中,布尔值也可以是 0 或 1,而不仅仅是 false 或 true。

CLI 选项

csvenum --help
Codegen for enums with associated constants

Usage: csvenum [OPTIONS] <FILENAME_CSV>

Arguments:
  <FILENAME_CSV>  Filename of the CSV file (required)

Options:
  -o, --outpath 
          Path to the output dir/file
  -s, --split-properties 
          Whether to split property declarations into separate files, defaults to: false [possible values: true, false]
  -v, --variant-str-fns 
          Generate variant as & from str fns , defaults to: true [possible values: true, false]
  -i, --impl-links 
          Pure conversion functions only or also impl links to them, defaults to: true [possible values: true, false]
  -h, --help
          Print help
  -V, --version
          Print version

功能

生成的代码

  • (总是) - 声明具有给定变体和包含所有属性+值的文档字符串的枚举

  • (可选,true) - 变体名称作为和从 str 函数 + std::fmt::Display 实现打印名称和所有相关值到字符串。

  • (总是) - 声明属性值作为常量,并声明它们之间的 "as" 和 "from" 转换函数。您可以选择将属性拆分到单独的文件中。

  • (可选,true) - 为枚举生成包含指向属性转换函数的 impl 块,同时也生成一个测试模块。

  • (总是) - 生成一个 get_all_variants 函数 -> [MyEnum; N_variants]

可用类型

  • 常量类型(由常量表达式初始化)

      - numeric types    
    
      - &str
    
      - tuples 
    
      - arrays
    
  • 正则表达式: - 依赖于正则表达式 crate 存在,cargo add regex

      - will create a const &str and a static `OnceLock<Regex>` 
    
      - "as"-method will return &Regex
    
      - "from"-method iterates over the associated regexes and returns the first match, i.e the matching variant
    
      - nested Regex, i.e. Regex in tuples or arrays are not planned
      
      - can't have duplicates for a given column/property 
    

已知问题

  1. csv 中的尾随逗号 - 可以修复,但一开始就不应该有。

  2. 变体和属性中的 Rust 标识符无效字符。

未来计划

  1. 为 Ord 实现专用列

  2. 生成 FromStr 实现以检查所有关联的字符串常量。

  3. 提供 OnceLock 或类似的包装器用于非 const 静态。

  4. 对缺失值的数据提供选项。

  5. 为大型数据集提供静态 HashMaps

请报告您发现的任何问题或建议,以进一步改进此工具!

依赖项

~3.5–5MB
~89K SLoC