1use core::convert::Infallible;
2
3use crate::{
4 core::{False, TokenGuard, TokenGuardMut, True, UnsafeTokenCellTrait},
5 prelude::*,
6};
7
8#[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 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 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 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 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#[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 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 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 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 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}