Crate clone_dyn

Source
Expand description

§Module :: clone_dyn

experimental rust-status docs.rs Open in Gitpod discord

Derive to clone dyn structures.

This crate is a facade that re-exports clone_dyn_types (for core traits and logic) and clone_dyn_meta (for procedural macros). It provides a convenient way to enable cloning for trait objects. By default, Rust does not support cloning for trait objects due to the Clone trait requiring compile-time knowledge of the type’s size. The clone_dyn crate addresses this limitation through its procedural macros, allowing for cloning collections of trait objects. The crate’s purpose is straightforward: it allows for easy cloning of dyn< Trait > with minimal effort and complexity, accomplished by applying the #[clone_dyn] attribute to the trait.

§Alternative

There are few alternatives dyn-clone, dyn-clonable. Unlike other options, this solution is more concise and demands less effort to use, all without compromising the quality of the outcome.

§Basic use-case

This example demonstrates the usage of the #[clone_dyn] attribute macro to enable cloning for trait objects.

#[ cfg( feature = "derive_clone_dyn" ) ]
#[ clone_dyn_meta::clone_dyn ] // Use fully qualified path
pub trait Trait1
{
  fn f1( &self );
}

#[ cfg( not( feature = "derive_clone_dyn" ) ) ]
pub trait Trait1
{
  fn f1( &self );
}

impl Trait1 for i32
{
  fn f1( &self ) {}
}

#[ cfg( feature = "derive_clone_dyn" ) ]
{
  let obj1: Box<dyn Trait1> = Box::new(10i32);
  let cloned_obj1 = obj1.clone(); // This should now work due to #[clone_dyn]
  // Example assertion, assuming f1() can be compared or has side effects
  // For a real test, you'd need a way to compare trait objects or their behavior.
  // For simplicity in doctest, we'll just ensure it compiles and clones.
  // assert_eq!(cloned_obj1.f1(), obj1.f1()); // This would require more complex setup
}
#[ cfg( not( feature = "derive_clone_dyn" ) ) ]
{
  // Provide a fallback or skip the example if macro is not available
}
If you use multithreading or asynchronous paradigms implement trait `Clone` also for `Send` and `Sync`

#[ allow( non_local_definitions ) ]
impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + 'c >
{
  #[ inline ]
  fn clone( &self ) -> Self
  {
    clone_dyn::clone_into_box( &**self )
  }
}

#[ allow( non_local_definitions ) ]
impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + 'c >
{
  #[ inline ]
  fn clone( &self ) -> Self
  {
    clone_dyn::clone_into_box( &**self )
  }
}

#[ allow( non_local_definitions ) ]
impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Sync + 'c >
{
  #[ inline ]
  fn clone( &self ) -> Self
  {
    clone_dyn::clone_into_box( &**self )
  }
}

#[ allow( non_local_definitions ) ]
impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + Sync + 'c >
{
  #[ inline ]
  fn clone( &self ) -> Self
  {
    clone_dyn::clone_into_box( &**self )
  }
}

Try out cargo run --example clone_dyn_trivial.
See code.

§To add to your project

cargo add clone_dyn

§Try out from the repository

git clone https://github.com/Wandalen/wTools
cd wTools
cd examples/clone_dyn_trivial
cargo run

Modules§

dependency
Namespace with dependencies.
exposed
Exposed namespace of the module.
orphan
Orphan namespace of the module.
own
Own namespace of the module.
prelude
Prelude to use essentials: use my_module::prelude::*.

Traits§

CloneDyn
A trait to upcast a clonable entity and clone it. It’s implemented for all entities which can be cloned.

Functions§

clone
True clone which is applicable not only to clonable entities, but to trait objects implementing CloneDyn.
clone_into_box
Clone boxed dyn.

Attribute Macros§

clone_dyn
Derive macro for CloneDyn trait.