Macro rental::rental
[−]
[src]
macro_rules! rental { { mod $rental_mod:ident { $($items:tt)* } } => { ... }; { pub mod $rental_mod:ident { $($items:tt)* } } => { ... }; { @ITEM use $($rest:tt)* } => { ... }; { @USES $uses:item $($rest:tt)* } => { ... }; { @ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* ) where [$($clause:tt)*]; $($rest:tt)* } => { ... }; { @ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* ): Deref($($deref_ty:tt)*) where [$($clause:tt)*]; $($rest:tt)* } => { ... }; { @ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* ) where [$($clause:tt)*]; $($rest:tt)* } => { ... }; { @ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* ): Deref($($deref_ty:tt)*) where [$($clause:tt)*]; $($rest:tt)* } => { ... }; { @ITEM pub mapper $mapper:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($from_ty:tt)*) -> ($($into_ty:tt)*) where [$($clause:tt)*]; $($rest:tt)* } => { ... }; { @ITEM pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($body:tt)*)$(: Deref($($target_ty:tt)*))*; $($rest:tt)* } => { ... }; { @ITEM pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*>($($body:tt)*)$(: Deref($($target_ty:tt)*))*; $($rest:tt)* } => { ... }; { @ITEM pub mapper $mapper:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ($($from_ty:tt)*) -> ($($into_ty:tt)*); $($rest:tt)* } => { ... }; { @ITEM } => { ... }; }
This macro is the bedrock of the API. It allows you to define three different kinds of items related to renting.
NOTE: This macro is only necessary to use if you want to define new rental
types that can store customized forms of borrow other than a bare reference.
For bare references, this crate provides premade types, called
RentRef
and RentMut
, that
accomplish this. Several type aliases are also provided for common
scenarios.
The top level item in an invocation of this macro must be a module. This
module can have any name you like, may be public or not, and will hold all
declared items. Standard use
statements are also accepted inside the module.
Rentals
The first two items this macro can produce are shared and mutable rentals. Both forms are tuple-structs that contain an (owner, borrow) pair. Both have a similar API, with minor differences pointed out below. They are declared as follows:
// Shared pub rental $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* )$(: Deref($($deref_ty:tt)*))* where [$($clause:tt)*]; // Mutable pub rental mut $rental:ident<'rental $(, $param:tt $(: [$($bounds:tt)*])*)*> ( $owner_ty:ty, $($rental_ty:tt)* )$(: Deref($($deref_ty:tt)*))* where [$($clause:tt)*];
The key difference being the presence or absence of mut
before the struct
name. The first generic parameter must be a lifetime called 'rental
. This
lifetime is special and represents the lifetime of the rental struct
itself. It should be used anywhere in the rented or owner type signatures
that represents their mutual link with the rental struct itself. For
example, the definition of RentRef
looks like this:
pub rental RentRef<'rental, T: [FixedDeref + 'rental], B: [?Sized + 'rental]> (T, &'rental B): Deref(B);
The lifetime 'rental
appears as the bound on the reference, because that
is the lifetime that will be attached when you create the reference by
borrowing from the owner object inside the creation closure. Note that it
also appears as a bound on the other generic types, since they must also
naturally live at least as long as the struct does. For a type to be
eligible as an owner, it must also implement the
FixedDeref
trait. Finally, after the
declaration, you may optionally add : Deref(Target)
where Target
is the
Deref
target of the rented type. This can't be inferred, because it must
be checked to ensure that it does NOT contain the 'rental
lifetime
anywhere in its signature. If it does, then implementing Deref
would be
unsafe, and the macro will reject it.
It should also be noted that trait bounds and where clauses must be
enclosed in square brackets, e.g. T: [MyTrait]
or where [T: MyTrait]
.
This is a consequence of how macros are parsed and is not avoidable without
significant complexity.
For an overview of the API provided by rental structs, see the
documentation for the built-in RentRef
and
RentMut
structs.
Mapping
At times you may wish to transform one rental into another. This can be accomplished with "mappers", which are the third kind of item that this macro allows you to define. They are declared thusly:
pub mapper $mapper:ident<'rental $(, $param:tt)*>($($from_ty:tt)*) -> ($($into_ty:tt)*) where [$($clause:tt)*];
As with rental structs, the special 'rental
lifetime makes an appearance
here and has the same meaning. An example of the built-in
MapRef
that maps from one reference type to another
is:
pub mapper MapRef<'rental, T, U>(&'rental T) -> (&'rental U) where [T: 'rental, U: 'rental];
A mapper may be used to transform between any rental structs provided they
have identical owner types. For details see the documentation for the
built-in MapRef
and MapMut
structs.