| Crates.io | named-ctor |
| lib.rs | named-ctor |
| version | 0.1.1 |
| created_at | 2023-09-30 00:48:37.89058+00 |
| updated_at | 2023-09-30 04:49:31.120065+00 |
| description | proc-macro to generate constructor functions with syntaxt similar to named params |
| homepage | |
| repository | https://github.com/jonhteper/named-ctor |
| max_upload_size | |
| id | 988309 |
| size | 11,276 |
Procedural macro to generate an alternative of named parameters with native Rust.
Rust don't has support for named parameters, but is possible to use a simulation with data structures.
This alternative is special easy to implement in Rust tanks to From trait.
For example:
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: "john@doe.com".to_string(),
name: "John Doe".to_string(),
is_active: true,
password: "1234".to_string(),
is_admin: false,
});
}
Whats the problem? First, too boilerplate. Second, its not easy to maintain, if User is modified, is absolutely necessary modify UserValues.
NamedCtor macroThe behavior is the same as last example, but now the macro is the responsable to create both aux struct (_User) and From implementation.
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: "john@doe.com".to_string(),
name: "John Doe".to_string(),
is_active: true,
password: "1234".to_string(),
is_admin: false,
});
}
Is possible to use a custom name for the axiliar struct, and change the constructor function:
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",
});
WARNING: Generics support only via where clause