1
2use std::{borrow::Borrow, ops::Deref};
3
4pub trait Shareable<'a> {
6 #[doc(hidden)]
8 type Shared: Copy + Borrow<Self> + 'a;
9
10 #[doc(hidden)]
12 fn share(&'a self) -> Self::Shared;
13}
14
15pub struct Share<'a, T: ?Sized + Shareable<'a>> {
18 shared: T::Shared,
19}
20
21impl<'a, T> Share<'a, T>
22where
23 T: ?Sized + Shareable<'a>,
24{
25 pub fn new(reference: &'a T) -> Self {
27 Share {
28 shared: reference.share(),
29 }
30 }
31}
32
33impl<'a, T> Deref for Share<'a, T>
34where
35 T: ?Sized + Shareable<'a>,
36{
37 type Target = T;
38
39 fn deref(&self) -> &T {
40 self.shared.borrow()
41 }
42}
43
44impl<'a, T> Shareable<'a> for &'a T
46where
47 T: 'a,
48{
49 type Shared = &'a T;
50 fn share(&'a self) -> &'a T {
51 *self
52 }
53}
54
55#[macro_export]
56macro_rules! shareable {
57 ($t:ty) => {
58 impl<'a> Shareable<'a> for $t {
59 type Shared = &'a $t;
60 fn share(&'a self) -> &'a $t {
61 self
62 }
63 }
64 };
65 ($t:ty: Copy) => {
66 impl<'a> Shareable<'a> for $t {
67 type Shared = $t;
68 fn share(&self) -> $t {
69 *self
70 }
71 }
72 };
73}
74
75
76
77#[test]
78fn copy() {
79 #[derive(Copy, Clone)]
80 struct Foo;
81 shareable!(Foo: Copy);
82
83 let _: Foo = Share::new(&Foo).shared;
85}
86
87
88#[test]
89fn reference() {
90 #[derive(Clone)]
91 struct Foo;
92 shareable!(Foo);
93
94 let _: &Foo = Share::new(&Foo).shared;
96}