#named #named-arguments #arguments #rust-patterns

named-ctor

类似于命名参数语法的构造函数生成proc宏

1个不稳定版本

0.1.1 2023年9月30日
0.1.0 2023年9月30日

#1115过程宏

MIT许可证

11KB
142

named-ctor

过程宏,用于生成与原生Rust类似的可选命名参数

可选命名参数

Rust不支持命名参数,但可以使用数据结构模拟。这种替代方法在Rust中特别容易实现,得益于From特性。

例如

pub struct User {
    id: u8,
    name: String,
    email: String,
    password: String,
    is_active: bool,
    is_admin: bool,
}

impl User {
    // ...
}

pub struct UserValues {
    id: u8,
    name: String,
    email: String,
    password: String,
    is_active: bool,
    is_admin: bool,
}

impl From<UserValues> for User {
    fn from(aux: UserValues) -> Self {
        Self {
            id: aux.id,
            name: aux.name,
            email: aux.email,
            password: aux.password,
            is_active: aux.is_active,
            is_admin: aux.is_admin,
        }
    }
}

pub fn main() {
    let user: User = User::from(UserValues {
        id: 0,
        email: "[email protected]".to_string(),
        name: "John Doe".to_string(),
        is_active: true,
        password: "1234".to_string(),
        is_admin: false,
    });
}

问题是什么?首先,过于繁琐。其次,如果修改了User,则需要绝对修改UserValues,否则难以维护。

使用NamedCtor

行为与上一个例子相同,但现在宏负责创建辅助结构(_User)和From实现。

use named_ctor::NamedCtor;

#[derive(NamedCtor)]
pub struct User {
    id: u8,
    name: String,
    email: String,
    password: String,
    is_active: bool,
    is_admin: bool,
}

impl User {
    // ...
}

pub fn main() {
    let user: User = User::from(_User {
        id: 0,
        email: "[email protected]".to_string(),
        name: "John Doe".to_string(),
        is_active: true,
        password: "1234".to_string(),
        is_admin: false,
    });
}

宏属性

可以自定义辅助结构的名称,并更改构造函数

use named_ctor::NamedCtor;
use core::fmt::Display;
#[derive(NamedCtor)]
#[named_ctor(name = "TaskInitValues", constructor = "new")]
pub struct Task<'a, T>
where
    T: Display
{
    id: T,
    name: &'a str,
}
let user: Task<&str> = Task::new(TaskInitValues {
    id: "example.id",
    name: "Example",
});

警告:泛型支持仅通过where子句

依赖

~1.5MB
~35K SLoC