Add this to your Cargo.toml
:
toml
[dependencies]
impl_new = "0.1.0"
Or run this command in your workspace:
bash
cargo add impl_new
The new
function is a function that is used to create a new instance of a struct. It is a common pattern in Rust to use a new
function to create a new instance of a struct instead of using the struct directly. This is because it is easier to add new fields to the struct without breaking the code that uses it.
Is simple, just derive the impl_new::New
proc macro on your struct and it will generate a new
function for you.
```rust
struct Foo { name: String, age: usize, }
// The generated code will look like this:
// impl Foo {
// pub fn new(name: impl Into
fn main() {
let foo = Foo::new("Hello", 42usize); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(foo.name, "Hello".tostring());
assert_eq!(foo.age, 42);
}
```
Note: The
#[impl_new(name = "name")]
attribute is required for unnamed fields.
```rust
struct Foo(#[implnew(name = "name")] String, #[implnew(name = "age")] usize);
// The generated code will look like this:
// impl Foo {
// pub fn new(name: impl Into
fn main() {
let foo = Foo::new("Hello", 42usize); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(foo.0, "Hello".tostring());
assert_eq!(foo.1, 42);
}
```
#[impl_new(name = "name")]
The name
option specifies the name of the argument in the new
function.
Note: This attribute is required for unnamed fields.
```rust
struct User(#[implnew(name = "username")] String, #[implnew(name = "age")] i32);
// The generated code will look like this:
// impl User {
// pub fn new(username: impl Into
fn main() {
let user = User::new("Hello", 42); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(user.0, "Hello".tostring());
assert_eq!(user.1, 42);
}
```
```rust
struct User { #[implnew(name = "username")] name: String, #[implnew(name = "user_age")] age: i32, }
// The generated code will look like this:
// impl User {
// pub fn new(username: impl Into
fn main() {
let user = User::new("Hello", 42); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(user.name, "Hello".tostring());
assert_eq!(user.age, 42);
}
```
#[impl_new(default)]
The default
option will remove the field from the new
function arguments and use the default value of the field type instead.
Note: This option is conflict with the
name
option, because the field will be removed from thenew
function arguments.
```rust
struct User { name: String, #[implnew(default)] isadmin: bool, }
// The generated code will look like this:
// impl User {
// pub fn new(name: impl Into
struct Foo(#[implnew(name = "somthing")] String, #[implnew(default)] User);
// The generated code will look like this:
// impl Foo {
// pub fn new(somthing: impl Into
fn main() {
let user = User::new("Hello"); // Will use Into::into
to convert the arguments to the fields types.
let somefoo = Foo::new("Hello"); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(user.name, "Hello".tostring());
asserteq!(user.isadmin, false);
asserteq!(somefoo.0, "Hello".tostring());
asserteq!(somefoo.1, User::default());
}
```
#[impl_new(value = || <VALUE>)]
The value
option will set the field value to the given value.
Note: This option is conflict with the
name
anddefault
options, because the field will be removed from thenew
function arguments.
Note: The value must be a closure that returns the field type.
```rust
struct User { name: String, #[implnew(value = || true)] isactive: bool, }
// The generated code will look like this: (Not exactly, but you get the idea)
// impl User {
// pub fn new(name: impl Into
struct Foo(#[implnew(name = "name")] String, #[implnew(value = || true)] bool);
// The generated code will look like this: (Not exactly, but you get the idea)
// impl Foo {
// pub fn new(name: impl Into
fn main() {
let user = User::new("Bob"); // Will use Into::into
to convert the arguments to the fields types.
let somefoo = Foo::new("Bob"); // Will use Into::into
to convert the arguments to the fields types.
asserteq!(user.name, "Bob".tostring());
asserteq!(user.isactive, true);
asserteq!(somefoo.0, "Bob".tostring());
asserteq!(somefoo.1, true);
}
```
Contributions are welcome! You can contribute in many ways, for example: - Improve the documentation. - Add more tests. - Add more examples. - Report a bug by opening an issue. - Suggest a new feature by opening an issue. - Fix a bug or add a new feature. (Please open an issue first if you want to add a new feature or if you want to fix a bug that doesn't have an issue yet.) - Fix a typo. - Refactor the code. - Improve the error messages.
We are committed to providing a friendly, safe and welcoming environment for all. Please read and respect the [Code of Conduct].
See [CHANGELOG.md].
This project is licensed under the [MIT license].