Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nrc/derive-new
derive simple constructor functions for Rust structs
https://github.com/nrc/derive-new
Last synced: 11 days ago
JSON representation
derive simple constructor functions for Rust structs
- Host: GitHub
- URL: https://github.com/nrc/derive-new
- Owner: nrc
- License: mit
- Created: 2016-10-08T02:10:24.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2024-08-29T02:17:52.000Z (2 months ago)
- Last Synced: 2024-09-30T10:35:30.131Z (about 1 month ago)
- Language: Rust
- Size: 109 KB
- Stars: 521
- Watchers: 8
- Forks: 35
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ccamel - nrc/derive-new - derive simple constructor functions for Rust structs (Rust)
README
# A custom derive implementation for `#[derive(new)]`
A `derive(new)` attribute creates a `new` constructor function for the annotated
type. That function takes an argument for each field in the type giving a
trivial constructor. This is useful since as your type evolves you can make the
constructor non-trivial (and add or remove fields) without changing client code
(i.e., without breaking backwards compatibility). It is also the most succinct
way to initialise a struct or an enum.Implementation uses macros 1.1 custom derive (which works in stable Rust from
1.15 onwards).`#[no_std]` is fully supported if you switch off the default feature `"std"`.
## Examples
Cargo.toml:
```toml
[dependencies]
derive-new = "0.5"
```Include the macro:
* Rust Edition 2015
```rust
#[macro_use]
extern crate derive_new;
```* Rust Edition 2018
```rust
use derive_new::new;
```Generating constructor for a simple struct:
```rust
#[derive(new)]
struct Bar {
a: i32,
b: String,
}let _ = Bar::new(42, "Hello".to_owned());
```Default values can be specified either via `#[new(default)]` attribute which removes
the argument from the constructor and populates the field with `Default::default()`,
or via `#[new(value = "..")]` which initializes the field with a given expression:```rust
#[derive(new)]
struct Foo {
x: bool,
#[new(value = "42")]
y: i32,
#[new(default)]
z: Vec,
}let _ = Foo::new(true);
```To make type conversion easier, `#[new(into)]` attribute changes the parameter type
to `impl Into`, and populates the field with `value.into()`:```rust
#[derive(new)]
struct Foo {
#[new(into)]
x: String,
}let _ = Foo::new("Hello");
```For iterators/collections, `#[new(into_iter = "T")]` attribute changes the parameter type
to `impl IntoIterator`, and populates the field with `value.into_iter().collect()`:```rust
#[derive(new)]
struct Foo {
#[new(into_iter = "bool")]
x: Vec,
}let _ = Foo::new([true, false]);
let _ = Foo::new(Some(true));
```Generic types are supported; in particular, `PhantomData` fields will be not
included in the argument list and will be initialized automatically:```rust
use std::marker::PhantomData;#[derive(new)]
struct Generic<'a, T: Default, P> {
x: &'a str,
y: PhantomData,
#[new(default)]
z: T,
}let _ = Generic::::new("Hello");
```For enums, one constructor method is generated for each variant, with the type
name being converted to snake case; otherwise, all features supported for
structs work for enum variants as well:```rust
#[derive(new)]
enum Enum {
FirstVariant,
SecondVariant(bool, #[new(default)] u8),
ThirdVariant { x: i32, #[new(value = "vec![1]")] y: Vec }
}let _ = Enum::new_first_variant();
let _ = Enum::new_second_variant(true);
let _ = Enum::new_third_variant(42);
```