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.