token_cell/
monads.rs

1use core::convert::Infallible;
2
3use crate::{
4    core::{TokenGuard, TokenGuardMut},
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: TokenCellTrait<T, Token> + ?Sized,
16    Token: TokenTrait + 'a,
17> {
18    pub(crate) cell: &'a Cell,
19    pub(crate) f: F,
20    pub(crate) marker: core::marker::PhantomData<(&'a T, U, Token)>,
21}
22impl<
23        'a,
24        T: ?Sized,
25        U,
26        F: FnOnce(TokenGuard<'a, T, Token>) -> U,
27        Token: TokenTrait,
28        Cell: TokenCellTrait<T, Token>,
29    > TokenMap<'a, T, U, F, Cell, Token>
30{
31    /// Attempt to apply the operation.
32    ///
33    /// # Errors
34    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
35    pub fn try_apply(self, token: &'a Token) -> Result<U, (Self, Token::ComparisonError)> {
36        match self.cell.try_guard(token) {
37            Ok(borrowed) => Ok((self.f)(borrowed)),
38            Err(e) => Err((self, e)),
39        }
40    }
41    /// Applies the operation.
42    pub fn apply(self, token: &'a Token) -> U
43    where
44        Token: TokenTrait<ComparisonError = Infallible>,
45    {
46        let borrowed = unsafe { self.cell.try_guard(token).unwrap_unchecked() };
47        (self.f)(borrowed)
48    }
49}
50
51/// An operation waiting to be applied onto a cell by providing a proof of mutable access.
52#[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`"]
53pub struct TokenMapMut<
54    'a,
55    T: ?Sized,
56    U,
57    F: FnOnce(TokenGuardMut<'a, T, Token>) -> U,
58    Cell: TokenCellTrait<T, Token> + ?Sized,
59    Token: TokenTrait + 'a,
60> {
61    pub(crate) cell: &'a Cell,
62    pub(crate) f: F,
63    pub(crate) marker: core::marker::PhantomData<(&'a T, U, Token)>,
64}
65impl<
66        'a,
67        T: ?Sized,
68        U,
69        F: FnOnce(TokenGuardMut<'a, T, Token>) -> U,
70        Token: TokenTrait,
71        Cell: TokenCellTrait<T, Token>,
72    > TokenMapMut<'a, T, U, F, Cell, Token>
73{
74    /// Attempt to apply the operation.
75    ///
76    /// # Errors
77    /// If the token comparison failed. Reaching this error is likely to be a fundamental error in your program.
78    pub fn try_apply(self, token: &'a mut Token) -> Result<U, Token::ComparisonError> {
79        let borrowed = self.cell.try_guard_mut(token)?;
80        Ok((self.f)(borrowed))
81    }
82    /// Applies the operation.
83    pub fn apply(self, token: &'a mut Token) -> U
84    where
85        Token: TokenTrait<ComparisonError = Infallible>,
86    {
87        let borrowed = unsafe { self.cell.try_guard_mut(token).unwrap_unchecked() };
88        (self.f)(borrowed)
89    }
90}
91impl<T: ?Sized, Token: TokenTrait> TokenCell<T, Token> {}