1#![cfg_attr(not(feature = "std"), no_std)]
2
3use core::fmt;
4
5use downcast_rs::{impl_downcast, Downcast, DowncastSync};
6use dyn_clone::{clone_trait_object, DynClone};
7
8pub trait CloneableAny: Downcast + DynClone {}
12
13impl_downcast!(CloneableAny);
14clone_trait_object!(CloneableAny);
15
16impl fmt::Debug for dyn CloneableAny {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("CloneableAny").finish_non_exhaustive()
19 }
20}
21impl fmt::Debug for dyn CloneableAny + Send {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("CloneableAny").finish_non_exhaustive()
24 }
25}
26impl fmt::Debug for dyn CloneableAny + Send + Sync {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 f.debug_struct("CloneableAny").finish_non_exhaustive()
29 }
30}
31
32impl<T> CloneableAny for T where T: 'static + Clone {}
33
34pub trait CloneableAnySync: DowncastSync + DynClone {}
38
39impl_downcast!(CloneableAnySync);
40clone_trait_object!(CloneableAnySync);
41
42impl fmt::Debug for dyn CloneableAnySync {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.debug_struct("CloneableAnySync").finish_non_exhaustive()
45 }
46}
47
48impl<T> CloneableAnySync for T where T: 'static + Clone + Send + Sync {}
49
50#[cfg(feature = "std")]
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[derive(Debug, Clone)]
56 struct Wrapper(Box<dyn CloneableAny + Send + Sync>);
57 #[derive(Debug, Clone)]
58 struct WrapperSync(Box<dyn CloneableAnySync>);
59
60 #[derive(Clone)]
61 struct Foo;
62
63 #[test]
64 fn test_debug_and_clone() {
65 let wrapper = Wrapper(Box::new(Foo));
66 println!("{:?}", wrapper);
67 #[allow(clippy::redundant_clone)]
68 let _ = wrapper.clone();
69
70 let wrapper = WrapperSync(Box::new(Foo));
71 println!("{:?}", wrapper);
72 #[allow(clippy::redundant_clone)]
73 let _ = wrapper.clone();
74 }
75
76 #[test]
77 fn test_downcast() {
78 assert!((Wrapper(Box::new(Foo)).0 as Box<dyn CloneableAny>)
79 .downcast_ref::<Foo>()
80 .is_some());
81 assert!((Wrapper(Box::new(Foo)).0 as Box<dyn CloneableAny>).is::<Foo>());
82 }
83}