Struct selfref::Holder

source ·
pub struct Holder<'k, T>where
    T: Opaque + 'k,{ /* private fields */ }
Expand description

Holds an “opaqueified” T::Kind.

Note the lifetime, 'k. This can be anything, as long as T outlives it.

Examples

use core::cell::Cell;
 
use selfref::Holder;
use selfref::opaque;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    // We can use a closure here, but we need to give the compiler a hint.
    let holder = Holder::<'_, FooKey>::new_with(
        |foo| foo.build(Foo::default())
    );
}

Implementations§

source§

impl<'k, T> Holder<'k, T>where T: Opaque,

source

pub fn new_with<F>(f: F) -> Selfwhere F: for<'a> FnOnce(&mut Builder<'a, T>), T::Kind<'k>: Sized,

Creates a new holder.

Examples

Simple example:

use core::cell::Cell;
 
use selfref::Holder;
use selfref::opaque;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    // We can use a closure here, but we need to help the compiler.
    let holder = Holder::<'_, FooKey>::new_with(
        |foo| foo.build(Foo::default())
    );
}

Lifetime parameters:

use core::cell::Cell;
use core::marker::PhantomData;
 
use selfref::Holder;
use selfref::opaque;

struct Foo<'a, 'b: 'a> {
    foo: Cell<Option<&'a Foo<'a, 'b>>>,
    t: &'b str,
}

struct FooKey<'b>(PhantomData<&'b str>);
opaque! {
    impl['b] Opaque for FooKey<'b> {
        type Kind<'a> = Foo<'a, 'b>;
    }
}

fn main() {
    let stack_array: [u8; 5] = *b"hello";
    // a non-'static &str
    let stack_str = core::str::from_utf8(&stack_array).unwrap();
    let holder = Holder::<'_, FooKey<'_>>::new_with(|foo| {
        foo.build(Foo {
            foo: Default::default(),
            t: stack_str,
        });
    });
}
source§

impl<'k, T> Holder<'k, T>where T: Opaque,

source

pub fn operate_in<'i, F, R>(self: Pin<&'i Self>, f: F) -> Rwhere F: for<'x> FnOnce(OperateIn<'x, T>) -> R,

Operates in this (pinned) holder.

This “unwraps” the value in this holder, and binds its lifetime to a new stack frame.

Examples

Simple example:

use core::cell::Cell;
 
use selfref::Holder;
use selfref::opaque;

#[derive(Default)]
struct Foo<'a> {
    foo: Cell<Option<&'a Foo<'a>>>,
}

struct FooKey;
opaque! {
    impl Opaque for FooKey {
        type Kind<'a> = Foo<'a>;
    }
}

fn main() {
    let holder = Box::pin(Holder::<'_, FooKey>::new_with(
        |foo| foo.build(Foo::default())
    ));
    // Actually making our Foo refer to itself.
    holder.as_ref().operate_in(
        |foo| {
            foo.foo.set(Some(foo.get_ref()));
        }
    );
}

With lifetime parameters:

use core::cell::Cell;
use core::marker::PhantomData;
use core::pin::Pin;
 
use selfref::Holder;
use selfref::opaque;

struct Foo<'a, 'b: 'a> {
    foo: Cell<Option<&'a Foo<'a, 'b>>>,
    t: &'b str,
}

struct FooKey<'b>(PhantomData<&'b str>);
opaque! {
    impl['b] Opaque for FooKey<'b> {
        type Kind<'a> = Foo<'a, 'b>;
    }
}

fn main() {
    let stack_array: [u8; 5] = *b"hello";
    // a non-'static &str
    let stack_str = core::str::from_utf8(&stack_array).unwrap();
    let holder = Box::pin(Holder::<'_, FooKey<'_>>::new_with(|foo| {
        foo.build(Foo {
            foo: Default::default(),
            t: stack_str,
        });
    }));
    // Actually making our Foo refer to itself.
    holder.as_ref().operate_in(|foo| {
        foo.foo.set(Some(foo.get_ref()));
    });
}

Auto Trait Implementations§

§

impl<'k, T> RefUnwindSafe for Holder<'k, T>where <T as Opaque>::Kind<'k>: RefUnwindSafe,

§

impl<'k, T> Send for Holder<'k, T>where <T as Opaque>::Kind<'k>: Send,

§

impl<'k, T> Sync for Holder<'k, T>where <T as Opaque>::Kind<'k>: Sync,

§

impl<'k, T> !Unpin for Holder<'k, T>

§

impl<'k, T> UnwindSafe for Holder<'k, T>where <T as Opaque>::Kind<'k>: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.