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::{LazyLock, Mutex};
59
60    static STATIC_MUTEX: LazyLock<Mutex<Option<u8>>> = LazyLock::new(Mutex::default);
61
62    assert!(STATIC_MUTEX.with_inner(|o| o + 2).is_none());
63    STATIC_MUTEX.with_borrow_mut(|option| {
64        *option = Some(2);
65    });
66    assert_eq!(
67        STATIC_MUTEX.with_inner_mut(|o| {
68            *o += 2;
69            *o
70        }),
71        Some(4)
72    );
73    assert_eq!(STATIC_MUTEX.with_inner(|o| o + 2), Some(6));
74}
75
76#[test]
77fn test_with_inner_static_rwlock() {
78    use std::sync::{LazyLock, RwLock};
79
80    static STATIC_RWLOCK: LazyLock<RwLock<Option<u8>>> = LazyLock::new(RwLock::default);
81
82    assert!(STATIC_RWLOCK.with_inner(|o| o + 2).is_none());
83    STATIC_RWLOCK.with_borrow_mut(|option| {
84        *option = Some(2);
85    });
86    assert_eq!(
87        STATIC_RWLOCK.with_inner_mut(|o| {
88            *o += 2;
89            *o
90        }),
91        Some(4)
92    );
93    assert_eq!(STATIC_RWLOCK.with_inner(|o| o + 2), Some(6));
94}