try_drop/drop_strategies/adhoc/fn_mut/
thread_unsafe.rs1use crate::{FallibleTryDropStrategy, TryDropStrategy};
2use anyhow::Error;
3use std::cell::RefCell;
4
5#[cfg_attr(
8 feature = "derives",
9 derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)
10)]
11pub struct ThreadUnsafeAdHocMutDropStrategy<F: FnMut(crate::Error)>(pub RefCell<F>);
12
13impl<F: FnMut(crate::Error)> ThreadUnsafeAdHocMutDropStrategy<F> {
14 pub fn new(f: F) -> Self {
16 Self(RefCell::new(f))
17 }
18}
19
20impl<F: FnMut(crate::Error)> TryDropStrategy for ThreadUnsafeAdHocMutDropStrategy<F> {
21 fn handle_error(&self, error: crate::Error) {
22 self.0.borrow_mut()(error)
23 }
24}
25
26pub trait IntoThreadUnsafeAdHocMutDropStrategy: FnMut(crate::Error) + Sized {
28 fn into_drop_strategy(self) -> ThreadUnsafeAdHocMutDropStrategy<Self> {
30 ThreadUnsafeAdHocMutDropStrategy::new(self)
31 }
32}
33
34impl<F: FnMut(crate::Error)> IntoThreadUnsafeAdHocMutDropStrategy for F {}
35
36#[cfg_attr(
39 feature = "derives",
40 derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)
41)]
42pub struct ThreadUnsafeAdHocMutFallibleDropStrategy<F, E>(pub RefCell<F>)
43where
44 F: FnMut(crate::Error) -> Result<(), E>,
45 E: Into<crate::Error>;
46
47impl<F, E> ThreadUnsafeAdHocMutFallibleDropStrategy<F, E>
48where
49 F: FnMut(crate::Error) -> Result<(), E>,
50 E: Into<crate::Error>,
51{
52 pub fn new(f: F) -> Self {
54 Self(RefCell::new(f))
55 }
56}
57
58impl<F, E> FallibleTryDropStrategy for ThreadUnsafeAdHocMutFallibleDropStrategy<F, E>
59where
60 F: FnMut(crate::Error) -> Result<(), E>,
61 E: Into<crate::Error>,
62{
63 type Error = E;
64
65 fn try_handle_error(&self, error: Error) -> Result<(), Self::Error> {
66 self.0.borrow_mut()(error)
67 }
68}
69
70pub trait IntoThreadUnsafeAdHocMutFallibleDropStrategy<E: Into<anyhow::Error>>:
72 FnMut(crate::Error) -> Result<(), E> + Sized
73{
74 fn into_drop_strategy(self) -> ThreadUnsafeAdHocMutFallibleDropStrategy<Self, E> {
76 ThreadUnsafeAdHocMutFallibleDropStrategy::new(self)
77 }
78}
79
80impl<T, E> IntoThreadUnsafeAdHocMutFallibleDropStrategy<E> for T
81where
82 T: FnMut(crate::Error) -> Result<(), E>,
83 E: Into<crate::Error>,
84{}
85
86#[cfg(test)]
87mod tests {
88 use std::cell::Cell;
89 use std::rc::Rc;
90 use crate::drop_strategies::PanicDropStrategy;
91 use crate::test_utils::fallible;
92 use super::*;
93
94 #[test]
95 fn test_thread_unsafe_adhoc_mut_drop_strategy() {
96 let works = Rc::new(Cell::new(false));
97 let w = Rc::clone(&works);
98 let strategy = ThreadUnsafeAdHocMutDropStrategy::new(move |_| w.set(true));
99 crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
100 drop(fallible());
101 assert!(works.get());
102 }
103
104 #[test]
105 fn test_into_thread_unsafe_adhoc_mut_drop_strategy() {
106 let works = Rc::new(Cell::new(false));
107 let w = Rc::clone(&works);
108 let strategy = move |_| w.set(true);
109 let strategy = IntoThreadUnsafeAdHocMutDropStrategy::into_drop_strategy(strategy);
110 crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
111 drop(fallible());
112 assert!(works.get());
113 }
114
115 #[test]
116 fn test_thread_unsafe_adhoc_mut_fallible_drop_strategy() {
117 let works = Rc::new(Cell::new(false));
118 let w = Rc::clone(&works);
119 let strategy = ThreadUnsafeAdHocMutFallibleDropStrategy::<_, crate::Error>::new(move |_| {
120 w.set(true);
121 Ok(())
122 });
123 crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
124 drop(fallible());
125 assert!(works.get());
126 }
127
128 #[test]
129 fn test_into_thread_unsafe_adhoc_mut_fallible_drop_strategy() {
130 let works = Rc::new(Cell::new(false));
131 let w = Rc::clone(&works);
132 let strategy = move |_| {
133 w.set(true);
134 Ok::<_, crate::Error>(())
135 };
136 let strategy = IntoThreadUnsafeAdHocMutFallibleDropStrategy::into_drop_strategy(strategy);
137 crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
138 drop(fallible());
139 assert!(works.get());
140 }
141}