drop_tracker/
itemtraits.rs1use 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 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 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}