Struct selfie::Selfie

source ·
pub struct Selfie<'a, P, R>
where P: 'a, R: for<'this> RefType<'this>,
{ /* private fields */ }
Expand description

A self-referential struct with a shared reference (R) to an object owned by a pinned pointer (P).

If you need a self-referential struct with an exclusive (mutable) reference to the data behind P, see SelfieMut.

This struct is a simple wrapper containing both the pinned pointer P and the shared reference to it R alongside it. It does not perform any additional kind of boxing or allocation.

A Selfie is constructed by using the new constructor, which requires the pinned pointer P, and a function to create the reference type R from a shared reference to the data behind P.

Because R references the data behind P for as long as this struct exists, the data behind P has to be considered to be borrowed for the lifetime of the Selfie.

Therefore, you can only access the data behind P through shared references (&T) using owned, or by using into_owned, which drops R and returns P as it was given to the constructor.

Note that the referential type R is not accessible outside of the Selfie either, and can only be accessed by temporarily borrowing it through the with_referential and with_referential_mut methods, which hide its true lifetime.

This is done because R actually has a self-referential lifetime, which cannot be named in Rust’s current lifetime system.

Also because of the non-nameable self-referential lifetime, R is not the referential type itself, but a stand-in that implements RefType (e.g. Ref<T> instead of &T). See the refs module for some reference type stand-ins this library provides, or see the RefType trait documentation for how to implement your own.

§Example

This example stores both an owned String and a str slice pointing into it.

use core::pin::Pin;
use selfie::{refs::Ref, Selfie};

let data: Pin<String> = Pin::new("Hello, world!".to_owned());
let selfie: Selfie<String, Ref<str>> = Selfie::new(data, |s| &s[0..5]);

assert_eq!("Hello", selfie.with_referential(|r| *r));
assert_eq!("Hello, world!", selfie.owned());

Implementations§

source§

impl<'a, P, R> Selfie<'a, P, R>
where P: StableDeref + 'a, R: for<'this> RefType<'this>, P::Target: 'a,

source

pub fn new<F>(owned: Pin<P>, handler: F) -> Self
where F: for<'this> FnOnce(&'this P::Target) -> <R as RefType<'this>>::Ref,

Creates a new Selfie from a pinned pointer P, and a closure to create the reference type R from a shared reference to the data behind P.

Note the closure cannot expect to be called with a specific lifetime, as it will handle the unnameable 'this lifetime instead.

§Example
use std::pin::Pin;
use selfie::refs::Ref;
use selfie::Selfie;

let data = Pin::new("Hello, world!".to_owned());
let selfie: Selfie<String, Ref<str>> = Selfie::new(data, |s| &s[0..5]);

// The selfie now contains both the String buffer and a subslice to "Hello"
assert_eq!("Hello", selfie.with_referential(|r| *r));
source

pub fn try_new<E, F>( owned: Pin<P>, handler: F ) -> Result<Self, SelfieError<P, E>>
where F: for<'this> FnOnce(&'this P::Target) -> Result<<R as RefType<'this>>::Ref, E>,

Creates a new Selfie from a pinned pointer P, and a fallible closure to create the reference type R from a shared reference to the data behind P.

Note the closure cannot expect to be called with a specific lifetime, as it will handle the unnameable 'this lifetime instead.

§Errors

The closure can return a Result containing either the referential type, or any error type. If the closure returns an Err, it will be returned in a SelfieError alongside the original owned pointer type.

§Example
use std::pin::Pin;
use selfie::refs::Ref;
use selfie::{Selfie, SelfieError};

let data = Pin::new("Hello, world!".to_owned());
let selfie: Result<Selfie<String, Ref<str>>, SelfieError<String, ()>>
    = Selfie::try_new(data, |s| Ok(&s[0..5]));

assert_eq!("Hello", selfie.unwrap().with_referential(|r| *r));
source

pub fn owned(&self) -> &P::Target

Returns a shared reference to the owned type by de-referencing P.

§Example
use core::pin::Pin;
use selfie::{refs::Ref, Selfie};

let data: Pin<Box<u32>> = Box::pin(42);
let selfie: Selfie<Box<u32>, Ref<u32>> = Selfie::new(data, |i| i);

assert_eq!(&42, selfie.owned());
source

