39 个版本 (12 个稳定版)
1.6.4 | 2023年11月1日 |
---|---|
1.5.1 | 2023年9月22日 |
1.4.1 | 2023年7月4日 |
1.3.0 | 2022年8月21日 |
0.3.0 | 2021年6月11日 |
#132 in Rust 模式
1,714 每月下载量
在 3 crate 中使用
38KB
693 行
const-gen
这是一个用于在您的 build.rs
文件中生成编译时常量的 crate。此 crate 支持将通常堆分配的类型转换为固定大小常量。它包括对基本类型、字符串、向量、映射、集合的支持,并附带一个 derive 宏,允许使用结构和枚举进行实现。
查看此示例
// build.rs
use const_gen::*;
use std::{env, fs, path::Path};
// First, let's dummy up some structs. Enabling the "derive"
// feature allows us to do this simply, but implementing the
// CompileConst trait by hand is straightforward.
#[derive(CompileConst)]
#[inherit_doc]
/// Example inherited documentation
struct TestStruct
{
test_u8: u8,
/// Example uninherited field documentation
test_vec: Vec<String>,
}
#[derive(CompileConst)]
#[inherit_docs]
/// Example inherited documentation
enum TestEnum
{
Variant1,
Variant2(u8),
#[inherit_doc]
/// Example inherited variant documentation
Variant3 { named: u8 }
}
#[derive(CompileConst)]
struct TestTup(u8, u16);
fn main()
{
// Use the OUT_DIR environment variable to get an
// appropriate path.
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("const_gen.rs");
// Now let's dummy up some data to use in our const
// generation
let test_vec: Vec<u8> = vec!(1,2,3,4,5,10,4);
let test_struct = TestStruct
{
test_u8: 12,
test_vec: vec!(String::from("Hello there."))
};
let test_tup_struct = TestTup(4, 55,);
let test_enum = TestEnum::Variant1;
let test_enum_tup = TestEnum::Variant2(23);
let test_enum_structlike = TestEnum::Variant3{ named: 78 };
// Now we'll generate the const declarations. We're also
// going to test with some primitive types.
let const_declarations = vec!
{
// Here are type definitions for our enums and structs
// above. Attributes from build.rs will not be preserved,
// so we need to pass any we want in.
const_definition!(#[derive(Debug)] pub TestStruct),
const_definition!(#[derive(Debug)] TestTup),
const_definition!(#[derive(Debug)] TestEnum),
// And here are constant definitions for particular
// values.
const_declaration!(TEST_U8 = 27u8),
const_declaration!(#[doc = "Example inherited documentation"] TEST_F32 = 33.5f32),
const_declaration!(TEST_VEC = test_vec),
const_declaration!(TEST_STRING = "I'm a string!"),
const_declaration!(TEST_COW =
std::borrow::Cow::from("Cow!")),
const_declaration!(pub TEST_STRUCT = test_struct),
const_declaration!(TEST_TUP_STRUCT = test_tup_struct),
const_declaration!(TEST_ENUM = test_enum),
const_declaration!(TEST_ENUM_TUP = test_enum_tup),
const_declaration!(TEST_ENUM_STRUCTLIKE =
test_enum_structlike),
// or generate statics with the static_declaration macro
static_declaration!(pub static TEST_U8_STATIC = 27u8),
}.join("\n");
// Note: The `const_definition!` and `const_declaration!`
// macros above are just simple wrappers for CompileConst
// trait methods of the same name. Using those methods
// would entail the following sytax:
// TestStruct::const_definition("#[derive(Debug)]")
// test_struct.const_declaration("TEST_STRUCT")
// These may be preferable in cases where const names
// or type attributes have been procedurally generated
// somehow and need to be treated as strings.
// If the "phf" feature is enabled, this crate will also
// support converting HashMap and HashSet types into
// compile-time constant phf map and set types respectively.
// Lastly, output to the destination file.
fs::write(&dest_path, const_declarations).unwrap();
}
现在,在我们的 main.rs
文件中,我们可以这样做
// Include our constants
include!(concat!(env!("OUT_DIR"), "/const_gen.rs"));
// And that's it, we can access all of the const values below.
// It plays quite well with rust-analyzer, etc
fn main()
{
println!("{}", TEST_U8);
println!("{}", TEST_F32);
println!("{:?}", TEST_VEC);
println!("{}", TEST_STRING);
println!("{}", TEST_COW);
println!("{:?}", TEST_STRUCT);
println!("{:?}", TEST_TUP_STRUCT);
println!("{:?}", TEST_ENUM);
println!("{:?}", TEST_ENUM_TUP);
println!("{:?}", TEST_ENUM_STRUCTLIKE);
}
实际的生成输出看起来像(此版本未格式化)这样
#[derive(Debug)]
struct TestStruct
{
test_u8: u8,
test_vec: &'static [&'static str],
}
#[derive(Debug)]
struct TestTup(u8, u16);
#[derive(Debug)]
/// Example inherited documentation
enum TestEnum
{
Variant1,
Variant2(u8),
/// Example inherited variant documentation
Variant3 { named: u8 },
}
const TEST_U8: u8 = 27u8;
/// Example inherited documentation
const TEST_F32: f32 = 33.5f32;
const TEST_VEC: &'static [u8] =
&[1u8, 2u8, 3u8, 4u8, 5u8, 10u8, 4u8];
const TEST_STRING: &'static str = "I'm a string!";
const TEST_COW: &'static str = "Cow!";
const TEST_STRUCT: TestStruct = TestStruct
{
test_u8: 12u8,
test_vec: &["Hello there."],
};
const TEST_TUP_STRUCT: TestTup = TestTup(4u8, 55u16);
const TEST_ENUM: TestEnum = TestEnum::Variant1;
const TEST_ENUM_TUP: TestEnum = TestEnum::Variant2(23u8);
const TEST_ENUM_STRUCTLIKE: TestEnum = TestEnum::Variant3
{
named: 78u8
};
static TEST_U8_STATIC: u8 = 27u8;
开箱即用的实现
下表显示了已经定义了 CompileConst 特征实现的类型
类型 | 常量表示 |
---|---|
<所有数值基本类型> | 无需转换 |
bool | 无需转换 |
String, &str, str | &'static str |
Vec<T>, &[T] | &'static [T] |
[T; N where N is 0-256] | [T's CompileConst representation; N] |
Box<T>, Cow<T>, Rc<T>, Arc<T> | T's CompileConst representation |
Option<T> | Option<T's CompileConst representation> |
HashMap<K,V> | phf::Map<K, V>, with K and V's CompileConst representation |
HashSet<E> | phf::Set<E>, with E's CompileConst representation |
() | 无需转换 |
<具有 2-16 个变体的元组> | 包含每个变体的 CompileConst 表示的元组 |
还有一个 CompileConstArray 特征,它为以下内容生成固定大小的数组而不是静态切片
类型 | 常量数组表示 |
---|---|
Vec<T>, &[T] | [T; N] |
String, &str, str | [char; N] |
Box<T>, Cow<T>, Rc<T>, Arc<T> | T's CompileConstArray representation |
() | 无需转换 |
<具有 2-16 个变体的元组> | 包含每个变体的 CompileConstArray 表示的元组。仅当每个变体实现 CompileConstArray 时才受支持。 |
属性
#[inherit_doc] 生成的定义将继承源项的文档。
#[inherit_docs] 生成的定义将继承源项的文档,以及内部项(字段和变体)的文档。
限制
这个包将使用宿主机的字节序、指针宽度等,而不是目标机的。例如,在整数上调用 to_ne_bytes
并将结果存储在常量中,可能会导致字节表示形式与目标机上相同的整数不等效。
特性
目前,所有特性都是默认的。
phf
phf
特性为 HashMap 和 HashSet 实现了 CompileConst 特性。它将为 HashMap 类型生成一个 phf::Map
,为 HashSet 类型生成一个 phf::Set
。请注意,phf
不需要包含在您的构建依赖项中,但为了使用常量,它应该包含在您的运行时依赖项中。
derive
derive
特性为结构和枚举添加了 #[derive(CompileConst)]
。要求所有成员都实现 CompileConst
。可以添加 #[inherit_docs]
属性,以便生成的定义继承 rustdocs。
std
可以禁用 std
默认特性,以使用 alloc
包代替 std
构造。
依赖项
~215KB