Skip to main content

Scope

Struct Scope 

Source
pub struct Scope<T: ?Sized> { /* private fields */ }
Expand description

Manages the lifetime of scoped references created with this library.

A Scope<T> acts effectively like an Option<&'a T> (but without the lifetime parameter). When the Scope<T> contains a reference, it is said to be assigned, when it does not it is unassigned.

An assigned Scope<T> can be used to produce StrongRef<T> instances that dereference to the contained &T. A Scope<T> cannot become unassigned while strong references exist.

Both unassigned and assigned Scope<T> instances can be used to produce WeakRef<T> instances, that can later be upgraded to StrongRef<T> instances.

To assign a &T, to a Scope<T> you use the Scope::assign() method. The method takes &T to assign and body to execute. When the body returns, and all StrongRef<T> instances created from the Scope<T> are dropped, Scope::assign() returns and the Scope<T> is again unassigned. This ensures that no dangling use of the &T can take place.

§Example

fn read_value(reference: StrongRef<i32>) -> i32 {
    *reference
}

let scope = Scope::new();
let value = 42;

let result = scope
    .assign(&value, || read_value(scope.strong_ref().unwrap()))
    .unwrap();

assert_eq!(42, result);

Implementations§

Source§

impl<T: ?Sized> Scope<T>

Source

pub const fn new() -> Self

Construct a new Scope.

This creates an unassigned Scope; assign a target using Self::assign().

§Note

Scope and WeakRef instances can also be created statically:

static SCOPE: Scope<i32> = Scope::new();
static WEAK_REF: WeakRef<'static, i32> = SCOPE.weak_ref();
let value = SCOPE.assign(&42, || *WEAK_REF.upgrade().unwrap()).unwrap();
assert_eq!(value, 42)
Source

pub fn assign<R, F: FnOnce() -> R>( &self, target: &T, body: F, ) -> Result<R, AssignedError<F>>

Run body with target assigned to self.

If self is not already assigned a target when this method is called, then:

  1. While body is executing, strong references to self will dereference to target.
  2. When body returns, this method will block until there are no strong references left to self before returning.
  3. The value returned by body is returned by this method. When this method returns, self is again considered unassigned.

This method has no effect if self is already assigned a target when called. In this case, the given body is not executed and is instead returned back to the caller in an AssignedError.

§Deadlocks

If any strong references are leaked, this method will never return.

§Errors

Will return AssignedError if self is already assigned a target when called.

§Notes

Pre-existing weak references to self will also be affected by this method.

let scope = scoped_ref::Scope::new();
let weak_ref = scope.weak_ref();
let sample = || *weak_ref.upgrade().unwrap();

let value = scope.assign(&42, sample).unwrap();
assert_eq!(value, 42);

let value = scope.assign(&43, sample).unwrap();
assert_eq!(value, 43);
Source

pub const fn weak_ref(&self) -> WeakRef<'_, T>

Construct a WeakRef to this Scope.

The returned WeakRef can be upgraded to a StrongRef with WeakRef::upgrade but only while a value is assigned to this Scope.

Source

pub fn strong_ref(&self) -> Option<StrongRef<'_, T>>

Construct a StrongRef to this Scope.

This will return None if no value is currently assigned to this Scope.

Trait Implementations§

Source§

impl<T: Debug + ?Sized> Debug for Scope<T>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<T: Default + ?Sized> Default for Scope<T>

Source§

fn default() -> Scope<T>

Returns the “default value” for a type. Read more
Source§

impl<T: Sync + ?Sized> Send for Scope<T>

Source§

impl<T: Sync + ?Sized> Sync for Scope<T>

Auto Trait Implementations§

§

impl<T> !Freeze for Scope<T>

§

impl<T> RefUnwindSafe for Scope<T>
where T: ?Sized,

§

impl<T> Unpin for Scope<T>
where T: ?Sized,

§

impl<T> UnsafeUnpin for Scope<T>
where T: ?Sized,

§

impl<T> UnwindSafe for Scope<T>
where T: ?Sized,

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>,

Source§

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>,

Source§

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.