Coverage Report

Created: 2026-09-06 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dyn-clone-1.0.20/src/lib.rs
Line
Count
Source
1
//! [![github]](https://github.com/dtolnay/dyn-clone) [![crates-io]](https://crates.io/crates/dyn-clone) [![docs-rs]](https://docs.rs/dyn-clone)
2
//!
3
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6
//!
7
//! <br>
8
//!
9
//! This crate provides a [`DynClone`] trait that can be used in trait objects,
10
//! and a [`clone_box`] function that can clone any sized or dynamically sized
11
//! implementation of `DynClone`. Types that implement the standard library's
12
//! [`std::clone::Clone`] trait are automatically usable by a `DynClone` trait
13
//! object.
14
//!
15
//! # Example
16
//!
17
//! ```
18
//! use dyn_clone::DynClone;
19
//!
20
//! trait MyTrait: DynClone {
21
//!     fn recite(&self);
22
//! }
23
//!
24
//! impl MyTrait for String {
25
//!     fn recite(&self) {
26
//!         println!("{} ♫", self);
27
//!     }
28
//! }
29
//!
30
//! fn main() {
31
//!     let line = "The slithy structs did gyre and gimble the namespace";
32
//!
33
//!     // Build a trait object holding a String.
34
//!     // This requires String to implement MyTrait and std::clone::Clone.
35
//!     let x: Box<dyn MyTrait> = Box::new(String::from(line));
36
//!
37
//!     x.recite();
38
//!
39
//!     // The type of x2 is a Box<dyn MyTrait> cloned from x.
40
//!     let x2 = dyn_clone::clone_box(&*x);
41
//!
42
//!     x2.recite();
43
//! }
44
//! ```
45
//!
46
//! This crate includes a macro for concisely implementing `impl
47
//! std::clone::Clone for Box<dyn MyTrait>` in terms of `dyn_clone::clone_box`.
48
//!
49
//! ```
50
//! # use dyn_clone::DynClone;
51
//! #
52
//! // As before.
53
//! trait MyTrait: DynClone {
54
//!     /* ... */
55
//! }
56
//!
57
//! dyn_clone::clone_trait_object!(MyTrait);
58
//!
59
//! // Now data structures containing Box<dyn MyTrait> can derive Clone:
60
//! #[derive(Clone)]
61
//! struct Container {
62
//!     trait_object: Box<dyn MyTrait>,
63
//! }
64
//! ```
65
//!
66
//! The `clone_trait_object!` macro expands to just the following, which you can
67
//! handwrite instead if you prefer:
68
//!
69
//! ```
70
//! # use dyn_clone::DynClone;
71
//! #
72
//! # trait MyTrait: DynClone {}
73
//! #
74
//! impl Clone for Box<dyn MyTrait> {
75
//!     fn clone(&self) -> Self {
76
//!         dyn_clone::clone_box(&**self)
77
//!     }
78
//! }
79
//!
80
//! // and similar for Box<dyn MyTrait + Send>, Box<dyn MyTrait + Sync>, Box<dyn MyTrait + Send + Sync>
81
//! ```
82
83
#![doc(html_root_url = "https://docs.rs/dyn-clone/1.0.20")]
84
#![no_std]
85
#![allow(
86
    clippy::missing_panics_doc,
87
    clippy::needless_doctest_main,
88
    clippy::ptr_as_ptr
89
)]
90
91
extern crate alloc;
92
93
#[cfg(doc)]
94
extern crate core as std;
95
96
#[macro_use]
97
mod macros;
98
99
// Not public API.
100
#[doc(hidden)]
101
pub mod __private {
102
    #[doc(hidden)]
103
    pub use core::clone::Clone;
104
    #[doc(hidden)]
105
    pub use core::marker::{Send, Sync};
106
107
    #[doc(hidden)]
108
    pub type Box<T> = alloc::boxed::Box<T>;
109
}
110
111
mod sealed {
112
    pub trait Sealed {}
113
    impl<T: Clone> Sealed for T {}
114
    impl Sealed for str {}
115
    impl<T: Clone> Sealed for [T] {}
116
    pub struct Private;
117
}
118
119
use crate::sealed::{Private, Sealed};
120
use alloc::boxed::Box;
121
use alloc::rc::Rc;
122
#[cfg(target_has_atomic = "ptr")]
123
use alloc::sync::Arc;
124
use core::ptr;
125
126
/// This trait is implemented by any type that implements [`std::clone::Clone`].
127
pub trait DynClone: Sealed {
128
    // Not public API
129
    #[doc(hidden)]
130
    fn __clone_box(&self, _: Private) -> *mut ();
131
}
132
133
/// `&T`&ensp;&mdash;&blacktriangleright;&ensp;`T`
134
0
pub fn clone<T>(t: &T) -> T
135
0
where
136
0
    T: DynClone,
