Struct AnyMut

Source
pub struct AnyMut<'a> { /* private fields */ }
Expand description

A type-erased mutable reference.

A mutable borrow of some owned memory, just like regular Rust primitive references, except that the type of the referee is erased. This allows you to deal with and store references of different types within the same collection.

§Example

let mut data = 'z';
let mut any = sashay::AnyMut::erase(&mut data);
let reference = any.unerase_mut::<char>().expect("not a reference to `char`");

*reference = '💤';

assert_eq!(data, '💤');

Implementations§

Source§

impl<'a> AnyMut<'a>

Source

pub fn erase<T: 'static>(reference: &'a mut T) -> AnyMut<'a>

Erase the type of a mutable reference.

The resulting type retains the lifetime of the original reference, but the referred to value can only be used after unerasing the type

let mut data : char = '🦀';
let any = sashay::AnyMut::erase(&mut data);

assert!(any.contains::<char>());
Source

pub unsafe fn from_raw_parts(ptr: *mut (), type_id: TypeId) -> Self

Construct an erased reference from its raw parts.

If you already have a &mut T, it is recommended to call AnyMut::erase().

This function behaves the same as calling as *mut T on a reference, with the addition that it takes a unique type_id representing the type T.

§Safety

Calling this is only defined behaviour if:

  • The pointer refers to a valid T
  • type_id is the correct TypeId for T
Source

pub fn unerase<T: 'static>(&self) -> Option<&T>

Unerase back to an immutable reference.

This behaves essentially the same as Any::downcast_ref(). If the original reference’s type was T, a valid reference is returned. Otherwise, you get None.

Note that while AnyMut represents a mutable reference, this function unerases it to an immutable one. If you need a mutable reference, use AnyMut::unerase_mut() or AnyMut::unerase_into()

let data : i32 = 7;
let any = sashay::AnyRef::erase(&data);

// You can unerase multiple times, because this is a shared, immutable reference
let unerased_a = any.unerase::<i32>().unwrap();
let unerased_b = any.unerase::<i32>().unwrap();
assert_eq!(unerased_a, unerased_b);

// Doesn't compile, because you can't mutate
// *unerased_a = 0;

// Unerasing to a different type gives you nothing
assert!(any.unerase::<bool>().is_none());
Source

pub fn unerase_mut<T: 'static>(&mut self) -> Option<&mut T>

Unerase back to a mutable reference.

This behaves essentially the same as Any::downcast_mut(). If the original reference’s type was T, a valid reference is returned. Otherwise, you get None.

Note that this function unerases to a mutable reference. If you only need an immutable one, you can use AnyMut::unerase()

let mut data : i32 = 7;
let mut any = sashay::AnyMut::erase(&mut data);

// You can unerase back to a mutable reference
let unerased = any.unerase_mut::<i32>().unwrap();
*unerased = 0;
assert_eq!(data, 0);

// You can't unerase_mut twice, because this is a _unique_, mutable reference
// any.unerase_mut::<i32>();
Source

pub fn unerase_into<T: 'static>(self) -> Option<&'a mut T>

Unerase back into a mutable reference.

This behaves essentially the same as AnyMut::unerase_mut(), except that ownership is tranferred into the reference. If the original reference’s type was T, a valid reference is returned. Otherwise, you get None.

let mut data : i32 = 7;

let unerased = {
    // Unerase, transferring ownership into the resulting reference
    let any = sashay::AnyMut::erase(&mut data);
    let unerased = any.unerase_into::<i32>().unwrap();

    // Can't unerase anymore after this, ownerhip has been moved out of the any
    // any.unerase_into::<i32>();

    // Because unerase_into() transfers ownership, the resulting reference's lifetime
    // can escape the any's lifetime scope and just reference the original data
    unerased
};

*unerased = 11;
assert_eq!(data, 11);
Source

pub fn borrow(&self) -> AnyRef<'_>

Borrow this mutable reference as an immutable one.

Even though you have mutable and unique access to a reference, this fuction lets you trade in the mutability for shared access.

let mut data : i32 = 7;
let any = sashay::AnyMut::erase(&mut data);

// borrow() can be called multiple times, because immutable references provide shared access
let immutable_a : sashay::AnyRef = any.borrow();
let immutable_b : sashay::AnyRef = any.borrow();

assert_eq!(immutable_a.unerase::<i32>(), Some(&7));
assert_eq!(immutable_b.unerase::<i32>(), Some(&7));
Source

pub fn borrow_mut(&mut self) -> AnyMut<'_>

Borrow this mutable reference as a mutable reference with lifetime ’self

This operation might seem redundant, but just like regular references coming out of methods have the lifetime or self, you can use borrow_mut() to do the same. The resulting AnyMut has its lifetime tied to self.

struct Container<'a> {
    any: sashay::AnyMut<'a>,
}

impl<'a> Container<'a> {
    fn get_ref<'b>(&'b mut self) -> sashay::AnyMut<'b> {
        self.any.borrow_mut()
    }
}
Source

pub const fn as_ptr(&self) -> *const ()

Retrieve an unsafe immutable pointer to the raw data.

Source

pub fn as_mut_ptr(&mut self) -> *mut ()

Retrieve an unsafe mutable pointer to the raw data.

Source

pub fn contains<T: 'static>(&self) -> bool

Was the original referee of type T?

Source

pub const fn type_id(&self) -> &TypeId

A unique type id representing the original reference type T.

Trait Implementations§

Source§

impl<'a> Debug for AnyMut<'a>

Source§

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

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

impl<'a, T: 'static> From<&'a mut T> for AnyMut<'a>

Source§

fn from(reference: &'a mut T) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<'a> Freeze for AnyMut<'a>

§

impl<'a> RefUnwindSafe for AnyMut<'a>

§

impl<'a> !Send for AnyMut<'a>

§

impl<'a> !Sync for AnyMut<'a>

§

impl<'a> Unpin for AnyMut<'a>

§

impl<'a> !UnwindSafe for AnyMut<'a>

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.