Derive a highly configurable constructor for your struct
Basic
use fancy_constructor::new;
#[derive(new, PartialEq, Eq, Debug)]
struct MyStruct {
foo: String,
bar: u8,
}
let a = MyStruct::new("#[derive(new)]".into(), 55);
let b = MyStruct { foo: "#[derive(new)]".into(), bar: 55 };
assert_eq!(a, b);
Outputs:
impl MyStruct {
pub fn new(foo: String, bar: u8) -> Self {
Self { foo, bar }
}
}
Options showcase
#[derive(new, PartialEq, Eq, Debug)]
#[new(vis(pub(crate)), name(construct), comment("Foo"), bounds(T: Clone))]
struct MyStruct<T> {
#[new(into)]
a: T,
#[new(val("Bar".into()))]
b: String,
#[new(clone)]
c: Arc<Whatever>,
#[new(default)]
d: Vec<u8>,
}
let we = Arc::new(Whatever::default());
let a = MyStruct::<String>::construct("A", &we);
let b = MyStruct {a: "A".into(), b: "Bar".into(), c: we, d: vec![]};
assert_eq!(a, b);
Outputs:
impl<T> MyStruct<T> {
/// Foo
pub(crate) fn construct(a: impl Into<T>, c: &Arc<Whatever>) -> Self where T: Clone {
Self {
a: a.into(),
b: "Bar".into(),
c: c.clone(),
d: Default::default(),
}
}
}
Private const fn
#[derive(new, PartialEq, Eq, Debug)]
#[new(const_fn, vis())]
struct Foo(u8);
const FOO: Foo = Foo::new(128);
assert_eq!(FOO, Foo(128));
Outputs:
impl Foo {
const fn new(f1: u8) -> Self {
Self(f1)
}
}
Computed values
#[derive(new)]
struct Foo {
is_bar: bool,
#[new(val(if is_bar { 100 } else { 5 }))]
barness_level: u8,
}
assert_eq!(Foo::new(true).barness_level, 100);
assert_eq!(Foo::new(false).barness_level, 5);
Custom constructor args
#[derive(new)]
#[new(args(input_string: &str))]
struct Foo {
#[new(val(input_string.to_lowercase()))]
pub lowercase: String,
#[new(val(input_string.to_uppercase()))]
pub uppercase: String,
}
let foo = Foo::new("Foo");
assert_eq!(foo.lowercase.as_str(), "foo");
assert_eq!(foo.uppercase.as_str(), "FOO");
Renaming constructor args
#[derive(new)]
struct MyNewtype(#[new(name(my_value))] u8);
Outputs:
impl MyNewtype {
pub fn new(my_value: u8) -> Self {
Self(my_value)
}
}
Enums
#[derive(new, Eq, PartialEq, Debug)]
enum MyEnum {
#[new]
Foo { #[new(into)] bar: u8 },
Qux,
}
assert_eq!(MyEnum::new(5), MyEnum::Foo { bar: 5 });
Outputs:
impl MyEnum {
pub fn new(bar: Into<u8>) -> Self {
Self::Foo { bar: bar.into() }
}
}
Invalid inputs
#[derive(fancy_constructor::new)]
enum Foo {
Bar, // no variants marked with `#[new]`
}
#[derive(fancy_constructor::new)]
enum Foo {
#[new] Bar, // multiple variants marked with `#[new]`
#[new] Qux,
}
#[derive(fancy_constructor::new)]
union Foo { // Unions not supported
bar: u8,
qux: u8,
}