137
{
138
0
    unsafe { *Box::from_raw(<T as DynClone>::__clone_box(t, Private) as *mut T) }
139
0
}
140
141
/// `&T`&ensp;&mdash;&blacktriangleright;&ensp;`Box<T>`
142
0
pub fn clone_box<T>(t: &T) -> Box<T>
143
0
where
144
0
    T: ?Sized + DynClone,
145
{
146
0
    let mut fat_ptr = t as *const T;
147
    unsafe {
148
0
        let data_ptr = ptr::addr_of_mut!(fat_ptr) as *mut *mut ();
149
0
        assert_eq!(*data_ptr as *const (), t as *const T as *const ());
150
0
        *data_ptr = <T as DynClone>::__clone_box(t, Private);
151
    }
152
0
    unsafe { Box::from_raw(fat_ptr as *mut T) }
153
0
}
Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox>
Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Send>
Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync>
Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync + core::marker::Send>
Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone>
Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Send>
Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Sync>
Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Sync + core::marker::Send>
154
155
/// `&mut Arc<T>`&ensp;&mdash;&blacktriangleright;&ensp;`&mut T`
156
#[cfg(target_has_atomic = "ptr")]
157
0
pub fn arc_make_mut<T>(arc: &mut Arc<T>) -> &mut T
158
0
where
159
0
    T: ?Sized + DynClone,
160
{
161
    // Atomic. Find out whether the Arc in the argument is the single holder of
162
    // a reference count (strong or weak) on the target object. If yes, it is
163
    // guaranteed to remain that way throughout the rest of this function
164
    // because no other threads could bump the reference count through any other
165
    // Arc (because no others exist) or through this Arc (because the current
166
    // thread holds an exclusive borrow of it).
167
0
    let is_unique = Arc::get_mut(arc).is_some();
168
0
    if !is_unique {
169
0
        // Non-atomic.
170
0
        let clone = Arc::from(clone_box(&**arc));
171
0
        // Atomic. Check the reference counts again to find out whether the old
172
0
        // object needs to be dropped. Probably not, but it can happen if all
173
0
        // the other holders of a reference count went away during the time that
174
0
        // the clone operation took.
175
0
        *arc = clone;
176
0
    }
177
    // Non-atomic. TODO: replace with Arc::get_mut_unchecked when stable.
178
0
    let ptr = Arc::as_ptr(arc) as *mut T;
179
0
    unsafe { &mut *ptr }
180
0
}
181
182
/// `&mut Rc<T>`&ensp;&mdash;&blacktriangleright;&ensp;`&mut T`
183
0
pub fn rc_make_mut<T>(rc: &mut Rc<T>) -> &mut T
184
0
where
185
0
    T: ?Sized + DynClone,
186
{
187
0
    let is_unique = Rc::get_mut(rc).is_some();
188
0
    if !is_unique {
189
0
        let clone = Rc::from(clone_box(&**rc));
190
0
        *rc = clone;
191
0
    }
192
0
    let ptr = Rc::as_ptr(rc) as *mut T;
193
0
    unsafe { &mut *ptr }
194
0
}
195
196
impl<T> DynClone for T
197
where
198
    T: Clone,
199
{
200
0
    fn __clone_box(&self, _: Private) -> *mut () {
201
0
        Box::<T>::into_raw(Box::new(self.clone())) as *mut ()
202
0
    }
Unexecuted instantiation: <mp4san::parse::trak::TrakBox as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <mp4san::parse::stco::StcoBox as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <mp4san::parse::co64::Co64Box as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <mp4san::parse::minf::MinfBox as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <mp4san::parse::mdia::MdiaBox as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <mp4san::parse::stbl::StblBox as dyn_clone::DynClone>::__clone_box
Unexecuted instantiation: <_ as dyn_clone::DynClone>::__clone_box
203
}
204
205
impl DynClone for str {
206
0
    fn __clone_box(&self, _: Private) -> *mut () {
207
0
        Box::<str>::into_raw(Box::from(self)) as *mut ()
208
0
    }
209
}
210
211
impl<T> DynClone for [T]
212
where
213
    T: Clone,
214
{
215
0
    fn __clone_box(&self, _: Private) -> *mut () {
216
0
        Box::<[T]>::into_raw(self.iter().cloned().collect()) as *mut ()
217
0
    }
218
}