Trait deferred_reference::Defer[][src]

pub trait Defer {
    type Target: ?Sized;
    fn defer(&self) -> Deferred<&Self::Target>;
}

The Defer trait offers easy access to deferred immutable references to types that implement Defer.

Examples

use deferred_reference::{Defer, Deferred};
use core::cell::UnsafeCell;

// Defer is implemented by default for any `UnsafeCell` holding an array or a slice:
let buffer = UnsafeCell::new([0u8; 1024]);
let deferred: Deferred<&[u8; 1024]> = buffer.defer();
// A deferred reference to an *array* can be unsized to a deferred reference to a *slice*:
let deferred_unsized: Deferred<&[u8]> = deferred.into();
// Dereferencing will create an actual reference `&[u8]`:
assert_eq!(*deferred, *deferred_unsized);
assert_eq!(*deferred, &[0u8; 1024][..]);

// Even though this crate is `#![no_std]`, it works with heap allocated contents as well:
let buffer = Box::new(UnsafeCell::new([0u8; 1024]));
let deferred /* : Deferred<&[u8; 1024]> */ = buffer.defer(); // omitting the type is okay
let deferred_unsized: Deferred<&[u8]> = deferred.into(); // unsize needs explicit type
// Dereferencing will create an actual reference `&[u8]`:
assert_eq!(*deferred, *deferred_unsized);
assert_eq!(*deferred, &[0u8; 1024][..]);

Why is Defer not implemented for all types?

The Defer trait comes implemented for all UnsafeCell<T: ?Sized>, but it is not implemented for all types T: ?Sized which are not wrapped in an UnsafeCell. This is by design, because calling the Defer::defer(&self) method will take out an immutable reference for as long as the returned Deferred is in use. In other words, this is not a deferrred immutable reference, but an actual immutable reference to the underlying type. As long as this immutable reference is in use, it is not allowed to create additional (deferred) mutable references due to the Rust borrowing rules, unless the type is wrapped in an UnsafeCell, which allows for interior mutability (in fact this is the only way that Rust supports interior mutability). If you don’t intend to mutate the underlying type, then there is no use-case for Defer and you’re better off using an immutable reference &T instead of a Deferred<&T>. If you do intend to mutate the underlying type, but have a good reason not to use UnsafeCell, then you may do so using the unsafe defer! and defer_mut! macros. However, use of these macros is not recommend and you should probably only use these if you know what you’re doing, because the lifetime of the Deferred returned by these macros is unbounded and the burden of managing the lifetimes falls on the implementor. Note that there are also other (safe) ways to construct a deferred immutable reference, see the documentation at Deferred for more information on how to do this.

Associated Types

type Target: ?Sized[src]

The type that the deferred reference points to.

Loading content...

Required methods

fn defer(&self) -> Deferred<&Self::Target>[src]

Obtain a deferred immutable reference to a Defer::Target.

Loading content...

Implementations on Foreign Types

impl<T: ?Sized> Defer for UnsafeCell<T>[src]

type Target = T

Loading content...

Implementors

impl<T: Reference> Defer for Deferred<T>[src]

type Target = T::Target

Loading content...