use crate::{MultitraitObject}; pub trait TryClone: Sized { fn try_clone(&self) -> Option; } /// 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 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 { let clone = self.downcast_trait::()?; 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(), }) } }