Skip to main content

token_cell/
monads.rs

1use core::convert::Infallible;
2
3use crate::{
4    core::{False, TokenGuard, TokenGuardMut, True, UnsafeTokenCellTrait},
5    prelude::*,
6};
7
8/// An operation waiting to be applied onto a cell by providing a proof of immutable access.
9#[must_use = "TokenMaps must be applied to do anything. Note that the closure execution will be deferred to the call-site of `apply/try_apply`"]
10pub struct TokenMap<
11    'a,
12    T: ?Sized,
13    U,
14    F: FnOnce(TokenGuard<'a, T, Token>) -> U,
15    Cell: ?Sized,
16    Token: TokenTrait<ComparisonMaySpuriouslyEq = ComparisonMaySpuriouslyEq> + 'a,
17    ComparisonMaySpuriouslyEq,
18> {
19    pub(crate) cell: &'a Cell,
20    pub(crate) f: F,
21    pub(crate) marker: core::marker::PhantomData<(&'a T, U, Token, ComparisonMaySpuriouslyEq)>,
22}
23impl<
24        'a,
25        T: ?Sized,
26        U,
27        F: FnOnce(TokenGuard<'a, T, Token>) -> U,
28        Token: TokenTrait<ComparisonMaySpuriouslyEq = True>,
29        Cell: UnsafeTokenCellTrait<T, Token>,
30    > TokenMap<'a, T, U, F, Cell, Token, True>
31{
32    /// Attempt to apply the operation.
33    ///
34    /// # Errors
35    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
36    pub fn try_apply(self, token: &'a Token) -> Result<U, (Self, Token::ComparisonError)> {
37        match unsafe { self.cell.try_guard(token) } {
38            Ok(borrowed) => Ok((self.f)(borrowed)),
39            Err(e) => Err((self, e)),
40        }
41    }
42    /// Applies the operation.
43    pub fn apply(self, token: &'a Token) -> U
44    where
45        Token: TokenTrait<ComparisonError = Infallible>,
46    {
47        let borrowed = unsafe { self.cell.try_guard(token).unwrap_unchecked() };
48        (self.f)(borrowed)
49    }
50}
51
52impl<
53        'a,
54        T: ?Sized,
55        U,
56        F: FnOnce(TokenGuard<'a, T, Token>) -> U,
57        Token: TokenTrait<ComparisonMaySpuriouslyEq = False>,
58        Cell: TokenCellTrait<T, Token>,
59    > TokenMap<'a, T, U, F, Cell, Token, False>
60{
61    /// Attempt to apply the operation.
62    ///
63    /// # Errors
64    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
65    pub fn try_apply(self, token: &'a Token) -> Result<U, (Self, Token::ComparisonError)> {
66        match self.cell.try_guard(token) {
67            Ok(borrowed) => Ok((self.f)(borrowed)),
68            Err(e) => Err((self, e)),
69        }
70    }
71    /// Applies the operation.
72    pub fn apply(self, token: &'a Token) -> U
73    where
74        Token: TokenTrait<ComparisonError = Infallible>,
75    {
76        let Ok(borrowed) = self.cell.try_guard(token);
77        (self.f)(borrowed)
78    }
79}
80
81/// An operation waiting to be applied onto a cell by providing a proof of mutable access.
82#[must_use = "TokenMaps must be applied to do anything. Note that the closure execution will be deferred to the call-site of `apply/try_apply`"]
83pub struct TokenMapMut<
84    'a,
85    T: ?Sized,
86    U,
87    F: FnOnce(TokenGuardMut<'a, T, Token>) -> U,
88    Cell: ?Sized,
89    Token: TokenTrait<ComparisonMaySpuriouslyEq = ComparisonMaySpuriouslyEq> + 'a,
90    ComparisonMaySpuriouslyEq,
91> {
92    pub(crate) cell: &'a Cell,
93    pub(crate) f: F,
94    pub(crate) marker: core::marker::PhantomData<(&'a T, U, Token, ComparisonMaySpuriouslyEq)>,
95}
96impl<
97        'a,
98        T: ?Sized,
99        U,
100        F: FnOnce(TokenGuardMut<'a, T, Token>) -> U,
101        Token: TokenTrait<ComparisonMaySpuriouslyEq = False>,
102        Cell: TokenCellTrait<T, Token>,
103    > TokenMapMut<'a, T, U, F, Cell, Token, False>
104{
105    /// Attempt to apply the operation.
106    ///
107    /// # Errors
108    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
109    pub fn try_apply(self, token: &'a mut Token) -> Result<U, Token::ComparisonError> {
110        let borrowed = self.cell.try_guard_mut(token)?;
111        Ok((self.f)(borrowed))
112    }
113    /// Applies the operation.
114    pub fn apply(self, token: &'a mut Token) -> U
115    where
116        Token: TokenTrait<ComparisonError = Infallible>,
117    {
118        let Ok(borrowed) = self.cell.try_guard_mut(token);
119        (self.f)(borrowed)
120    }
121}
122impl<
123        'a,
124        T: ?Sized,
125        U,
126        F: FnOnce(TokenGuardMut<'a, T, Token>) -> U,
127        Token: TokenTrait<ComparisonMaySpuriouslyEq = True>,
128        Cell: UnsafeTokenCellTrait<T, Token>,
129    > TokenMapMut<'a, T, U, F, Cell, Token, True>
130{
131    /// Attempt to apply the operation.
132    ///
133    /// # Errors
134    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
135    pub fn try_apply(self, token: &'a mut Token) -> Result<U, Token::ComparisonError> {
136        let borrowed = unsafe { self.cell.try_guard_mut(token) }?;
137        Ok((self.f)(borrowed))
138    }
139    /// Applies the operation.
140    pub fn apply(self, token: &'a mut Token) -> U
141    where
142        Token: TokenTrait<ComparisonError = Infallible>,
143    {
144        let Ok(borrowed) = unsafe { self.cell.try_guard_mut(token) };
145        (self.f)(borrowed)
146    }
147}