InitPin

Trait InitPin 

Source
pub trait InitPin<T: ?Sized>: Initializer {
    // Required method
    fn init_pin<'a, 'b>(
        self,
        place: Uninit<'a, T>,
        slot: DropSlot<'a, 'b, T>,
    ) -> InitPinResult<'a, 'b, T, Self::Error>;

    // Provided methods
    fn and_pin<F: FnOnce(Pin<&mut T>)>(self, f: F) -> AndPin<Self, F> { ... }
    fn or<M, I2>(self, other: I2) -> Or<Self, I2, M>
       where I2: IntoInitPin<T, M, Error: Into<Self::Error>> { ... }
    fn or_else<F, I2>(self, f: F) -> OrElse<Self, F>
       where F: FnOnce(Self::Error) -> I2,
             I2: InitPin<T, Error: Into<Self::Error>> { ... }
    fn unwrap_or<M, I2>(self, other: I2) -> UnwrapOr<Self, I2, M>
       where I2: IntoInitPin<T, M, Error = Infallible> { ... }
    fn unwrap_or_else<F, I2>(self, f: F) -> UnwrapOrElse<Self, F>
       where F: FnOnce(Self::Error) -> I2,
             I2: InitPin<T, Error = Infallible> { ... }
}
Expand description

A trait for initializing a place with a pinned value.

This trait is used to abstract over the different ways a place can be initialized. See the implementors for more details.

§Safety

This trait is itself safe to implement. However, care must be taken when implementing the init_pin method to ensure the pinning guarantees if hand-written unsafe code is involved.

An important aspect worth noting is that the init_pin method cannot leave a partially-pin-initialized state in the provided place even if initialization fails. This is crucial to maintain the safety guarantees of the pinning abstraction.

For example, when pin-initializing a struct:

#[pin]
struct A {
    #[pin]
    b: B,
    c: C,
}

If the initialization of field b succeeds before the initialization of field c fails, b must be dropped before returning the error or resuming the panic. On the other hand, if the initialization of b fails after c is initialized, no cleanup is necessary since c is not pinned and can be safely mem::forgeted.

Required Methods§

Source

