#toml-config #toml #static #build-script

构建 toml_const

从 TOML 中生成的编译时常量

2 个版本

0.1.1 2023 年 11 月 28 日
0.1.0 2023 年 11 月 27 日

#233 in 构建工具


用于 toml_const_cli

MIT 许可证

25KB
374

toml_const

TOML 编译时常量

入门

安装 CLI。这将生成一些样板文件和代码

cargo install toml_const_cli

# use toml_const_cli init --help to view more options
toml_const_cli init <MANIFEST_PATH> # path to Cargo.toml

现在您的包应该看起来像这样

package
├── .cargo          # generated/modified by CLI
│   └── config.toml
├── .config         # generated by CLI
│   ├── .gitignore
│   ├── package.debug.toml      # debug variant
│   ├── package.deploy.toml     # deploy/release variant
│   └── package.template.toml   # defaults
├── src
│   └── main.rs
├── .gitignore
├── build.rs        # generated by CLI
├── generated.rs    # generated by build.rs
└── Cargo.toml

如果您有现有的构建脚本,请在其中添加以下内容

// inside build.rs
fn main() {
    toml_const::run();

    // ... rest of your build script
}

generated.rs 现在可以包含到您的代码中

include!("../generated.rs") // included in main, for example

建议将此文件包含在单独的模块中

// inside main.rs / lib.rs
mod consts;

// inside consts.rs
#![allow(unused)]
include!("../generated.rs")

然后使用它

let this: bool = consts::USE; // the USE const must always be defined

说明

所有有效的 TOML 数据类型都作为编译时常量生成,除非包含内部表/数组的表/数组。

数组和表在 lazy_static! 包装器内部定义。

所有表在可能的情况下都会解构,指向它们的 TOML 值的键。命名空间用下划线 "_" 分隔。

示例

[table]
field = "string"
time = 11:20:00
integer = 3

[table.inner]
field = "another string"
datetime = 1979-05-27 07:32:00Z
one_billion = 1e09

[table.other]
normal_array = [1, 2, 3, 4, 5, 6]

[[arr_of_tables]]
this = "foo"
that = "bar"

[[arr_of_tables]]
this = "fizz"
that = "buzz"

[[arr_of_tables]]
this = "pee"
that = "poo"

解构变量

// destructured first table
let f: &str = TABLE_FIELD;
let t: toml::value::Datetime = TABLE_TIME;
let i: i64 = TABLE_INTEGER;

// destructured second table
let tif: &str = TABLE_INNER_FIELD;
let tidt: toml::value::Datetime = TABLE_INNER_DATETIME;
let tib: i64 = TABLE_INNER_ONE_BILLION;

最后一层的表,或者不包含内部表或数组的表,也将它们的键值对存储为 HashMap<&'static str, String>

/// `table` does not have an associated hashmap, as it contains
/// an inner table `table.inner`.
///
/// The associatd hashmap for `table.inner` is TABLE_INNER.
let ht: &HashMap<&'static str, String> = &*TABLE_INNER;

// hashmaps lose type-specific information
let tif_string: &str = TABLE_INNER.get("FIELD").unwrap();
let tidt_string: &str = TABLE_INNER.get("DATETIME").unwrap();
let tib_string: &str = TABLE_INNER.get("ONE_BILLION").unwrap();

// but you can iterate over them at runtime
for key in TABLE_INNER.keys() {
    // ...
}

数组

也可以使用数组。所有元素的类型都是从第一个元素推断出来的。

// iterate over array elements
for item: &i64 in TABLE_OTHER_NORMAL_ARRAY.iter() {
    // ...
}

// iterate over array of tables
for subtable: &HashMap<&'static str, String> in ARR_OF_TABLES.iter() {
    // ...
}
生成的代码
// ...imports excluded

/// type: &'static str
pub const TABLE_INNER_FIELD: &'static str = "another string";
/// type: f64
pub const TABLE_INNER_ONE_BILLION: f64 = (1000000000_f64);
/// type: i64
pub const TABLE_INTEGER: i64 = (3_i64);
lazy_static::lazy_static! {
/// type: [HashMap<&'static str, String>; 3]
pub static ref ARR_OF_TABLES: [HashMap<&'static str, String>; 3] = [
HashMap::from([
("that", "bar".to_string()),("this", "foo".to_string()),])
,
HashMap::from([
("that", "buzz".to_string()),("this", "fizz".to_string()),])
,
HashMap::from([
("that", "poo".to_string()),("this", "pee".to_string()),])

];
}
/// type: &'static str
pub const TABLE_FIELD: &'static str = "string";
/// type: bool
pub const USE: bool = false;
/// type: Datetime
pub const TABLE_TIME: Datetime = Datetime {
    date: None,
    time: Some(Time {
        hour: 11,
        minute: 20,
        second: 0,
        nanosecond: 0,
    }),
    offset: None,
};
lazy_static::lazy_static! {
/// type: [i64; 6]
pub static ref OTHER_NORMAL_ARRAY: [i64; 6] = [
(1_i64),
(2_i64),
(3_i64),
(4_i64),
(5_i64),
(6_i64)
];
}
/// type: Datetime
pub const TABLE_INNER_DATETIME: Datetime = Datetime {
    date: Some(Date {
        year: 1979,
        month: 5,
        day: 27,
    }),
    time: Some(Time {
        hour: 7,
        minute: 32,
        second: 0,
        nanosecond: 0,
    }),
    offset: Some(Offset::Z),
};
lazy_static::lazy_static! {
/// type: HashMap<&'static str, String>
pub static ref TABLE_INNER: HashMap<&'static str, String> = HashMap::from([
("DATETIME", Datetime { date: Some(Date { year: 1979, month: 5, day: 27 } ), time: Some(Time { hour: 7, minute: 32, second: 0, nanosecond: 0 } ), offset: Some(Offset::Z) }.to_string()),
("FIELD", "another string".to_string()),
("ONE_BILLION", (1000000000_f64).to_string()),
]);
}

模板、调试、部署

toml_const 将 3 个 toml 文件生成到您的根项目目录(默认位于 .config/)。

*.template.toml 的内容用作基础,匹配 *.debug.toml*.deploy.toml 的键将覆盖模板值。在 debugdeploy 中定义的新键也将被添加。

将顶级键 use=true 设置将会导致 toml_const 从特定的配置文件生成代码。

debug 使用 deploy 使用 使用的文件
false false 模板:编译警告
false true 模板 + deploy
true false 模板 + debug
true true 模板 + deploy

依赖项

~270–520KB
~11K SLoC