clonable_trait_object 0.1.1

clonar objectos traits sin usar unsafe
Documentation

//!
//!clonar objectos traits sin usar unsafe
//!
//! ```
//!
//! use clonable_trait_object::clonable_trait_object;
//! 
//! /*El primer parametro es el trait objetivo
//! el segundo parametro es el nombre que le daras al trait 
//! que hara de Clone*/ 
//!clonable_trait_object!(Animal,AnimalClone);

//!trait Animal: AnimalClone {
//!  fn speak(&self);

//!}
//!#[derive(Clone,Debug)]
//!struct Dog {
//!  name: String,
//!}
//!impl Dog {
//!  fn new(name: &str) -> Dog {
//!      Dog {
//!          name: name.to_string(),
//!      }
//!  }
//!}

//!impl Animal for Dog {
//!  fn speak(&self) {
//!      println!("{}: ruff, ruff!", self.name);
//!  }
  
//!}
//!#[derive(Clone)]
//!struct AnimalHouse {
//!  animal: Box<dyn Animal>,
//!}

//! fn main() {
//!  let house = AnimalHouse {
//!      animal: Box::new(Dog::new("Bobby")),
//!  };
//!  let house2 = house.clone();
//!  house2.animal.speak();
   
//!}
//! ```
//! 
//! 
#[macro_export]
macro_rules! clonable_trait_object {
   
    ($target_traint:ident,$trait_name:ident) => {
    
        pub trait $trait_name :Send + std::fmt::Debug +Sync{
            fn clone_box(&self) -> Box<dyn $target_traint>;
        }
    
        impl<T> $trait_name for T
        where
            T: 'static + $target_traint + Clone,
        {
            fn clone_box(&self) -> Box<dyn $target_traint> {
                Box::new(self.clone())
            }
        }
        
        impl Clone for Box<dyn $target_traint> {
            fn clone(&self) -> Box<dyn $target_traint> {
                self.clone_box()
            }
        }
    };
}