Macro pin_init::init_pin[][src]

macro_rules! init_pin {
    (try $err:ty => $ty:ident { $($tt:tt)* }) => { ... };
    (try $err:ty => $ty:ident ( $($tt:tt)* )) => { ... };
    (try $err:ty => $ty:ident) => { ... };
    ($ty:ident { $($tt:tt)* }) => { ... };
    ($ty:ident ( $($tt:tt)* )) => { ... };
    ($ty:ident) => { ... };
}
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 = new_box(init_pin!(ManyPin {
    a: NeedPin::new,
    b: 0,
}));

Also works for tuple-structs:

#[pin_init]
struct ManyPin(#[pin] NeedPin, usize);
let p = new_box(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> = new_box(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 need to add a ? before expression. You can add try Error => to specify the error to avoid type inference failure.

#[pin_init]
let p = new_box(init_pin!(try Infallible => ManyPin {
    a:? NeedPin::new,
    b: 0,
}));

init_pin! can be used for nested initialization as well:

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

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

impl ManyPin {
    pub fn new(this: PinInit<'_, Self>) -> PinInitResult<'_, Self, Infallible> {
        this.init(init_pin!(ManyPin {
            a: NeedPin::new,
            b: 1,
        }))
    }
}

init_pin! can also initialize some std types:

use core::cell::UnsafeCell;
use core::cell::Cell;
init_pin!(try Infallible => PhantomPinned);
init_pin!(UnsafeCell(NeedPin::new));
init_pin!(Cell(NeedPin::new));