arena_voxel_tree/
utils.rs

1//! Functions that make it easy to unwrap a value safely. These functions are
2//! provided to improve the ergonomics of using wrapped values in Rust. Examples
3//! of wrapped values are `<Arc<RwLock<T>>`, and `<Option>`.
4
5use std::{
6    fmt::Debug,
7    sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
8};
9
10pub type ReadGuarded<'a, T> = RwLockReadGuard<'a, T>;
11pub type WriteGuarded<'a, T> = RwLockWriteGuard<'a, T>;
12
13/// Macros to unwrap various locks.
14#[macro_export]
15macro_rules! unwrap {
16    (mutex from $arc_mutex: expr) => {
17        $arc_mutex.lock().unwrap()
18    };
19
20    (r_lock from $arc_rw_lock: expr) => {
21        $arc_rw_lock.read().unwrap()
22    };
23
24    (w_lock from $arc_rw_lock: expr) => {
25        $arc_rw_lock.write().unwrap()
26    };
27}
28
29// Functions to unwrap various locks.
30
31pub fn unwrap_arc_read_lock_and_call<T, F, R>(
32    arc_lock_wrapped_value: &Arc<RwLock<T>>,
33    receiver_fn: &mut F,
34) -> R
35where
36    F: FnMut(&T) -> R,
37{
38    let arc_clone = arc_lock_wrapped_value.clone();
39    let read_guarded: ReadGuarded<'_, T> = unwrap!(r_lock from arc_clone);
40    receiver_fn(&read_guarded)
41}
42
43pub fn unwrap_arc_write_lock_and_call<T, F, R>(
44    arc_lock_wrapped_value: &Arc<RwLock<T>>,
45    receiver_fn: &mut F,
46) -> R
47where
48    F: FnMut(&mut T) -> R,
49{
50    let arc_clone = arc_lock_wrapped_value.clone();
51    let mut write_guarded: WriteGuarded<'_, T> = unwrap!(w_lock from arc_clone);
52    receiver_fn(&mut write_guarded)
53}
54
55// Helper lambdas.
56
57pub fn with_mut<T, F, R>(arg: &mut T, receiver_fn: &mut F) -> R
58where
59    F: FnMut(&mut T) -> R,
60{
61    receiver_fn(arg)
62}
63
64pub fn with<T, F, R>(arg: T, receiver_fn: F) -> R
65where
66    F: Fn(T) -> R,
67{
68    receiver_fn(arg)
69}
70
71pub fn call_if_some<T, F>(option_wrapped_value: &Option<T>, receiver_fn: &F)
72where
73    F: Fn(&T),
74{
75    if let Some(value) = option_wrapped_value {
76        receiver_fn(value);
77    }
78}
79
80pub fn call_if_none<T, F>(option_wrapped_value: &Option<T>, receiver_fn: &F)
81where
82    F: Fn(),
83{
84    if (option_wrapped_value).is_none() {
85        receiver_fn();
86    }
87}
88
89pub fn call_if_ok<T, F, E>(option_wrapped_value: &Result<T, E>, receiver_fn: &F)
90where
91    F: Fn(&T),
92{
93    if let Ok(value) = option_wrapped_value {
94        receiver_fn(value);
95    }
96}
97
98pub fn call_if_err<T, F, E>(option_wrapped_value: &Result<T, E>, receiver_fn: &F)
99where
100    F: Fn(&E),
101    T: Debug,
102{
103    if option_wrapped_value.is_err() {
104        receiver_fn(option_wrapped_value.as_ref().unwrap_err());
105    }
106}