1 个稳定版本
1.0.0 | 2023年9月5日 |
---|
2360 在 Rust 模式
13KB
50 行
statenum
statenum
,代表 "state-enum",是一个过程宏属性,为枚举的每个变体生成一个特性和一个结构体。
安装
将以下依赖项添加到您的 Cargo.toml
文件中
[dependencies]
statenum = "1.0"
用法
要使用 statenum
,请将 #[statenum]
属性添加到您的枚举定义中。默认情况下,生成的特性将命名为 State
。您可以通过将名称作为宏的参数提供来重写此名称。
use statenum::statenum;
#[statenum]
enum RocketStage {
Grounded,
Launched,
// and so on...
}
#[statenum("PayloadState")]
enum PayloadStage {
Vacant,
Packed,
// and so on...
}
可见性
这将生成一个名为 State
的特性和为枚举的每个变体生成的结构体。枚举的可见性会传递到 statenum
的实现中。如果枚举被标记为 pub
,则生成的结构体变体和特性也将标记为 pub
。但是,如果枚举不是公共的,则生成的组件也不会是公共的。
mod hidden {
use statenum::statenum;
#[statenum]
enum RocketStage {
Grounded,
Launched,
}
pub struct Rocket<Stage: State = Grounded> {
stage: Stage,
}
}
// This would cause an error because the enum `RocketStage` is marked as private.
// let grounded: hidden::Rocket<hidden::Grounded>;
// The same applies to the trait.
// trait PayloadState: hidden::State {}
示例
通常,Rust 中的状态模式需要使用多个结构体定义。以下示例演示了实现状态模式的典型方法,并来自 Jon Gjengset 所著的《Rust for Rustaceans》一书。
use std::marker::PhantomData;
struct Grounded;
struct Launched;
// and so on...
pub struct Rocket<Stage = Grounded> {
stage: PhantomData<Stage>,
}
impl<Stage> Rocket<Stage> {
// ...
}
impl Rocket<Grounded> {
pub fn launch(self) -> Rocket<Launched> {
Rocket::<Launched> { stage: PhantomData::<Launched> }
}
}
impl Rocket<Launched> {
pub fn accelerate(&mut self) {
// ...
}
pub fn decelerate(&mut self) {
// ...
}
}
如果不指定任何特性名称,使用宏将创建一个名为 State
的特性,如下所示(有意忽略 PhantomData
方面)
use statenum::statenum;
#[statenum]
enum RocketStage {
Grounded,
Launched,
// and so on...
}
pub struct Rocket<Stage: State = Grounded> {
stage: Stage,
}
impl<Stage: State> Rocket<Stage> {
// ...
}
impl Rocket<Grounded> {
pub fn launch(self) -> Rocket<Launched> {
Rocket::<Launched> { stage: Launched }
}
}
impl Rocket<Launched> {
pub fn accelerate(&mut self) {
// ...
}
pub fn decelerate(&mut self) {
// ...
}
}
否则,如果您希望将特性命名为除 State
之外的其他名称,可以通过指定名称来完成
use statenum::statenum;
#[statenum("RocketState")]
enum RocketStage {
Grounded,
Launched,
// and so on...
}
pub struct Rocket<Stage: RocketState = Grounded> {
stage: Stage,
}
impl<Stage: RocketState> Rocket<Stage> {
// ...
}
impl Rocket<Grounded> {
pub fn launch(self) -> Rocket<Launched> {
Rocket::<Launched> { stage: Launched }
}
}
impl Rocket<Launched> {
pub fn accelerate(&mut self) {
// ...
}
pub fn decelerate(&mut self) {
// ...
}
}
许可证
statenum
根据 MIT 许可证分发。
依赖项
~275–730KB
~17K SLoC