Skip to content

Derive a highly configurable constructor for your struct

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

Alorel/fancy_constructor-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Derive a highly configurable constructor for your struct

MASTER CI status crates.io badge dependencies badge Coverage Status

Examples

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() } } }
Deriving the Default trait

The Default trait can be derived if the constructor ends up with no arguments:

#[derive(new, PartialEq, Eq, Debug)] #[new(default, name(construct))] struct Foo { #[new(val(u8::MAX))] bar: u8, } assert_eq!(Foo::construct(), Foo::default());

Outputs:

impl Default for Foo { fn default() -> Self { Foo::construct() } }

Attempting to use the option when the constructor has arguments will result in a compile error:

#[derive(new)] #[new(default)] struct Foo { bar: u8, }
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, }

About

Derive a highly configurable constructor for your struct

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

No packages published

Contributors 2

  •  
  •  

Languages