multi_trait_object/trait_impl/try_clone.rs
1use crate::{MultitraitObject};
2
3pub trait TryClone: Sized {
4 fn try_clone(&self) -> Option<Self>;
5}
6
7/// Returns a raw pointer to the cloned data.
8/// This will leak the memory of the underlying pointer.
9/// This trait is implemented for all types that implement clone
10/// so you can pass this trait to the object constructor. This
11/// way the given object can be cloned with [TryClone].
12pub unsafe trait RawClone {
13 #[doc(hidden)]
14 #[must_use]
15 unsafe fn raw_clone(&self) -> *mut ();
16}
17
18/// A trait that tries cloning an object and returns an option
19/// with the variant depending on the result. For a multitrait object
20/// to be clonable it needs to have the [RawClone] trait registered.
21unsafe impl<T: Clone> RawClone for T {
22 unsafe fn raw_clone(&self) -> *mut () {
23 Box::into_raw(Box::new(self.clone())) as *mut ()
24 }
25}
26
27impl TryClone for MultitraitObject {
28 fn try_clone(&self) -> Option<Self> {
29 let clone = self.downcast_trait::<dyn RawClone>()?;
30 let data_ptr = unsafe {
31 // SAFETY: We're using the pointer in the multitrait object so
32 // it won't leak memory
33 clone.raw_clone()
34 };
35 Some(MultitraitObject {
36 data: data_ptr,
37 original_typeid: self.original_typeid.clone(),
38 traits: self.traits.clone(),
39 })
40 }
41}