classicube_helpers\traits/
with_inner.rs

1use crate::WithBorrow;
2
3pub trait WithInner<O> {
4    #[must_use]
5    fn with_inner<F, R>(&'static self, f: F) -> Option<R>
6    where
7        F: FnOnce(&O) -> R;
8
9    #[must_use]
10    fn with_inner_mut<F, R>(&'static self, f: F) -> Option<R>
11    where
12        F: FnOnce(&mut O) -> R;
13}
14
15impl<'a, S, O> WithInner<O> for S
16where
17    S: WithBorrow<'a, Option<O>>,
18{
19    fn with_inner<F, R>(&'a self, f: F) -> Option<R>
20    where
21        F: FnOnce(&O) -> R,
22    {
23        self.with_borrow(|o| o.as_ref().map(f))
24    }
25
26    fn with_inner_mut<F, R>(&'a self, f: F) -> Option<R>
27    where
28        F: FnOnce(&mut O) -> R,
29    {
30        self.with_borrow_mut(|o| o.as_mut().map(f))
31    }
32}
33
34#[test]
35fn test_with_inner_thread_local() {
36    use std::cell::RefCell;
37
38    thread_local!(
39        static THREAD_LOCAL: RefCell<Option<u8>> = RefCell::default();
40    );
41
42    assert!(THREAD_LOCAL.with_inner(|o| o + 2).is_none());
43    THREAD_LOCAL.with_borrow_mut(|option| {
44        *option = Some(2);
45    });
46    assert_eq!(
47        THREAD_LOCAL.with_inner_mut(|o| {
48            *o += 2;
49            *o
50        }),
51        Some(4)
52    );
53    assert_eq!(THREAD_LOCAL.with_inner(|o| o + 2), Some(6));
54}
55
56#[test]
57fn test_with_inner_static_mutex() {
58    use std::sync::Mutex;
59
60    use lazy_static::lazy_static;
61
62    lazy_static! {
63        static ref STATIC_MUTEX: Mutex<Option<u8>> = Mutex::default();
64    };
65
66    assert!(STATIC_MUTEX.with_inner(|o| o + 2).is_none());
67    STATIC_MUTEX.with_borrow_mut(|option| {
68        *option = Some(2);
69    });
70    assert_eq!(
71        STATIC_MUTEX.with_inner_mut(|o| {
72            *o += 2;
73            *o
74        }),
75        Some(4)
76    );
77    assert_eq!(STATIC_MUTEX.with_inner(|o| o + 2), Some(6));
78}
79
80#[test]
81fn test_with_inner_static_rwlock() {
82    use std::sync::RwLock;
83
84    use lazy_static::lazy_static;
85
86    lazy_static! {
87        static ref STATIC_RWLOCK: RwLock<Option<u8>> = RwLock::default();
88    };
89
90    assert!(STATIC_RWLOCK.with_inner(|o| o + 2).is_none());
91    STATIC_RWLOCK.with_borrow_mut(|option| {
92        *option = Some(2);
93    });
94    assert_eq!(
95        STATIC_RWLOCK.with_inner_mut(|o| {
96            *o += 2;
97            *o
98        }),
99        Some(4)
100    );
101    assert_eq!(STATIC_RWLOCK.with_inner(|o| o + 2), Some(6));
102}