1use ::core::{
2 cell::UnsafeCell,
3 ops::{Deref, DerefMut},
4};
5
6trait MapLikely<T> {
7 type Output<U>;
8 fn map_likely<U, F: FnOnce(T) -> U>(self, f: F) -> Self::Output<U>;
9}
10#[cold]
11const fn cold() {}
12impl<T, E> MapLikely<T> for Result<T, E> {
13 type Output<U> = Result<U, E>;
14 fn map_likely<U, F: FnOnce(T) -> U>(self, f: F) -> Self::Output<U> {
15 match self {
16 Ok(v) => Ok(f(v)),
17 Err(e) => {
18 cold();
19 Err(e)
20 }
21 }
22 }
23}
24
25use crate::monads::{TokenMap, TokenMapMut};
26pub trait TokenTrait: Sized {
28 type ConstructionError;
30 type RunError;
34 type Identifier;
38 type ComparisonError;
40 type Branded<'a>;
42 fn new() -> Result<Self, Self::ConstructionError>;
47 fn with_token<R, F: for<'a> FnOnce(Self::Branded<'a>) -> R>(f: F) -> Result<R, Self::RunError>;
54 fn identifier(&self) -> Self::Identifier;
56 fn compare(&self, id: &Self::Identifier) -> Result<(), Self::ComparisonError>;
61}
62
63pub trait TokenCellTrait<T: ?Sized, Token: TokenTrait>: Sync {
67 fn new(inner: T, token: &Token) -> Self
69 where
70 T: Sized;
71 fn try_guard<'l>(
77 &'l self,
78 token: &'l Token,
79 ) -> Result<TokenGuard<'l, T, Token>, Token::ComparisonError>;
80 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError>;
85 fn try_guard_mut<'l>(
91 &'l self,
92 token: &'l mut Token,
93 ) -> Result<TokenGuardMut<'l, T, Token>, Token::ComparisonError>;
94 fn try_borrow_mut<'l>(
99 &'l self,
100 token: &'l mut Token,
101 ) -> Result<&'l mut T, Token::ComparisonError>;
102 fn borrow<'l>(&'l self, token: &'l Token) -> &'l T
104 where
105 Token::ComparisonError: core::fmt::Debug,
106 {
107 self.try_borrow(token).unwrap()
108 }
109 fn borrow_mut<'l>(&'l self, token: &'l mut Token) -> &'l mut T
111 where
112 Token::ComparisonError: core::fmt::Debug,
113 {
114 self.try_borrow_mut(token).unwrap()
115 }
116 fn map<'a, U, F: FnOnce(TokenGuard<'a, T, Token>) -> U>(
118 &'a self,
119 f: F,
120 ) -> TokenMap<'a, T, U, F, Self, Token> {
121 TokenMap {
122 cell: self,
123 f,
124 marker: core::marker::PhantomData,
125 }
126 }
127 fn map_mut<'a, U, F: FnOnce(TokenGuardMut<'a, T, Token>) -> U>(
129 &'a self,
130 f: F,
131 ) -> TokenMapMut<'a, T, U, F, Self, Token> {
132 TokenMapMut {
133 cell: self,
134 f,
135 marker: core::marker::PhantomData,
136 }
137 }
138}
139
140pub struct TokenGuard<'a, T: ?Sized, Token: TokenTrait> {
142 cell: &'a TokenCell<T, Token>,
143 token: &'a Token,
144}
145impl<'a, T: ?Sized, Token: TokenTrait> TokenGuard<'a, T, Token> {
146 pub const fn token(&self) -> &Token {
148 self.token
149 }
150}
151impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuard<'a, T, Token> {
152 type Target = T;
153 fn deref(&self) -> &Self::Target {
154 unsafe { &*self.cell.inner.get() }
155 }
156}
157
158pub struct TokenGuardMut<'a, T: ?Sized, Token: TokenTrait> {
160 cell: &'a TokenCell<T, Token>,
161 token: &'a mut Token,
162}
163impl<'a, T: ?Sized, Token: TokenTrait> TokenGuardMut<'a, T, Token> {
164 pub fn token(&self) -> &Token {
166 self.token
167 }
168 pub fn token_mut(&mut self) -> &mut Token {
170 self.token
171 }
172}
173impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuardMut<'a, T, Token> {
174 type Target = T;
175 fn deref(&self) -> &Self::Target {
176 unsafe { &*self.cell.inner.get() }
177 }
178}
179impl<'a, T, Token: TokenTrait> core::ops::DerefMut for TokenGuardMut<'a, T, Token> {
180 fn deref_mut(&mut self) -> &mut Self::Target {
181 unsafe { &mut *self.cell.inner.get() }
182 }
183}
184
185pub struct TokenCell<T: ?Sized, Token: TokenTrait> {
187 token_id: Token::Identifier,
188 inner: UnsafeCell<T>,
189}
190impl<T: ?Sized, Token: TokenTrait> TokenCell<T, Token> {
191 pub fn get_mut(&mut self) -> &mut T {
194 self.inner.get_mut()
195 }
196}
197impl<T: Sized, Token: TokenTrait> TokenCell<T, Token> {
198 pub fn into_inner(self) -> T {
202 self.inner.into_inner()
203 }
204}
205impl<T: ?Sized, Token: TokenTrait> Deref for TokenCell<T, Token> {
206 type Target = UnsafeCell<T>;
207 fn deref(&self) -> &Self::Target {
208 &self.inner
209 }
210}
211impl<T: ?Sized, Token: TokenTrait> DerefMut for TokenCell<T, Token> {
212 fn deref_mut(&mut self) -> &mut Self::Target {
213 &mut self.inner
214 }
215}
216
217unsafe impl<T: ?Sized, Token: TokenTrait> Sync for TokenCell<T, Token> {}
218
219impl<T: ?Sized, Token: TokenTrait> TokenCellTrait<T, Token> for TokenCell<T, Token> {
220 fn new(inner: T, token: &Token) -> Self
221 where
222 T: Sized,
223 {
224 TokenCell {
225 inner: UnsafeCell::new(inner),
226 token_id: token.identifier(),
227 }
228 }
229 fn try_guard<'l>(
230 &'l self,
231 token: &'l Token,
232 ) -> Result<TokenGuard<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
233 token
234 .compare(&self.token_id)
235 .map_likely(move |_| TokenGuard { cell: self, token })
236 }
237 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError> {
238 token
239 .compare(&self.token_id)
240 .map_likely(move |_| unsafe { &*self.inner.get() })
241 }
242 fn try_guard_mut<'l>(
243 &'l self,
244 token: &'l mut Token,
245 ) -> Result<TokenGuardMut<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
246 token
247 .compare(&self.token_id)
248 .map_likely(move |_| TokenGuardMut { cell: self, token })
249 }
250
251 fn try_borrow_mut<'l>(
252 &'l self,
253 token: &'l mut Token,
254 ) -> Result<&'l mut T, Token::ComparisonError> {
255 token
256 .compare(&self.token_id)
257 .map_likely(move |_| unsafe { &mut *self.inner.get() })
258 }
259}