pub fn with_referential<'s, F, T>(&'s self, handler: F) -> T
where F: for<'this> FnOnce(&'s <R as RefType<'this>>::Ref) -> T,

Performs an operation borrowing the referential type R, and returns its result.

§Example
use core::pin::Pin;
use selfie::{refs::Ref, Selfie};

let data: Pin<Box<u32>> = Box::pin(42);
let selfie: Selfie<Box<u32>, Ref<u32>> = Selfie::new(data, |i| i);

assert_eq!(50, selfie.with_referential(|r| *r + 8));
source

pub fn with_referential_mut<'s, F, T>(&'s mut self, handler: F) -> T
where F: for<'this> FnOnce(&'s mut <R as RefType<'this>>::Ref) -> T,

Performs an operation mutably borrowing the referential type R, and returns its result.

Note that this operation cannot mutably access the data behind P, it only mutates the referential type R itself.

§Example
use core::pin::Pin;
use selfie::{refs::Ref, Selfie};

let data: Pin<String> = Pin::new("Hello, world!".to_owned());
let mut selfie: Selfie<String, Ref<str>> = Selfie::new(data, |s| &s[0..5]);

assert_eq!("Hello", selfie.with_referential(|r| *r));
assert_eq!("Hello, world!", selfie.owned());

selfie.with_referential_mut(|s| *s = &s[0..2]);

assert_eq!("He", selfie.with_referential(|r| *r));
assert_eq!("Hello, world!", selfie.owned());
source

pub fn into_owned(self) -> Pin<P>

Unwraps the Selfie by dropping the reference type R, and returning the owned pointer type P, as it was passed to the constructor.

§Example
use std::pin::Pin;
use selfie::refs::Ref;
use selfie::Selfie;

let data = Pin::new("Hello, world!".to_owned());
let selfie: Selfie<String, Ref<str>> = Selfie::new(data, |str| &str[0..5]);

let original_data: Pin<String> = selfie.into_owned();
assert_eq!("Hello, world!", original_data.as_ref().get_ref());
source

pub fn map<R2: for<'this> RefType<'this>, F>( self, mapper: F ) -> Selfie<'a, P, R2>
where F: for<'this> FnOnce(<R as RefType<'this>>::Ref, &'this P::Target) -> <R2 as RefType<'this>>::Ref,

Creates a new Selfie by consuming this Selfie’s reference type R and producing another (R2), using a given closure.

The owned pointer type P is left unchanged, and a shared reference to the data behind it is also provided to the closure for convenience.

This method consumes the Selfie. If you need to keep it intact, see map_cloned.

§Example
use std::pin::Pin;
use selfie::refs::Ref;
use selfie::Selfie;

let data = Pin::new("Hello, world!".to_owned());
let selfie: Selfie<String, Ref<str>> = Selfie::new(data, |str| &str[0..5]);
assert_eq!("Hello", selfie.with_referential(|r| *r));

let selfie = selfie.map::<Ref<str>, _>(|str, _| &str[3..]);
assert_eq!("lo", selfie.with_referential(|r| *r));

let selfie: Selfie<String, Ref<str>> = selfie.map(|_, owned| &owned[7..]);
assert_eq!("world!", selfie.with_referential(|r| *r));
source

pub fn try_map<R2: for<'this> RefType<'this>, E, F>( self, mapper: F ) -> Result<Selfie<'a, P, R2>, SelfieError<P, E>>
where F: for<'this> FnOnce(<R as RefType<'this>>::Ref, &'this P::Target) -> Result<<R2 as RefType<'this>>::Ref, E>,

Creates a new Selfie by consuming this Selfie’s reference type R and producing another (R2), using a given fallible closure.

The owned pointer type P is left unchanged, and a shared reference to the data behind it is also provided to the closure for convenience.

This method consumes the Selfie. If you need to keep it intact, see try_map_cloned.

§Errors

The closure can return a Result containing either the referential type, or any error type. If the closure returns an Err, it will be returned in a SelfieError alongside the original owned pointer type.

§Example
use std::pin::Pin;
use selfie::refs::Ref;
use selfie::{Selfie, SelfieError};

let data = Pin::new("Hello, world!".to_owned());
let selfie: Selfie<String, Ref<str>> = Selfie::new(data, |str| &str[0..5]);
assert_eq!("Hello", selfie.with_referential(|r| *r));