fn init_pin<'a, 'b>( self, place: Uninit<'a, T>, slot: DropSlot<'a, 'b, T>, ) -> InitPinResult<'a, 'b, T, Self::Error>

Initializes a place with a pinned value.

This method performs the actual initialization of an uninitialized place, creating a pinned reference to the initialized value. It requires both an uninitialized place and a drop slot to manage the value’s lifetime.

§Arguments
  • place - The uninitialized place to initialize
  • slot - The drop slot for managing the pinned value’s lifetime
§Returns

Returns a pinned owned reference on success, or an InitPinError containing the error and the failed place.

Provided Methods§

Source

fn and_pin<F: FnOnce(Pin<&mut T>)>(self, f: F) -> AndPin<Self, F>

Chains a closure to execute after successful initialization with a pinned reference.

This method allows you to perform additional setup on the initialized value while maintaining its pinned status. The closure receives a mutable pinned reference to the newly initialized value.

§Examples
use placid::prelude::*;
use core::pin::Pin;

let owned: POwn<Vec<_>> = pown!(
    init::value(vec![1, 2, 3]).and_pin(|mut v| v.as_mut().push(4))
);
assert_eq!(*owned, [1, 2, 3, 4]);
Source

fn or<M, I2>(self, other: I2) -> Or<Self, I2, M>
where I2: IntoInitPin<T, M, Error: Into<Self::Error>>,

Provides a fallback initializer if this one fails.

If initialization fails, the other initializer will be attempted instead. The other initializer must produce the same target type and have an error that can be converted to this initializer’s error type.

§Examples
use placid::prelude::*;

let owned: Own<u32> = own!(init::value(10u32).or(20u32));
assert_eq!(*owned, 10);

let failed: Own<u32> = own!(init::try_with(|| u32::try_from(-1i32)).or(30u32));
assert_eq!(*failed, 30);
Source

fn or_else<F, I2>(self, f: F) -> OrElse<Self, F>
where F: FnOnce(Self::Error) -> I2, I2: InitPin<T, Error: Into<Self::Error>>,

Provides a fallback initializer based on the error from this one.

If initialization fails, the closure f is called with the error, and the returned initializer is used instead. This allows for error-dependent recovery.

§Examples
use placid::prelude::*;

let owned: Own<u32> = own!(init::try_with(|| u32::try_from(-1i32)).or_else(|err| {
    println!("Initialization failed with error: {}", err);
    init::value(42u32)
}));
assert_eq!(*owned, 42);
Source

fn unwrap_or<M, I2>(self, other: I2) -> UnwrapOr<Self, I2, M>
where I2: IntoInitPin<T, M, Error = Infallible>,

Provides a fallback initializer if the primary one fails. The fallback initializer must be infallible.

§Examples
use placid::prelude::*;

let owned = own!(init::value(10u32).unwrap_or(20u32));
assert_eq!(*owned, 10);

let failed = own!(
    init::try_with(|| u32::try_from(-1i32)).unwrap_or(30u32)
);
assert_eq!(*failed, 30);
Source

fn unwrap_or_else<F, I2>(self, f: F) -> UnwrapOrElse<Self, F>
where F: FnOnce(Self::Error) -> I2, I2: InitPin<T, Error = Infallible>,

Provides a fallback initializer computed from the error of the primary one. The fallback initializer must be infallible.

§Examples
use placid::prelude::*;

let owned = own!(
    init::try_with(|| u32::try_from(-1i32))
        .unwrap_or_else(|err| {
            println!("Initialization failed with error: {}", err);
            init::value(42u32)
        })
);
assert_eq!(*owned, 42);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl InitPin<str> for Str<'_>

Source§

impl<T> InitPin<T> for Value<T>

Source§

impl<T, E, F> InitPin<T> for TryWith<F>
where F: FnOnce() -> Result<T, E>,

Source§

impl<T, F> InitPin<[T]> for RepeatWith<F>
where F: Fn(usize) -> T,

Source§

impl<T, F> InitPin<T> for With<F>
where F: FnOnce() -> T,

Source§

impl<T, F, const N: usize> InitPin<[T; N]> for RepeatWith<F>
where F: Fn(usize) -> T,

Source§

impl<T, I, F> InitPin<T> for And<I, F>
where T: ?Sized, I: Init<T>, F: FnOnce(&mut T),

Source§

impl<T, I, F> InitPin<T> for AndPin<I, F>
where T: ?Sized, I: InitPin<T>, F: FnOnce(Pin<&mut T>),

Source§

impl<T, I, F, E> InitPin<T> for MapErr<I, F>
where T: ?Sized, I: InitPin<T>, F: FnOnce(I::Error) -> E,

Source§

impl<T: Clone> InitPin<[T]> for Repeat<T>

Source§

impl<T: Clone> InitPin<[T]> for Slice<'_, T>

Source§

impl<T: Clone, const N: usize> InitPin<[T; N]> for Repeat<T>

Source§

impl<T: Clone, const N: usize> InitPin<[T; N]> for Slice<'_, T>

Source§

impl<T: ?Sized, F> InitPin<T> for Raw<F, T>
where F: FnOnce(Uninit<'_, T>) -> Own<'_, T>,

Source§

impl<T: ?Sized, F> InitPin<T> for RawPin<F, T>
where F: for<'a, 'b> FnOnce(Uninit<'a, T>, DropSlot<'a, 'b, T>) -> POwn<'b, T>,

Source§

impl<T: ?Sized, F, E> InitPin<T> for TryRaw<F, T, E>
where F: FnOnce(Uninit<'_, T>) -> InitResult<'_, T, E>,

Source§

impl<T: ?Sized, F, E> InitPin<T> for TryRawPin<F, T, E>
where F: for<'a, 'b> FnOnce(Uninit<'a, T>, DropSlot<'a, 'b, T>) -> InitPinResult<'a, 'b, T, E>,

Source§

impl<T: ?Sized, I1, M, I2> InitPin<T> for Or<I1, I2, M>
where I1: InitPin<T>, I2: IntoInitPin<T, M, Error: Into<I1::Error>>,

Source§

impl<T: ?Sized, I1, M, I2> InitPin<T> for UnwrapOr<I1, I2, M>
where I1: InitPin<T>, I2: IntoInitPin<T, M, Error = Infallible>,

Source§

impl<T: ?Sized, I1: InitPin<T>, F, I2> InitPin<T> for OrElse<I1, F>
where F: FnOnce(I1::Error) -> I2, I2: InitPin<T, Error: Into<I1::Error>>,

Source§

impl<T: ?Sized, I1: InitPin<T>, F, I2> InitPin<T> for UnwrapOrElse<I1, F>
where F: FnOnce(I1::Error) -> I2, I2: InitPin<T, Error = Infallible>,