Macro pin_init::init_pin[][src]

init_pin!() { /* proc-macro */ }
Expand description

Create and pin-initialize a struct.

The type to create need to be marked with #[pin_init].

#[pin_init]
struct ManyPin {
    #[pin]
    a: NeedPin,
    b: usize,
}
let p = Box::pin_with(init_pin!(ManyPin {
    a: NeedPin::new(),
    b: 0,
}));

Also works for tuple-structs:

#[pin_init]
struct ManyPin(#[pin] NeedPin, usize);
let p = Box::pin_with(init_pin!(ManyPin(
    NeedPin::new(),
    0,
)));

You could apply it to unit-structs (but probably not very useful):

#[pin_init]
struct NoPin;
let p: Result<_, Infallible> = Box::pin_with(init_pin!(NoPin));

By default, no conversions are made for errors, as otherwise type inference may fail (like using the ? operator in a closure). If you need error conversion, you can use Init::map_err. You may need type annotation or specify_err to avoid type inference failure.

#[pin_init]
let p: Result<Pin<Box<_>>, Infallible> = Box::pin_with(init_pin!(ManyPin {
    a: NeedPin::new().map_err(Into::into),
    b: 0,
}));

init_pin! can be used for nested initialization as well:

#[pin_init]
struct TooManyPin {
    #[pin]
    a: NeedPin,
    #[pin]
    b: ManyPin,
}
let p = Box::pin_with(init_pin!(TooManyPin {
    a: NeedPin::new(),
    // Nested by default. To opt out write `b: #[unpin] NeedPin {`.
    b: ManyPin {
        a: NeedPin::new(),
        b: 0,
    },
}));

If you want to define a constructor, you can write like this:

impl ManyPin {
    pub fn new() -> impl Init<Self, Infallible> {
        init_pin!(ManyPin {
            a: NeedPin::new(),
            b: 1,
        })
    }
}

init_pin! can also initialize some std types:

use core::cell::UnsafeCell;
use core::cell::Cell;
specify_err::<_, Infallible, _>(init_pin!(PhantomPinned));
init_pin!(UnsafeCell(NeedPin::new()));
init_pin!(Cell(NeedPin::new()));