droppable-pin 0.1.1

The eponoymous `droppable_pin!` macro around a given `let var = pin!()` declaration allows invoking `pin_drop!` and `pin_set!` on the given `var`, which have in turn been designed to avoid silly borrow-checking errors.
Documentation

::droppable-pin

The eponoymous droppable_pin! macro around a given let var = pin!() declaration allows invoking pin_drop! and pin_set! on the given var, which have in turn been designed to avoid silly borrow-checking errors.

Repository Latest version Documentation MSRV unsafe used so that you don't License CI no_std compatible


Example

# async {
#
use ::core::pin::pin;
use ::droppable_pin::{droppable_pin, pin_drop, pin_set}; // 👈
use ::futures_util::future::{Fuse, FusedFuture, FutureExt};

async fn foo() {}
async fn bar(_borrowed: &mut i32) {}

let mut borrowed = 42;
droppable_pin! { // 👈
    let mut a = pin!(Fuse::terminated()); // Reminder: `Fuse::terminated()` is akin to `None`,
    let mut b = pin!(Fuse::terminated()); // and `future().fuse()`, to `Some(future())`.
}
loop {
    if a.is_terminated() {
        // 👇
        pin_set!(a, foo().fuse());
        // same as:
        a.set(foo().fuse());
    }
    if b.is_terminated() {
        // 1. Needed because of the `&mut borrowed` capture (see # Motivation).
        // 👇
        pin_drop!(b);
        pin_set!(b, bar(&mut borrowed).fuse());
        // 👆
        // 2. Cannot use `Pin::set()` here because of `pin_drop!()`.
    }
    ::futures_util::select! {
        () = a.as_mut() => {
            /* handle this case... */
            # if true { break; }
        },
        () = b.as_mut() => {
            /* handle this case... */
        },
    }
}
#
# };

See the docs of droppable_pin! for more information and the motivation behind this.