[−][src]Derive Macro shorthand::ShortHand
#[derive(ShortHand)] { // Attributes available to this derive: #[shorthand] }
A proc_macro
to derive getter, mutgetter and setter for fields.
A list of all attributes can be found here.
Attributes
option_as_ref
This attribute makes the getter return Option<&T>
instead of &Option<T>
.
This feature is enabled by default and recommended, because most of the
functions for Option
consume the type.
You can find a discussion, about wether or not you should use it here.
const_fn
There is a new feature coming to rust called constant functions.
Functions, that are marked with const
can be executed by the compiler at
compile time, if the value is known.
const fn add(value: usize, other: usize) -> usize { value + other } let three = add(1, 2);
will be optimized to
let three = 3;
Another benefit is, that you can also save the result in a const
variable.
const fn add(value: usize, other: usize) -> usize { value + other } const THREE: usize = add(1, 2);
This feature is currently work in progress see rust-lang/rust#57563
You can read more about it here or in the RFC.
By enabling this feature the derived functions will be const
.
Please note, that not everything is currently supported and therefore some
attributes will ignore this attribute and not add const
to the function.
primitive_copy
This attribute will cause get functions to return a copy of the type, instead of a reference.
use shorthand::ShortHand; #[derive(ShortHand, Default)] #[shorthand(disable(primitive_copy))] struct Example { field: usize, #[shorthand(enable(primitive_copy))] other: usize, } let example = Example::default(); assert_eq!(example.field(), &0); assert_eq!(example.other(), 0);
This attribute is enabled by default.
Please note, that this does only work with primitive types from the standard
library, other types have to be marked with copy
.
copy
There is no way for a proc_macro
to know wether or not a type implements
Copy
, so fields, where the getter should return a copy, instead of a
reference have to be marked with #[shorthand(copy)]
.
use shorthand::ShortHand; #[derive(Default, Copy, Clone, PartialEq, Debug)] struct Number(pub usize); #[derive(ShortHand, Default)] struct Example { #[shorthand(enable(copy))] field: Number, other: Number, } let example = Example::default(); assert_eq!(example.field(), Number(0)); assert_eq!(example.other(), &Number(0));
inline
This attribute adds #[inline(always)]
to the derived function.
#[inline(always)] fn add(a: usize, b: usize) -> usize { a + b } let three = add(1, 2);
will be optimized to
let three = 1 + 2;
You can read more about the inline attribute here.
A discussion, about wether or not you should use it: https://internals.rust-lang.org/t/when-should-i-use-inline/598
This attribute is enabled by default.
must_use
This attribute will mark functions with #[must_use]
,
which means, that their results have to be used, otherwise you get a warning
#[must_use] fn hello() -> &'static str { "hello" } hello();
warning: unused return value of `hello` that must be used
--> src/main.rs:6:5
|
6 | hello();
| ^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
This is disabled by default and can only be enabled for getter and mutable
getter. If you really need this attributes on a setter you can just mark the
field with #[must_use]
and shorthand will automatically forward the
attribute (see here).
get
This attribute derives a function, to get the value of a field
(sometimes referred to as getter
).
use shorthand::ShortHand; #[derive(ShortHand, Default)] #[shorthand(disable(get))] struct Example { #[shorthand(enable(get))] field: usize, } let example = Example::default(); assert_eq!(example.field(), 0);
This attribute is enabled by default.
set
This attribute derives a function, to set the value of a field
(sometimes referred to as setter
).
use shorthand::ShortHand; #[derive(ShortHand, Default)] #[shorthand(disable(get, set))] struct Example { #[shorthand(enable(get, set))] field: usize, } let mut example = Example::default(); example.set_field(1); assert_eq!(example.field(), 1);
This attribute is enabled by default.
ignore_phantomdata
Like the name implies, this will tell the proc_macro
, to ignore
PhantomData
and to not generate functions for it.
use core::marker::PhantomData; use shorthand::ShortHand; #[derive(ShortHand, Default)] struct Example { field: PhantomData<usize>, } let example = Example::default(); example.field(); // this will cause a compiler error, because the function does not exist!
This feature is enabled by default.
skip
Like the name implies, this will tell the proc_macro
to not generate
functions for this field (skipping it).
use shorthand::ShortHand; #[derive(ShortHand, Default)] struct Example { #[shorthand(enable(skip))] field: usize, } let example = Example::default(); example.field(); // this will cause a compiler error, because the function does not exist!
into
The into
attribute adds VALUE: Into<field_type>
as a trait bound for
setters (Into
).
use shorthand::ShortHand; #[derive(ShortHand, Default)] struct Example { #[shorthand(enable(into))] field: String, other: String, } let mut example = Example::default(); example.set_field("field"); // accepts any type, that implements Into<String> or From<String> example.set_other("other".to_string()); assert_eq!(example.field(), &"field".to_string()); assert_eq!(example.other(), &"other".to_string());
This struct uses VALUE
as a generic, so you should NOT use that on your
struct
struct DoNotDoThis<VALUE> { value: VALUE, }
This attribute is not enabled by default.
forward
The forward
attribute, allows you to control how attributes are
forwarded. By default the proc_macro
will forward
the following attributes of the field to the generated function:
use shorthand::ShortHand; #[derive(ShortHand)] #[shorthand(disable(forward))] struct Example { #[shorthand(enable(forward(must_use)))] #[must_use] hello: &'static str, }
The hello
function would now have a #[must_use]
attribute:
#[must_use] fn hello() -> &'static str { "hello" }
This attribute can be applied multiple times on the same field, which would allow controlled forwarding. Please note, that this feature does not work, until this issue is fixed https://github.com/rust-lang/rust/issues/67839.
use shorthand::ShortHand; #[derive(ShortHand)] struct Example { #[shorthand(enable(forward))] #[must_use] #[shorthand(disable(forward))] #[allow(dead_code)] hello: &'static str, }
In this example only #[must_use]
is forwarded and #[allow(dead_code)]
is
not.
This attribute can also be used to forward parts of docs.
A doc comment ///
will be converted to
#[doc]
attribute.
use shorthand::ShortHand; #[derive(ShortHand, Default)] struct Example { /// Data has some special restrictions. /// - The String can only exist of uppercase characters /// - Numbers are allowed /// - The String has a maximum size of 5. #[shorthand(disable(forward))] /// This part will not be forwarded. #[shorthand(enable(forward))] /// /// # Example /// /// ``` /// println!("nice"); /// ``` data: String, }
will instruct shorthand to generate the following code
impl Example { /// Data has some special restrictions. /// - The String can only exist of uppercase characters /// - Numbers are allowed /// - The String has a maximum size of 5. /// /// # Example /// /// ``` /// println!("nice"); /// ``` #[inline(always)] pub fn data(&self) -> &String { &self.data } /// Data has some special restrictions. /// - The String can only exist of uppercase characters /// - Numbers are allowed /// - The String has a maximum size of 5. /// /// # Example /// /// ``` /// println!("nice"); /// ``` #[inline(always)] pub fn set_data(&mut self, value: String) -> &mut Self { self.data = value; self } }
as you can see the line /// This part will not be forwarded.
did not get
forwarded.
ignore_underscore
This attribute instructs the proc_macro
to ignore fields prefixed
with an _
.
This attribute is not enabled by default.
collection_magic
This attribute instructs the proc_macro
to derive additonal functions
for fields, that have a collection.
The following collections are supported:
It will derive a push_field
function for Vec
and for all the other collection types an insert_field
function.
use shorthand::ShortHand; use std::collections::BTreeMap; #[derive(ShortHand, Default)] struct Example { #[shorthand(enable(collection_magic))] value: Vec<usize>, #[shorthand(enable(collection_magic))] other: BTreeMap<usize, usize>, } let mut example = Example::default(); example.push_value(1); example.push_value(2); example.push_value(3); assert_eq!(example.value(), &vec![1, 2, 3]); example.insert_other(1, 1); example.insert_other(2, 2); example.insert_other(3, 3); assert_eq!(example.other(), &{ let mut result = BTreeMap::new(); result.insert(1, 1); result.insert(2, 2); result.insert(3, 3); result });
strip_option
This will change the input type for setter of optional fields from
Option<T>
to T
.
use shorthand::ShortHand; #[derive(ShortHand, Default)] struct Example { value: Option<usize>, #[shorthand(enable(strip_option))] other: Option<usize>, } Example::default().set_value(Some(0)); Example::default().set_other(0);
This attribute is diabled by default.
clone
The getter will clone
the field instead of returning a
reference.
use shorthand::ShortHand; use std::rc::Rc; #[derive(ShortHand, Default)] struct Example { #[shorthand(enable(clone))] value: Rc<usize>, } assert_eq!(Example::default().value(), Rc::new(0));
This attribute is diabled by default.