You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

41 lines
1.3 KiB
Rust

use crate::{MultitraitObject};
pub trait TryClone: Sized {
fn try_clone(&self) -> Option<Self>;
}
/// Returns a raw pointer to the cloned data.
/// This will leak the memory of the underlying pointer.
/// This trait is implemented for all types that implement clone
/// so you can pass this trait to the object constructor. This
/// way the given object can be cloned with [TryClone].
pub unsafe trait RawClone {
#[doc(hidden)]
#[must_use]
unsafe fn raw_clone(&self) -> *mut ();
}
/// A trait that tries cloning an object and returns an option
/// with the variant depending on the result. For a multitrait object
/// to be clonable it needs to have the [RawClone] trait registered.
unsafe impl<T: Clone> RawClone for T {
unsafe fn raw_clone(&self) -> *mut () {
Box::into_raw(Box::new(self.clone())) as *mut ()
}
}
impl TryClone for MultitraitObject {
fn try_clone(&self) -> Option<Self> {
let clone = self.downcast_trait::<dyn RawClone>()?;
let data_ptr = unsafe {
// SAFETY: We're using the pointer in the multitrait object so
// it won't leak memory
clone.raw_clone()
};
Some(MultitraitObject {
data: data_ptr,
original_typeid: self.original_typeid.clone(),
traits: self.traits.clone(),
})
}
}