cloneable_any/
lib.rs

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
8//
9//
10//
11pub 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
34//
35//
36//
37pub 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}