try_drop/drop_strategies/adhoc/
mod.rs

1#[cfg(feature = "ds-adhoc-mut")]
2mod fn_mut;
3
4#[cfg(feature = "ds-adhoc-mut")]
5pub use fn_mut::*;
6
7use crate::{FallibleTryDropStrategy, TryDropStrategy};
8
9/// A quick and dirty drop strategy which uses a function.
10#[cfg_attr(
11    feature = "derives",
12    derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
13)]
14#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
15#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
16pub struct AdHocDropStrategy<F: Fn(crate::Error)>(pub F);
17
18impl<F: Fn(crate::Error)> AdHocDropStrategy<F> {
19    /// Take the inner function.
20    #[cfg(feature = "shrinkwraprs")]
21    pub fn take(this: Self) -> F {
22        this.0
23    }
24}
25
26impl<F: Fn(crate::Error)> TryDropStrategy for AdHocDropStrategy<F> {
27    fn handle_error(&self, error: crate::Error) {
28        self.0(error)
29    }
30}
31
32impl<F: Fn(crate::Error)> From<F> for AdHocDropStrategy<F> {
33    fn from(f: F) -> Self {
34        AdHocDropStrategy(f)
35    }
36}
37
38/// Signifies that this type can be converted into an [`AdHocDropStrategy`].
39pub trait IntoAdHocDropStrategy: Fn(crate::Error) + Sized {
40    /// Convert this type into an [`AdHocDropStrategy`].
41    fn into_drop_strategy(self) -> AdHocDropStrategy<Self> {
42        AdHocDropStrategy(self)
43    }
44}
45
46impl<T: Fn(crate::Error)> IntoAdHocDropStrategy for T {}
47
48/// A quick and dirty fallible drop strategy which uses a function.
49#[cfg_attr(
50    feature = "derives",
51    derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
52)]
53#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
54#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
55pub struct AdHocFallibleDropStrategy<F, E>(pub F)
56where
57    F: Fn(crate::Error) -> Result<(), E>,
58    E: Into<anyhow::Error>;
59
60impl<F, E> AdHocFallibleDropStrategy<F, E>
61where
62    F: Fn(crate::Error) -> Result<(), E>,
63    E: Into<anyhow::Error>,
64{
65    /// Take the inner function.
66    #[cfg(feature = "shrinkwraprs")]
67    pub fn take(this: Self) -> F {
68        this.0
69    }
70}
71
72impl<F, E> FallibleTryDropStrategy for AdHocFallibleDropStrategy<F, E>
73where
74    F: Fn(crate::Error) -> Result<(), E>,
75    E: Into<anyhow::Error>,
76{
77    type Error = E;
78
79    fn try_handle_error(&self, error: crate::Error) -> Result<(), Self::Error> {
80        (self.0)(error)
81    }
82}
83
84impl<F, E> From<F> for AdHocFallibleDropStrategy<F, E>
85where
86    F: Fn(crate::Error) -> Result<(), E>,
87    E: Into<anyhow::Error>,
88{
89    fn from(f: F) -> Self {
90        Self(f)
91    }
92}
93
94/// Signifies that this type can be converted into an [`AdHocFallibleDropStrategy`].
95pub trait IntoAdHocFallibleDropStrategy<E: Into<anyhow::Error>>:
96    Fn(crate::Error) -> Result<(), E> + Sized
97{
98    /// Convert this type into an [`AdHocFallibleDropStrategy`].
99    fn into_drop_strategy(self) -> AdHocFallibleDropStrategy<Self, E> {
100        AdHocFallibleDropStrategy(self)
101    }
102}
103
104impl<T, E> IntoAdHocFallibleDropStrategy<E> for T
105where
106    T: Fn(crate::Error) -> Result<(), E>,
107    E: Into<anyhow::Error>,
108{}
109
110#[cfg(test)]
111mod tests {
112    use std::cell::Cell;
113    use std::rc::Rc;
114    use crate::drop_strategies::PanicDropStrategy;
115    use crate::test_utils::fallible;
116    use super::*;
117
118    #[test]
119    fn test_adhoc_drop_strategy() {
120        let works = Rc::new(Cell::new(false));
121        let w = Rc::clone(&works);
122        let strategy = AdHocDropStrategy(move |_| w.set(true));
123        crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
124        drop(fallible());
125        assert!(works.get(), "the strategy should have worked");
126    }
127
128    #[test]
129    fn test_into_adhoc_drop_strategy() {
130        let works = Rc::new(Cell::new(false));
131        let w = Rc::clone(&works);
132        let strategy = move |_| w.set(true);
133        let strategy = IntoAdHocDropStrategy::into_drop_strategy(strategy);
134        crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
135        drop(fallible());
136        assert!(works.get(), "the strategy should have worked");
137    }
138
139    #[test]
140    fn test_adhoc_fallible_drop_strategy() {
141        let works = Rc::new(Cell::new(false));
142        let w = Rc::clone(&works);
143        let strategy = AdHocFallibleDropStrategy::<_, crate::Error>(move |_| {
144            w.set(true);
145            Ok(())
146        });
147        crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
148        drop(fallible());
149        assert!(works.get(), "the strategy should have worked");
150    }
151
152    #[test]
153    fn test_into_adhoc_fallible_drop_strategy() {
154        let works = Rc::new(Cell::new(false));
155        let w = Rc::clone(&works);
156        let strategy = move |_| {
157            w.set(true);
158            Ok::<_, crate::Error>(())
159        };
160        let strategy = IntoAdHocFallibleDropStrategy::into_drop_strategy(strategy);
161        crate::install_thread_local_handlers(strategy, PanicDropStrategy::DEFAULT);
162        drop(fallible());
163        assert!(works.get(), "the strategy should have worked");
164    }
165}