1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
//! <code>[OwnRef]\<\'\_, dyn Send… + Sync… + [Any]\>::[downcast][OwnRef::downcast]</code>
use ::core::any::{Any, TypeId};
use crate::OwnRef;
impl<'slot, T : ?Sized> OwnRef<'slot, T> {
/// The moral equivalent of [`Box::downcast`], but for [`OwnRef`]s.
///
/// > More like `.owncast()`, am I right? 🥁
///
/// ## Example
///
/// ```rust
/// #![forbid(unsafe_code)]
///
/// use ::core::any::{Any, TypeId};
/// use ::own_ref::prelude::*;
///
/// fn too_generic<T : 'static>(it: T) {
/// // Say we want to do something special if `T` is a `String`.
///
/// match own_ref!(: T = it).downcast::<String>() {
/// // Ok, `T = String` here, and this property is embodied
/// // by `s: &own String` in this branch:
/// Ok(own_s) => {
/// let s: String = own_s.deref_move();
/// // …
/// },
/// Err(own_t) => {
/// let it: T = own_t.deref_move();
/// },
/// }
/// }
/// ```
pub
fn downcast<U>(
self: OwnRef<'slot, T>,
) -> Result<
OwnRef<'slot, U>,
OwnRef<'slot, T>,
>
where
T : Any,
U : Any,
{
let _checked_eq @ true = (&*self).type_id() == TypeId::of::<U>()
else {
return Err(self);
};
let (ptr, lt) = OwnRef::into_raw(self);
Ok(unsafe {
// Safety: same layout of thin pointers,
// and `TypeId`s have just been checked for equality.
OwnRef::from_raw(ptr as *mut ::core::mem::ManuallyDrop<U>, lt)
})
}
}