You are reading the documentation for derive_constructors version 1.0.0
Allows to derive multiple constructor functions and implement the [From] and [TryFrom] traits for a struct by giving simple information such as their field's names.
Also allows to derive [From] for enums.
1 The Derive macros for structs: From and TryFrom
Ref: [derive_constructors_proc::From], [derive_constructors_proc::TryFrom]
These allow you to Derive the [From] and [TryFrom] traits where a tuple of the fields are passed to the [From::from] or [TryFrom::try_from] function, for example
let character_using_from = from;
let expected_character = CharacterInfo ;
assert_eq!;
2 The Attribute Macro for structs:
Ref: [derive_constructors_proc::constructor]
Allows you to define a constructor function, inside the proc attribute you can customize the implementation by giving this information following attributes (Note every attribute is optional):
-
named: Name of the function, constructor functions are usually named like 'with_name of the fields', as calling them are quite readable, like
CharacterInfo::with_name_and_age("Jorge", 23)
. Note: If this field isn't given, instead of implementing a 'with_*' constructor function, it will implement the [From] or [TryFrom] trait. -
pattern (values: [From, TryFrom], default: From):
- When using the From pattern, the function receives fields as parameters and returns this struct with said values, this is what you'll be looking for most of the time.
- When using the TryFrom pattern, the functions receives types that implement Into, Into..., returning a [Ok] with your struct if every field could successfully be turned to your field, in case not, it will return [Err] with an enum telling which field couldn't get initialized and the Error why it didn't, see examples below for this.
-
fields (default: All fields not included in the '
defaults
' attribute): Name of the fields you want to create your constructor for, for example:fields(age, name)
could result in a function like:fn new(age: u8, name: String) -> CharacterInfo
. -
defaults: Tells how to initialize fields not covered in the
fields
attribute, for exampledefaults(years_studied(4))
. If a field isn't either on thefields
ordefaults
attributes, it would count as it was initialized through [Default::default], this means, thetimes_appeared
field that hasn't been covered will be init as 0 (since u8::default() is 0). -
error_enum_named (Only for the TryFrom pattern): Specifies the name for the enum error that it's returned the TryFrom function fails.
-
error_enum_metadata (Only for the TryFrom pattern): Declares the metadata for the enum error that it's returned the TryFrom function fails, you will most likely want to write
error_enum_metadata(#[derive(Debug)])
in there.
2.1 Example 1: Empty constructor
If you just apply the [constructor] attribute, it will just implement the [From] trait where it
will take a tuple formed out of all your fields, in this case,
from(value: (String, u8)) -> CharacterInfo
.
let character_using_from = from;
let expected_character = CharacterInfo ;
assert_eq!;
2.2 Example 2: A 'new' constructor using specific fields
The following example creates a function named new(name: String, age: u8) -> CharacterInfo
.
Since years_studied
is specified, it will be initialized as 4, and since
times_appeared
is not, it will be initialized as u8::default() (which is 0).
let character_using_from = new;
let expected_character = CharacterInfo ;
assert_eq!;
2.3 Example 3: A 'new' constructor with the TryFrom pattern
The following example creates a function named new(name: T where String: TryFrom<T>, age: U where String: TryFrom<U>) -> Result<CharacterInfo, MyEnumError>
.
Since years_studied
is specified, it will be initialized as 4, and since
times_appeared
is not, it will be initialized as u8::default() (which is 0).
In case of an error, it returns a variant of an enum named MyEnumError
, this enum is
specified to derive [Debug] and [PartialEq].
let character_using_try_from = new.unwrap;
let expected_character = CharacterInfo ;
assert_eq!;
let produced_error = u8 try_from.unwrap_err;
let forced_error_using_try_from = new.unwrap_err;
let expected_error_on_try_from = AgeError;
assert_eq!;
3 The Derive macro for enums: From
Ref: [derive_constructors_proc::From]
This implement the From trait for each enum by creating a From::from function on each taking every field as value, for example:
let scattered_values = vec!;
let specified = vec!;
assert_eq!;