[][src]Struct gsrs::SRS

pub struct SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
{ /* fields omitted */ }

Self Referencing Struct

Allows owner and references to it to be saved in a same movable struct

In general you create SRS with create_with, modify it with with, use it with get_ref and in the end it will be dropped automatically or you can use split to keep some parts if necessary.f

If you want to add additional owned values you will need arena-like structure like Arena from typed_arena

If Owner type can be extended while there are references to existing data, like Arena, you can use default otherwise new is the only way to create it

It is recommended to annotate lifetime used for DerefWithLifetime impl as 'static when creating SRS otherwise it might be impossible to move it.

Methods

impl<'a, Owner: 'a, U: Default> SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
[src]

pub fn new(owner: Owner) -> Self[src]

Creates new SRS instance without any actual self reference. with method should be used to add self references afterwards

impl<'a, Owner: 'a, U> SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
[src]

pub fn create_with<'b, F>(owner: Owner, f: F) -> Self where
    F: 'static + FnOnce(&'b Owner) -> <U as DerefWithLifetime<'b>>::Target,
    Owner: 'b,
    U: 'b, 
[src]

Creates SRS from Owner and a function that creates self referencing part from owner

use gsrs::*;
struct Test{field:usize}
struct TestRef<'a>(&'a Test);
deref_with_lifetime!(TestRef);
// let a = None;
let mut srs = SRS::<Test,TestRef<'static>>::create_with(
    Test{field:5},
    |owner|TestRef(owner),
);
let r = srs.get_ref(|user,_|user.0);
let mut ow = Box::new(Test{field:0});
let r = srs.split(&mut ow);
println!("{}",r.0.field);

pub fn split<'b>(
    self,
    new: &'b mut Box<Owner>
) -> <U as DerefWithLifetime<'b>>::Target
[src]

Splits SRS into owned and borrowed parts.

Be careful because reverse operation is impossible because there is no way to know that references, that we will bundle with Owner, are actually all pointing inside Owner.

It requires some existing Owner because it needs place where to move it out and get lifetime from.

use gsrs::*;
struct Test{field:usize}
#[derive(Default)]
struct TestRef<'a>(Option<&'a Test>);
deref_with_lifetime!(TestRef);
let mut srs = SRS::<Test,TestRef<'static>>::new(Test{field:5});
srs.with(|user, owner|*user = TestRef(Some(owner)));
// do some work with srs
let mut ow = Box::new(Test{field:0});
let r = srs.split(&mut ow);
println!("{}",r.0.unwrap().field);

pub fn with<'b, F, Z: 'static>(&'b mut self, f: F) -> Z where
    F: 'static + FnOnce(&'x mut <U as DerefWithLifetime<'b>>::Target, &'b Owner) -> Z,
    'a: 'b, 
[src]

Main interface to modify SRS

Used to actually create or mutate SRS

Safety

'static lifetime on closure and on return value is required to prevent saving outer references in user and enforcing 'b lifetime allows to use references to data inside this struct outside. Moving struct is safe because you can't get reference to the underlying fields (Owner is behind Box and U is behind incompatible lifetime when passed into closure).

pub fn get_ref<'b, F, Z: ?Sized + 'static>(&'b self, f: F) -> &'b Z where
    F: 'static + FnOnce(&'x <U as DerefWithLifetime<'b>>::Target, &'b Owner) -> &'b Z,
    'a: 'b, 
[src]

Method for using 'SRS'

Allows you to get existing self reference to use it outside

Safety

Same as for with

Trait Implementations

impl<Owner: Debug, U: Debug> Debug for SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
[src]

impl<Owner: Default, U: Default> Default for SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
[src]

impl<'a, Owner: 'a, U> Deref for SRS<Owner, U> where
    U: for<'b> DerefWithLifetime<'b>, 
[src]

type Target = Owner

The resulting type after dereferencing.

Auto Trait Implementations

impl<Owner, U> RefUnwindSafe for SRS<Owner, U> where
    Owner: RefUnwindSafe,
    U: RefUnwindSafe

impl<Owner, U> !Send for SRS<Owner, U>

impl<Owner, U> !Sync for SRS<Owner, U>

impl<Owner, U> Unpin for SRS<Owner, U> where
    U: Unpin

impl<Owner, U> UnwindSafe for SRS<Owner, U> where
    Owner: RefUnwindSafe,
    U: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.