selfref 0.1.2

Pain-free self-referential pinned types
Documentation

Pain-free self-referential pinned types.

This crate (currently) requires nightly, as it relies on GATs.

Example

#![feature(generic_associated_types)]
#![feature(pin_macro)]

use core::cell::Cell;
use core::marker::PhantomData;
use core::pin::Pin;
use core::pin::pin;

use selfref::Holder;
use selfref::NewWith;
use selfref::OperateIn;
use selfref::SelfRef;
use selfref::opaque;

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

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

fn main() {
struct FooBuilder<'b>(&'b str);
impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> {
fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a {
Foo {
foo: Default::default(),
t: self.0,
}
}
}
let stack_array: [u8; 5] = *b"hello";
// a non-'static &str
let stack_str = core::str::from_utf8(&stack_array).unwrap();
let holder = pin!(Holder::new_with(FooBuilder(stack_str)));
// Actually making our Foo refer to itself.
struct SetFooRef;
impl<'k, 'b: 'k> OperateIn<'k, FooKey<'b>> for SetFooRef {
type Out = ();
fn operate_in<'a>(self, foo: Pin<&'a Foo<'a, 'b>>)
where 'k: 'a {
foo.foo.set(Some(foo.get_ref()));
}
}
holder.as_ref().operate_in(SetFooRef);
}