1#[cfg(feature = "std")]
4mod arc_error {
5 use std::error::Error;
6 use std::fmt;
7 use std::sync::Arc;
8
9 #[derive(Debug, Clone)]
12 pub struct ArcError(pub Arc<crate::Error>);
13
14 impl ArcError {
15 pub fn new(error: crate::Error) -> Self {
17 ArcError(Arc::new(error))
18 }
19 }
20
21 impl fmt::Display for ArcError {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 self.0.fmt(f)
24 }
25 }
26
27 impl Error for ArcError {}
28}
29
30#[cfg(feature = "std")]
31pub use arc_error::ArcError;
32
33use crate::{
34 DynFallibleTryDropStrategy, FallibleTryDropStrategy, PureTryDrop, RepeatableTryDrop,
35 TryDropStrategy,
36};
37
38#[allow(unused_imports)] use crate::TryDrop;
40
41use core::marker::PhantomData;
42
43#[cfg_attr(
48 feature = "derives",
49 derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
50)]
51#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
52pub struct InfallibleToFallibleTryDropStrategyAdapter<T: TryDropStrategy, E: Into<anyhow::Error>> {
53 #[cfg_attr(feature = "shrinkwraprs", shrinkwrap(main_field))]
55 pub inner: T,
56
57 _error: PhantomData<E>,
58}
59
60impl<T: TryDropStrategy, E: Into<anyhow::Error>> InfallibleToFallibleTryDropStrategyAdapter<T, E> {
61 pub fn new(value: T) -> Self {
63 Self {
64 inner: value,
65 _error: PhantomData,
66 }
67 }
68
69 #[cfg(feature = "shrinkwraprs")]
71 pub fn take(this: Self) -> T {
72 this.inner
73 }
74}
75
76impl<T: TryDropStrategy, E: Into<anyhow::Error>> FallibleTryDropStrategy
77 for InfallibleToFallibleTryDropStrategyAdapter<T, E>
78{
79 type Error = E;
80
81 fn try_handle_error(&self, error: anyhow::Error) -> Result<(), Self::Error> {
82 self.inner.handle_error(error);
83 Ok(())
84 }
85}
86
87#[cfg_attr(
90 feature = "derives",
91 derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
92)]
93#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
94#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
95pub struct RepeatableTryDropAdapter<T: PureTryDrop> {
96 #[cfg_attr(feature = "shrinkwraprs", shrinkwrap(main_field))]
98 pub inner: T,
99
100 dropped: bool,
101 panic_on_double_drop: bool,
102}
103
104impl<T: PureTryDrop + Default> Default for RepeatableTryDropAdapter<T> {
105 fn default() -> Self {
106 Self::new(T::default())
107 }
108}
109
110impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
111 pub fn new(item: T) -> Self {
113 Self {
114 inner: item,
115 dropped: false,
116 panic_on_double_drop: true,
117 }
118 }
119}
120
121#[cfg(not(feature = "shrinkwraprs"))]
122impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
123 pub fn with_panic_on_double_drop(mut self, panic_on_double_drop: bool) -> Self {
126 self.panic_on_double_drop = panic_on_double_drop;
127 self
128 }
129
130 pub fn dropped(&self) -> bool {
132 self.dropped
133 }
134
135 pub fn panic_on_double_drop(&self) -> bool {
137 self.panic_on_double_drop
138 }
139}
140
141#[cfg(feature = "shrinkwraprs")]
142impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
143 pub fn with_panic_on_double_drop(mut this: Self, panic_on_double_drop: bool) -> Self {
146 this.panic_on_double_drop = panic_on_double_drop;
147 this
148 }
149
150 pub fn dropped(this: &Self) -> bool {
152 this.dropped
153 }
154
155 pub fn panic_on_double_drop(this: &Self) -> bool {
157 this.panic_on_double_drop
158 }
159
160 pub fn take(this: Self) -> T {
162 this.inner
163 }
164}
165
166impl<T: PureTryDrop> PureTryDrop for RepeatableTryDropAdapter<T> {
167 type Error = T::Error;
168 type FallbackTryDropStrategy = T::FallbackTryDropStrategy;
169 type TryDropStrategy = T::TryDropStrategy;
170
171 fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy {
172 self.inner.fallback_try_drop_strategy()
173 }
174
175 fn try_drop_strategy(&self) -> &Self::TryDropStrategy {
176 self.inner.try_drop_strategy()
177 }
178
179 unsafe fn try_drop(&mut self) -> Result<(), Self::Error> {
180 if self.dropped && self.panic_on_double_drop {
181 panic!("tried to drop object twice, this is an invalid operation")
182 } else {
183 self.inner.try_drop()?;
184 self.dropped = true;
185 Ok(())
186 }
187 }
188}
189
190unsafe impl<T: PureTryDrop> RepeatableTryDrop for RepeatableTryDropAdapter<T> {}
192
193#[cfg_attr(
204 feature = "derives",
205 derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
206)]
207#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
208#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
209pub struct DropAdapter<TD: PureTryDrop>(pub TD);
210
211impl<TD: PureTryDrop> Drop for DropAdapter<TD> {
212 fn drop(&mut self) {
213 let result = unsafe { self.0.try_drop() };
215 if let Err(error) = result {
216 let handler = FallbackTryDropStrategyHandler::new(
217 TryDropStrategyRef(self.0.fallback_try_drop_strategy()),
218 FallibleTryDropStrategyRef(self.0.try_drop_strategy()),
219 );
220
221 handler.handle_error(error.into())
222 }
223 }
224}
225
226impl<RTD: RepeatableTryDrop> PureTryDrop for DropAdapter<RTD> {
227 type Error = RTD::Error;
228 type FallbackTryDropStrategy = RTD::FallbackTryDropStrategy;
229 type TryDropStrategy = RTD::TryDropStrategy;
230
231 fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy {
232 self.0.fallback_try_drop_strategy()
233 }
234
235 fn try_drop_strategy(&self) -> &Self::TryDropStrategy {
236 self.0.try_drop_strategy()
237 }
238
239 unsafe fn try_drop(&mut self) -> Result<(), Self::Error> {
240 self.0.try_drop()
241 }
242}
243
244unsafe impl<RTD: RepeatableTryDrop> RepeatableTryDrop for DropAdapter<RTD> {}
247
248impl<TD: PureTryDrop> From<TD> for DropAdapter<TD> {
249 fn from(t: TD) -> Self {
250 t.adapt()
251 }
252}
253
254#[cfg_attr(
257 feature = "derives",
258 derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
259)]
260#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
261pub struct FallibleTryDropStrategyRef<'a, T: FallibleTryDropStrategy>(pub &'a T);
262
263impl<'a, T: FallibleTryDropStrategy> FallibleTryDropStrategy for FallibleTryDropStrategyRef<'a, T> {
264 type Error = T::Error;
265
266 fn try_handle_error(&self, error: anyhow::Error) -> Result<(), Self::Error> {
267 self.0.try_handle_error(error)
268 }
269}
270
271#[cfg_attr(
274 feature = "derives",
275 derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
276)]
277#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
278pub struct TryDropStrategyRef<'a, T: TryDropStrategy>(pub &'a T);
279
280impl<'a, T: TryDropStrategy> TryDropStrategy for TryDropStrategyRef<'a, T> {
281 fn handle_error(&self, error: anyhow::Error) {
282 self.0.handle_error(error)
283 }
284}
285
286#[cfg_attr(
292 feature = "derives",
293 derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
294)]
295pub struct FallbackTryDropStrategyHandler<FDS, FTDS>
296where
297 FDS: TryDropStrategy,
298 FTDS: FallibleTryDropStrategy,
299{
300 pub fallback_try_drop_strategy: FDS,
303
304 pub fallible_try_drop_strategy: FTDS,
306}
307
308impl<FDS, FTDS> FallbackTryDropStrategyHandler<FDS, FTDS>
309where
310 FDS: TryDropStrategy,
311 FTDS: FallibleTryDropStrategy,
312{
313 pub fn new(fallback_try_drop_strategy: FDS, fallible_try_drop_strategy: FTDS) -> Self {
315 Self {
316 fallback_try_drop_strategy,
317 fallible_try_drop_strategy,
318 }
319 }
320}
321
322impl<FDS, FTDS> TryDropStrategy for FallbackTryDropStrategyHandler<FDS, FTDS>
323where
324 FDS: TryDropStrategy,
325 FTDS: FallibleTryDropStrategy,
326{
327 fn handle_error(&self, error: anyhow::Error) {
328 if let Err(error) = self.fallible_try_drop_strategy.dyn_try_handle_error(error) {
329 self.fallback_try_drop_strategy.handle_error(error)
330 }
331 }
332}