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>
impl<'a> AnyMut<'a>
Sourcepub fn erase<T: 'static>(reference: &'a mut T) -> AnyMut<'a>
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>());
Sourcepub unsafe fn from_raw_parts(ptr: *mut (), type_id: TypeId) -> Self
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 correctTypeId
forT
Sourcepub fn unerase<T: 'static>(&self) -> Option<&T>
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());
Sourcepub fn unerase_mut<T: 'static>(&mut self) -> Option<&mut T>
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>();
Sourcepub fn unerase_into<T: 'static>(self) -> Option<&'a mut T>
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);
Sourcepub fn borrow(&self) -> AnyRef<'_>
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));
Sourcepub fn borrow_mut(&mut self) -> AnyMut<'_>
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()
}
}
Sourcepub fn as_mut_ptr(&mut self) -> *mut ()
pub fn as_mut_ptr(&mut self) -> *mut ()
Retrieve an unsafe mutable pointer to the raw data.