try_drop/drop_strategies/adhoc/fn_mut/
mod.rs1mod thread_unsafe;
2
3use crate::{FallibleTryDropStrategy, TryDropStrategy};
4use anyhow::Error;
5use parking_lot::Mutex;
6use std::marker::PhantomData;
7pub use thread_unsafe::*;
8
9#[cfg_attr(feature = "derives", derive(Debug, Default))]
16pub struct AdHocMutDropStrategy<F: FnMut(crate::Error)>(pub Mutex<F>);
17
18impl<F: FnMut(crate::Error)> AdHocMutDropStrategy<F> {
19 pub fn new(f: F) -> Self {
21 Self(Mutex::new(f))
22 }
23}
24
25impl<F: FnMut(crate::Error)> TryDropStrategy for AdHocMutDropStrategy<F> {
26 fn handle_error(&self, error: crate::Error) {
27 self.0.lock()(error)
28 }
29}
30
31impl<F: FnMut(crate::Error)> From<F> for AdHocMutDropStrategy<F> {
32 fn from(f: F) -> Self {
33 Self::new(f)
34 }
35}
36
37pub trait IntoAdHocMutDropStrategy: FnMut(crate::Error) + Sized {
39 fn into_drop_strategy(self) -> AdHocMutDropStrategy<Self> {
41 AdHocMutDropStrategy::new(self)
42 }
43}
44
45impl<T: FnMut(crate::Error)> IntoAdHocMutDropStrategy for T {}
46
47#[cfg_attr(feature = "derives", derive(Debug, Default))]
54pub struct AdHocMutFallibleDropStrategy<F, E>
55where
56 F: FnMut(crate::Error) -> Result<(), E>,
57 E: Into<anyhow::Error>,
58{
59 pub f: Mutex<F>,
61 _error: PhantomData<E>,
62}
63
64impl<F, E> AdHocMutFallibleDropStrategy<F, E>
65where
66 F: FnMut(crate::Error) -> Result<(), E>,
67 E: Into<anyhow::Error>,
68{
69 pub fn new(f: F) -> Self {
71 Self {
72 f: Mutex::new(f),
73 _error: PhantomData,
74 }
75 }
76}
77
78impl<F, E> FallibleTryDropStrategy for AdHocMutFallibleDropStrategy<F, E>
79where
80 F: FnMut(crate::Error) -> Result<(), E>,
81 E: Into<anyhow::Error>,
82{
83 type Error = E;
84
85 fn try_handle_error(&self, error: Error) -> Result<(), Self::Error> {
86 self.f.lock()(error)
87 }
88}
89
90impl<F, E> From<F> for AdHocMutFallibleDropStrategy<F, E>
91where
92 F: FnMut(crate::Error) -> Result<(), E>,
93 E: Into<anyhow::Error>,
94{
95 fn from(f: F) -> Self {
96 Self::new(f)
97 }
98}
99
100pub trait IntoAdHocMutFallibleDropStrategy<E: Into<anyhow::Error>>:
102 FnMut(crate::Error) -> Result<(), E> + Sized
103{
104 fn into_drop_strategy(self) -> AdHocMutFallibleDropStrategy<Self, E> {
106 AdHocMutFallibleDropStrategy::new(self)
107 }
108}
109
110impl<T, E> IntoAdHocMutFallibleDropStrategy<E> for T
111where
112 T: FnMut(crate::Error) -> Result<(), E>,
113 E: Into<anyhow::Error>,
114{}
115
116#[cfg(test)]
117mod tests {
118 use std::sync::Arc;
119 use std::sync::atomic::AtomicBool;
120 use crate::drop_strategies::PanicDropStrategy;
121 use crate::{LOAD_ORDERING, STORE_ORDERING};
122 use crate::test_utils::fallible;
123 use super::*;
124
125 static LOCK: Mutex<()> = parking_lot::const_mutex(());
127
128 #[test]
129 fn test_adhoc_mut_drop_strategy() {
130 let _lock = LOCK.lock();
131 let works = Arc::new(AtomicBool::new(false));
132 let w = Arc::clone(&works);
133 let strategy = AdHocMutDropStrategy::new(move |_| w.store(true, STORE_ORDERING));
134 crate::install_global_handlers(strategy, PanicDropStrategy::DEFAULT);
135 drop(fallible());
136 assert!(works.load(LOAD_ORDERING));
137 }
138
139 #[test]
140 fn test_into_adhoc_mut_drop_strategy() {
141 let _lock = LOCK.lock();
142 let works = Arc::new(AtomicBool::new(false));
143 let w = Arc::clone(&works);
144 let strategy = move |_| w.store(true, STORE_ORDERING);
145 let strategy = IntoAdHocMutDropStrategy::into_drop_strategy(strategy);
146 crate::install_global_handlers(strategy, PanicDropStrategy::DEFAULT);
147 drop(fallible());
148 assert!(works.load(LOAD_ORDERING));
149 }
150
151 #[test]
152 fn test_adhoc_mut_fallible_drop_strategy() {
153 let _lock = LOCK.lock();
154 let works = Arc::new(AtomicBool::new(false));
155 let w = Arc::clone(&works);
156 let strategy = AdHocMutFallibleDropStrategy::<_, crate::Error>::new(move |_| {
157 w.store(true, STORE_ORDERING);
158 Ok(())
159 });
160 crate::install_global_handlers(strategy, PanicDropStrategy::DEFAULT);
161 drop(fallible());
162 assert!(works.load(LOAD_ORDERING));
163 }
164
165 #[test]
166 fn test_into_adhoc_mut_fallible_drop_strategy() {
167 let _lock = LOCK.lock();
168 let works = Arc::new(AtomicBool::new(false));
169 let w = Arc::clone(&works);
170 let strategy = move |_| {
171 w.store(true, STORE_ORDERING);
172 Ok::<_, crate::Error>(())
173 };
174 let strategy = IntoAdHocMutFallibleDropStrategy::into_drop_strategy(strategy);
175 crate::install_global_handlers(strategy, PanicDropStrategy::DEFAULT);
176 drop(fallible());
177 assert!(works.load(LOAD_ORDERING));
178 }
179}