1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use std::marker::PhantomData;
4 use std::rc::{self, Rc};
5 use std::sync::{self, Arc};
6 
7 /// Trait for generalizing downgrading a strong reference to a weak reference.
8 pub trait Downgrade
9 where
10     Self: Sized,
11 {
12     /// Weak reference type.
13     type Weak;
14 
15     /// Downgrade to a weak reference.
downgrade(&self) -> Self::Weak16     fn downgrade(&self) -> Self::Weak;
17 }
18 
19 /// Trait for generalizing upgrading a weak reference to a strong reference.
20 pub trait Upgrade
21 where
22     Self: Sized,
23 {
24     /// Strong reference type.
25     type Strong;
26 
27     /// Try upgrading a weak reference to a strong reference.
upgrade(&self) -> Option<Self::Strong>28     fn upgrade(&self) -> Option<Self::Strong>;
29 }
30 
31 impl<T: Downgrade + crate::ObjectType> Upgrade for crate::WeakRef<T> {
32     type Strong = T;
33 
upgrade(&self) -> Option<Self::Strong>34     fn upgrade(&self) -> Option<Self::Strong> {
35         self.upgrade()
36     }
37 }
38 
39 impl<T> Downgrade for PhantomData<T> {
40     type Weak = PhantomData<T>;
41 
downgrade(&self) -> Self::Weak42     fn downgrade(&self) -> Self::Weak {
43         PhantomData
44     }
45 }
46 
47 impl<T: Downgrade> Downgrade for &T {
48     type Weak = T::Weak;
49 
downgrade(&self) -> Self::Weak50     fn downgrade(&self) -> Self::Weak {
51         T::downgrade(*self)
52     }
53 }
54 
55 impl<T> Downgrade for Arc<T> {
56     type Weak = sync::Weak<T>;
57 
downgrade(&self) -> Self::Weak58     fn downgrade(&self) -> Self::Weak {
59         Arc::downgrade(self)
60     }
61 }
62 
63 impl<T> Upgrade for PhantomData<T> {
64     type Strong = PhantomData<T>;
65 
upgrade(&self) -> Option<Self::Strong>66     fn upgrade(&self) -> Option<Self::Strong> {
67         Some(PhantomData)
68     }
69 }
70 
71 impl<T> Upgrade for sync::Weak<T> {
72     type Strong = Arc<T>;
73 
upgrade(&self) -> Option<Self::Strong>74     fn upgrade(&self) -> Option<Self::Strong> {
75         self.upgrade()
76     }
77 }
78 
79 impl<T> Downgrade for Rc<T> {
80     type Weak = rc::Weak<T>;
81 
downgrade(&self) -> Self::Weak82     fn downgrade(&self) -> Self::Weak {
83         Rc::downgrade(self)
84     }
85 }
86 
87 impl<T> Upgrade for rc::Weak<T> {
88     type Strong = Rc<T>;
89 
upgrade(&self) -> Option<Self::Strong>90     fn upgrade(&self) -> Option<Self::Strong> {
91         self.upgrade()
92     }
93 }
94