let selfie = selfie.try_map::<Ref<str>, (), _>(|str, _| Ok(&str[3..])).unwrap();
assert_eq!("lo", selfie.with_referential(|r| *r));

let selfie: Result<Selfie<String, Ref<str>>, SelfieError<String,()>> = selfie.try_map(|_, owned| Ok(&owned[7..]));
assert_eq!("world!", selfie.unwrap().with_referential(|r| *r));
source

pub fn map_cloned<R2: for<'this> RefType<'this>, F>( &self, mapper: F ) -> Selfie<'a, P, R2>
where F: for<'this> FnOnce(&<R as RefType<'this>>::Ref, &'this P::Target) -> <R2 as RefType<'this>>::Ref, P: CloneStableDeref,

Creates a new Selfie by cloning this Selfie’s reference pointer P and producing a new reference (R2), using a given closure.

The owned pointer type P needs to be CloneStableDeref, as only the pointer itself is going to be cloned, not the data behind it. Both the current reference R and the new R2 will refer to the data behind P.

This method keeps the original Selfie unchanged, as only its owned pointer is cloned.

§Example
use std::rc::Rc;
use selfie::refs::Ref;
use selfie::Selfie;

let data = Rc::pin("Hello, world!".to_owned());
let selfie: Selfie<Rc<String>, Ref<str>> = Selfie::new(data, |str| &str[0..5]);
selfie.with_referential(|s| assert_eq!("Hello", *s));

let second_selfie = selfie.map_cloned::<Ref<str>, _>(|str, _| &str[3..]);
second_selfie.with_referential(|s| assert_eq!("lo", *s));
selfie.with_referential(|s| assert_eq!("Hello", *s)); // Old one still works

drop(selfie);
second_selfie.with_referential(|s| assert_eq!("lo", *s)); // New one still works
source

pub fn try_map_cloned<R2: for<'this> RefType<'this>, E, F>( &self, mapper: F ) -> Result<Selfie<'a, P, R2>, E>
where F: for<'this> FnOnce(&<R as RefType<'this>>::Ref, &'this P::Target) -> Result<<R2 as RefType<'this>>::Ref, E>, P: CloneStableDeref,

Creates a new Selfie by cloning this Selfie’s reference pointer P and producing a new reference (R2), using a given fallible closure.

The owned pointer type P needs to be CloneStableDeref, as only the pointer itself is going to be cloned, not the data behind it. Both the current reference R and the new R2 will refer to the data behind P.

This method keeps the original Selfie unchanged, as only its owned pointer is cloned.

§Errors

The closure can return a Result containing either the referential type, or any error type. If the closure returns an Err, it will be returned right away.

§Example
use std::rc::Rc;
use selfie::refs::Ref;
use selfie::Selfie;

let data = Rc::pin("Hello, world!".to_owned());
let selfie: Selfie<Rc<String>, Ref<str>> = Selfie::new(data, |str| &str[0..5]);
selfie.with_referential(|s| assert_eq!("Hello", *s));

let second_selfie = selfie.try_map_cloned::<Ref<str>, (), _>(|str, _| Ok(&str[3..])).unwrap();
second_selfie.with_referential(|s| assert_eq!("lo", *s));
selfie.with_referential(|s| assert_eq!("Hello", *s)); // Old one still works

drop(selfie);
second_selfie.with_referential(|s| assert_eq!("lo", *s)); // New one still works

Trait Implementations§

source§

impl<'a, P, R> Debug for Selfie<'a, P, R>
where P::Target: Debug, for<'this> <R as RefType<'this>>::Ref: Debug, P: 'a + StableDeref, R: for<'this> RefType<'this>,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, P, R> Freeze for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: Freeze, P: Freeze,

§

impl<'a, P, R> RefUnwindSafe for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: RefUnwindSafe, P: RefUnwindSafe,

§

impl<'a, P, R> Send for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: Send, P: Send,

§

impl<'a, P, R> Sync for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: Sync, P: Sync,

§

impl<'a, P, R> Unpin for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: Unpin, P: Unpin,

§

impl<'a, P, R> UnwindSafe for Selfie<'a, P, R>
where <R as RefType<'a>>::Ref: UnwindSafe, P: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where 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 T
where 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 T
where 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 T
where 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.