drop_tracker/
itemtraits.rs

1use crate::DropItem;
2use crate::DroppedError;
3use crate::State;
4use std::borrow::Borrow;
5use std::borrow::BorrowMut;
6use std::cmp::Ordering;
7use std::fmt;
8use std::hash;
9use std::ops::Deref;
10use std::ops::DerefMut;
11
12impl<V> DropItem<V> {
13    fn inner_ref(&self) -> &V {
14        self.try_inner_ref().expect("cannot borrow value")
15    }
16
17    fn try_inner_ref(&self) -> Result<&V, DroppedError> {
18        match self.state {
19            Some(ref state) if state.is_alive() => {
20                // SAFETY: The item is alive. It is possible that another thread may have dropped
21                // the item since we last checked, but in that case it's the caller's
22                // responsibility to ensure safety.
23                Ok(unsafe { self.value.assume_init_ref() })
24            },
25            _ => Err(DroppedError),
26        }
27    }
28
29    fn inner_mut(&mut self) -> &mut V {
30        self.try_inner_mut().expect("cannot borrow mutable value")
31    }
32
33    fn try_inner_mut(&mut self) -> Result<&mut V, DroppedError> {
34        match self.state {
35            Some(ref state) if state.is_alive() => {
36                // SAFETY: The item is alive. It is possible that another thread may have dropped
37                // the item since we last checked, but in that case it's the caller's
38                // responsibility to ensure safety.
39                Ok(unsafe { self.value.assume_init_mut() })
40            },
41            _ => Err(DroppedError),
42        }
43    }
44}
45
46impl<V> Deref for DropItem<V> {
47    type Target = V;
48
49    fn deref(&self) -> &Self::Target {
50        self.inner_ref()
51    }
52}
53
54impl<V> DerefMut for DropItem<V> {
55    fn deref_mut(&mut self) -> &mut Self::Target {
56        self.inner_mut()
57    }
58}
59
60macro_rules! impl_ref_trait {
61    () => {};
62    ( impl <{ $( $params:tt )* }> Borrow < $target:ty > for DropItem < $type_bound:ty > ; $( $rest:tt )* ) => {
63        impl<$($params)*> Borrow<$target> for DropItem<$type_bound> {
64            #[inline(always)]
65            fn borrow(&self) -> &$target {
66                self.inner_ref().borrow()
67            }
68        }
69
70        impl_ref_trait! { $($rest)* }
71    };
72    ( impl <{ $( $params:tt )* }> BorrowMut < $target:ty > for DropItem < $type_bound:ty > ; $( $rest:tt )* ) => {
73        impl<$($params)*> BorrowMut<$target> for DropItem<$type_bound> {
74            #[inline(always)]
75            fn borrow_mut(&mut self) -> &mut $target {
76                self.inner_mut().borrow_mut()
77            }
78        }
79
80        impl_ref_trait! { $($rest)* }
81    };
82    ( impl <{ $( $params:tt )* }> AsRef < $target:ty > for DropItem < $type_bound:ty > ; $( $rest:tt )* ) => {
83        impl<$($params)*> AsRef<$target> for DropItem<$type_bound> {
84            #[inline(always)]
85            fn as_ref(&self) -> &$target {
86                self.inner_ref().as_ref()
87            }
88        }
89
90        impl_ref_trait! { $($rest)* }
91    };
92    ( impl <{ $( $params:tt )* }> AsMut < $target:ty > for DropItem < $type_bound:ty > ; $( $rest:tt )* ) => {
93        impl<$($params)*> AsMut<$target> for DropItem<$type_bound> {
94            #[inline(always)]
95            fn as_mut(&mut self) -> &mut $target {
96                self.inner_mut().as_mut()
97            }
98        }
99
100        impl_ref_trait! { $($rest)* }
101    };
102}
103
104impl_ref_trait! {
105    impl<{V}>                       Borrow<V>       for DropItem<V>;
106    impl<{V: Borrow<str>}>          Borrow<str>     for DropItem<V>;
107    impl<{V: Borrow<[T]>, T}>       Borrow<[T]>     for DropItem<V>;
108
109    impl<{V}>                       BorrowMut<V>    for DropItem<V>;
110    impl<{V: BorrowMut<str>}>       BorrowMut<str>  for DropItem<V>;
111    impl<{V: BorrowMut<[T]>, T}>    BorrowMut<[T]>  for DropItem<V>;
112
113    impl<{V: AsRef<T>, T}>          AsRef<T>        for DropItem<V>;
114    impl<{V: AsMut<T>, T}>          AsMut<T>        for DropItem<V>;
115}
116
117impl<V: Eq> Eq for DropItem<V> {
118}
119
120impl<V: PartialEq<W>, W> PartialEq<DropItem<W>> for DropItem<V> {
121    fn eq(&self, other: &DropItem<W>) -> bool {
122        self.inner_ref().eq(other.inner_ref())
123    }
124}
125
126impl<V: PartialOrd<W>, W> PartialOrd<DropItem<W>> for DropItem<V> {
127    fn partial_cmp(&self, other: &DropItem<W>) -> Option<Ordering> {
128        self.inner_ref().partial_cmp(other.inner_ref())
129    }
130}
131
132macro_rules! impl_cmp_trait {
133    () => {};
134    (
135        impl < $( $lifetime:lifetime , )? $param:ident $( , $extra_param:ident )? >
136        PartialEq + PartialOrd < $other_type:ty >
137        for DropItem < $item_bound:ty > ; $( $rest:tt )*
138    ) => {
139        impl<$($lifetime,)? $param $(, $extra_param)?> PartialEq<$other_type> for DropItem<$item_bound>
140            where $param: PartialEq<$other_type>
141        {
142            fn eq(&self, other: &$other_type) -> bool {
143                self.inner_ref().eq(other)
144            }
145        }
146
147        impl<$($lifetime,)? $param $(, $extra_param)?> PartialOrd<$other_type> for DropItem<$item_bound>
148            where $param: PartialOrd<$other_type>
149        {
150            fn partial_cmp(&self, other: &$other_type) -> Option<Ordering> {
151                self.inner_ref().partial_cmp(other)
152            }
153        }
154
155        impl_cmp_trait! { $($rest)* }
156    };
157}
158
159impl_cmp_trait! {
160    impl<V>         PartialEq+PartialOrd<i8>        for DropItem<V>;
161    impl<V>         PartialEq+PartialOrd<i16>       for DropItem<V>;
162    impl<V>         PartialEq+PartialOrd<i32>       for DropItem<V>;
163    impl<V>         PartialEq+PartialOrd<i64>       for DropItem<V>;
164    impl<V>         PartialEq+PartialOrd<i128>      for DropItem<V>;
165
166    impl<V>         PartialEq+PartialOrd<u8>        for DropItem<V>;
167    impl<V>         PartialEq+PartialOrd<u16>       for DropItem<V>;
168    impl<V>         PartialEq+PartialOrd<u32>       for DropItem<V>;
169    impl<V>         PartialEq+PartialOrd<u64>       for DropItem<V>;
170    impl<V>         PartialEq+PartialOrd<u128>      for DropItem<V>;
171
172    impl<V>         PartialEq+PartialOrd<f32>       for DropItem<V>;
173    impl<V>         PartialEq+PartialOrd<f64>       for DropItem<V>;
174
175    impl<V>         PartialEq+PartialOrd<char>      for DropItem<V>;
176    impl<V>         PartialEq+PartialOrd<bool>      for DropItem<V>;
177    impl<V>         PartialEq+PartialOrd<()>        for DropItem<V>;
178    impl<V>         PartialEq+PartialOrd<str>       for DropItem<V>;
179    impl<'a, V>     PartialEq+PartialOrd<&'a str>   for DropItem<V>;
180    impl<V, T>      PartialEq+PartialOrd<[T]>       for DropItem<V>;
181    impl<'a, V, T>  PartialEq+PartialOrd<&'a [T]>   for DropItem<V>;
182}
183
184impl<V: hash::Hash> hash::Hash for DropItem<V> {
185    fn hash<H: hash::Hasher>(&self, state: &mut H) {
186        self.inner_ref().hash(state)
187    }
188}
189
190impl<V: fmt::Display> fmt::Display for DropItem<V> {
191    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192        self.inner_ref().fmt(f)
193    }
194}
195
196impl<V: fmt::Debug> fmt::Debug for DropItem<V> {
197    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198        match self.try_inner_ref() {
199            Ok(value) => {
200                f.debug_struct("DropItem")
201                 .field("value", value)
202                 .field("state", &State::Alive)
203                 .finish()
204            },
205            Err(_) => {
206                f.debug_struct("DropItem")
207                 .field("value", &"<dropped>")
208                 .field("state", &State::Dropped)
209                 .finish()
210            }
211        }
212    }
213}