1#![cfg_attr(not(feature = "std"), no_std)]
2#![forbid(clippy::semicolon_if_nothing_returned)]
3#![deny(missing_docs)]
4#![deny(missing_debug_implementations)]
5#![forbid(unsafe_op_in_unsafe_fn)]
6#![forbid(clippy::undocumented_unsafe_blocks)]
7use core::{
45 cell::UnsafeCell,
46 fmt,
47 marker::PhantomData,
48 ops::{Deref, DerefMut},
49};
50
51use crate::{
52 error::{BorrowError, BorrowMutError},
53 token::Token,
54};
55
56pub mod error;
57mod repr_hack;
58pub mod token;
59
60#[cfg(feature = "alloc")]
61pub use token::BoxToken;
62
63macro_rules! repr {
64 ($Tk:ident::$name:ident $($tt:tt)*) => {
65 <<<$Tk as Token>::Id as crate::repr_hack::TokenId>::CellRepr as crate::repr_hack::CellRepr<$Tk::Id>>::$name$($tt)*
66 };
67}
68
69macro_rules! unwrap {
71 ($expr:expr) => {
72 match $expr {
73 Ok(ok) => ok,
74 Err(err) => err.panic(),
75 }
76 };
77}
78
79struct Invariant<T: ?Sized>(PhantomData<fn(T) -> T>);
80impl<T: ?Sized> Invariant<T> {
81 fn new() -> Self {
82 Self(PhantomData)
83 }
84}
85
86#[repr(transparent)]
96pub struct TokenRefCell<
97 T: ?Sized,
98 #[cfg(not(feature = "alloc"))] Tk: Token + ?Sized,
99 #[cfg(feature = "alloc")] Tk: Token + ?Sized = BoxToken,
100> {
101 _invariant: Invariant<Tk>,
102 cell: repr!(Tk::Cell<T>),
103}
104
105impl<T: ?Sized, Tk: Token + ?Sized> AsRef<TokenRefCell<T, Tk>> for &TokenRefCell<T, Tk> {
106 fn as_ref(&self) -> &TokenRefCell<T, Tk> {
107 self
108 }
109}
110
111unsafe impl<T: ?Sized + Sync, Tk: Token + ?Sized> Sync for TokenRefCell<T, Tk> where Tk: Send + Sync {}
114
115impl<T, Tk: Token + ?Sized> TokenRefCell<T, Tk> {
116 #[inline]
118 pub fn new(value: T, token: &Tk) -> Self
119 where
120 repr!(Tk::Cell<T>): Sized,
121 {
122 Self::with_token_id(value, token.id())
123 }
124
125 #[inline]
127 pub fn new_const(value: T) -> Self
128 where
129 Tk: Token<Id = ()>,
130 {
131 Self {
132 _invariant: Invariant::new(),
133 cell: UnsafeCell::new(value),
134 }
135 }
136
137 #[inline]
141 pub fn with_token_id(value: T, token_id: Tk::Id) -> Self
142 where
143 repr!(Tk::Cell<T>): Sized,
144 {
145 Self {
146 _invariant: Invariant::new(),
147 cell: repr!(Tk::new)(value, token_id),
148 }
149 }
150
151 #[inline]
153 pub fn into_inner(self) -> T
154 where
155 repr!(Tk::Cell<T>): Sized,
156 {
157 repr!(Tk::inner(self.cell))
158 }
159}
160
161impl<T: ?Sized, Tk: Token + ?Sized> TokenRefCell<T, Tk> {
162 #[inline]
163 fn get_ref(&self, token_id: Tk::Id) -> Result<Ref<T, Tk>, BorrowError> {
164 if *repr!(Tk::token_id)(&self.cell) == token_id {
165 Ok(Ref {
166 inner: unsafe { &*repr!(Tk::get(&self.cell)) },
170 token_id,
171 _invariant: Invariant::new(),
172 _token_ref: PhantomData,
173 })
174 } else {
175 Err(BorrowError)
176 }
177 }
178
179 #[inline]
194 pub fn borrow<'a>(&'a self, token: &'a Tk) -> Ref<'a, T, Tk> {
195 unwrap!(self.try_borrow(token))
196 }
197
198 #[inline]
211 pub fn try_borrow<'a>(&'a self, token: &'a Tk) -> Result<Ref<'a, T, Tk>, BorrowError> {
212 self.get_ref(token.id())
213 }
214
215 #[inline]
219 unsafe fn get_ref_mut(&self, token_id: Tk::Id) -> Result<RefMut<T, Tk>, BorrowMutError> {
220 if *repr!(Tk::token_id(&self.cell)) == token_id {
221 Ok(RefMut {
222 inner: unsafe { &mut *repr!(Tk::get(&self.cell)) },
226 token_id,
227 _invariant: Invariant::new(),
228 _token_mut: PhantomData,
229 })
230 } else {
231 Err(BorrowMutError::WrongToken)
232 }
233 }
234
235 #[inline]
251 pub fn borrow_mut<'a>(&'a self, token: &'a mut Tk) -> RefMut<'a, T, Tk> {
252 unwrap!(self.try_borrow_mut(token))
253 }
254
255 #[inline]
270 pub fn try_borrow_mut<'a>(
271 &'a self,
272 token: &'a mut Tk,
273 ) -> Result<RefMut<'a, T, Tk>, BorrowMutError> {
274 if !token.is_unique() {
275 return Err(BorrowMutError::NotUniqueToken);
276 }
277 unsafe { self.get_ref_mut(token.id()) }
279 }
280
281 #[inline]
283 pub fn as_ptr(&self) -> *mut T {
284 repr!(Tk::get(&self.cell))
285 }
286
287 #[inline]
289 pub fn get_mut(&mut self) -> &mut T {
290 repr!(Tk::get_mut(&mut self.cell))
291 }
292
293 #[inline]
295 pub fn from_ref(t: &mut T) -> &Self
296 where
297 Tk: Token<Id = ()>,
298 {
299 unsafe { &*(t as *mut T as *const TokenRefCell<T, Tk>) }
302 }
303
304 #[inline]
306 pub fn set_token(&mut self, token: &Tk) {
307 self.set_token_id(token.id());
308 }
309
310 #[inline]
312 pub fn token_id(&self) -> Tk::Id {
313 repr!(Tk::token_id(&self.cell)).clone()
314 }
315
316 #[inline]
318 pub fn set_token_id(&mut self, token_id: Tk::Id) {
319 repr!(Tk::set_token_id(&mut self.cell, token_id));
320 }
321}
322
323impl<T, Tk: Token<Id = ()> + ?Sized> TokenRefCell<[T], Tk> {
324 #[inline]
326 pub fn as_slice_of_cells(&self) -> &[TokenRefCell<T, Tk>]
327 where
328 Tk: Token<Id = ()>,
329 {
330 unsafe { &*(self as *const TokenRefCell<[T], Tk> as *const [TokenRefCell<T, Tk>]) }
332 }
333}
334
335impl<T: ?Sized + fmt::Debug, Tk: Token + ?Sized> fmt::Debug for TokenRefCell<T, Tk>
336where
337 Tk::Id: fmt::Debug,
338{
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 f.debug_struct("TokenRefCell")
341 .field("token", repr!(Tk::token_id(&self.cell)))
342 .finish_non_exhaustive()
343 }
344}
345
346pub struct Ref<
351 'b,
352 T: ?Sized,
353 #[cfg(not(feature = "alloc"))] Tk: Token + ?Sized,
354 #[cfg(feature = "alloc")] Tk: Token + ?Sized = BoxToken,
355> {
356 inner: &'b T,
357 token_id: Tk::Id,
358 _invariant: Invariant<Tk>,
359 _token_ref: PhantomData<&'b Tk>,
360}
361
362impl<'b, T: ?Sized, Tk: Token + ?Sized> Ref<'b, T, Tk> {
363 pub fn into_ref(self) -> &'b T {
365 self.inner
366 }
367
368 #[allow(clippy::should_implement_trait)]
375 #[must_use]
376 #[inline]
377 pub fn clone(this: &Self) -> Self {
378 Self {
379 inner: this.inner,
380 token_id: this.token_id.clone(),
381 _invariant: Invariant::new(),
382 _token_ref: PhantomData,
383 }
384 }
385
386 #[inline]
392 pub fn reborrow<U: ?Sized>(&self, cell: impl FnOnce(&T) -> &TokenRefCell<U, Tk>) -> Ref<U, Tk> {
393 unwrap!(self.try_reborrow(cell))
394 }
395
396 #[inline]
400 pub fn try_reborrow<U: ?Sized>(
401 &self,
402 cell: impl FnOnce(&T) -> &TokenRefCell<U, Tk>,
403 ) -> Result<Ref<U, Tk>, BorrowError> {
404 cell(self.inner).get_ref(self.token_id.clone())
405 }
406
407 #[inline]
413 pub fn reborrow_opt<U: ?Sized>(
414 &self,
415 cell: impl FnOnce(&T) -> Option<&TokenRefCell<U, Tk>>,
416 ) -> Option<Ref<U, Tk>> {
417 Some(unwrap!(self.try_reborrow_opt(cell)?))
418 }
419
420 #[inline]
424 pub fn try_reborrow_opt<U: ?Sized>(
425 &self,
426 cell: impl FnOnce(&T) -> Option<&TokenRefCell<U, Tk>>,
427 ) -> Option<Result<Ref<U, Tk>, BorrowError>> {
428 Some(cell(self.inner)?.get_ref(self.token_id.clone()))
429 }
430
431 #[inline]
435 pub fn reborrow_stateful<'a, S>(
436 &'a self,
437 state: impl FnOnce(&'a T) -> S,
438 ) -> Reborrow<'a, S, Tk> {
439 Reborrow {
440 token_id: self.token_id.clone(),
441 _invariant: Invariant::new(),
442 _phantom: PhantomData,
443 state: state(self.inner),
444 }
445 }
446
447 #[inline]
449 pub fn token_id(&self) -> Tk::Id {
450 self.token_id.clone()
451 }
452}
453
454impl<T: ?Sized, Tk: Token + ?Sized> Deref for Ref<'_, T, Tk> {
455 type Target = T;
456
457 #[inline]
458 fn deref(&self) -> &Self::Target {
459 self.inner
460 }
461}
462
463impl<T: ?Sized + fmt::Debug, Tk: Token + ?Sized> fmt::Debug for Ref<'_, T, Tk>
464where
465 Tk::Id: fmt::Debug,
466{
467 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
468 f.debug_struct("Ref")
469 .field("inner", &self.inner)
470 .field("token_id", &self.token_id)
471 .finish()
472 }
473}
474
475impl<T: ?Sized + fmt::Display, Tk: Token + ?Sized> fmt::Display for Ref<'_, T, Tk> {
476 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
477 write!(f, "{}", &**self)
478 }
479}
480
481pub struct Reborrow<'b, S: ?Sized, Tk: Token + ?Sized> {
483 token_id: Tk::Id,
484 _invariant: Invariant<Tk>,
485 _phantom: PhantomData<&'b Tk>,
486 state: S,
487}
488
489impl<'b, S: ?Sized, Tk: Token + ?Sized> Reborrow<'b, S, Tk> {
490 pub fn reborrow<U: ?Sized>(
496 &mut self,
497 cell: impl FnOnce(&mut S) -> &TokenRefCell<U, Tk>,
498 ) -> Ref<U, Tk> {
499 unwrap!(self.try_reborrow(cell))
500 }
501
502 pub fn try_reborrow<U: ?Sized>(
506 &mut self,
507 cell: impl FnOnce(&mut S) -> &TokenRefCell<U, Tk>,
508 ) -> Result<Ref<U, Tk>, BorrowError> {
509 cell(&mut self.state).get_ref(self.token_id.clone())
510 }
511
512 pub fn reborrow_opt<U: ?Sized>(
518 &mut self,
519 cell: impl FnOnce(&mut S) -> Option<&TokenRefCell<U, Tk>>,
520 ) -> Option<Ref<U, Tk>> {
521 Some(unwrap!(self.try_reborrow_opt(cell)?))
522 }
523
524 pub fn try_reborrow_opt<U: ?Sized>(
528 &mut self,
529 cell: impl FnOnce(&mut S) -> Option<&TokenRefCell<U, Tk>>,
530 ) -> Option<Result<Ref<U, Tk>, BorrowError>> {
531 Some(cell(&mut self.state)?.get_ref(self.token_id.clone()))
532 }
533
534 #[inline]
536 pub fn token_id(&self) -> Tk::Id {
537 self.token_id.clone()
538 }
539}
540
541impl<S: ?Sized, Tk: Token + ?Sized> Deref for Reborrow<'_, S, Tk> {
542 type Target = S;
543
544 #[inline]
545 fn deref(&self) -> &Self::Target {
546 &self.state
547 }
548}
549
550impl<S: ?Sized, Tk: Token + ?Sized> DerefMut for Reborrow<'_, S, Tk> {
551 #[inline]
552 fn deref_mut(&mut self) -> &mut Self::Target {
553 &mut self.state
554 }
555}
556
557impl<S: ?Sized + fmt::Debug, Tk: Token + ?Sized> fmt::Debug for Reborrow<'_, S, Tk>
558where
559 Tk::Id: fmt::Debug,
560{
561 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
562 f.debug_struct("Reborrow")
563 .field("state", &&self.state)
564 .field("token_id", &self.token_id)
565 .finish()
566 }
567}
568
569pub struct RefMut<
573 'b,
574 T: ?Sized,
575 #[cfg(not(feature = "alloc"))] Tk: Token + ?Sized,
576 #[cfg(feature = "alloc")] Tk: Token + ?Sized = BoxToken,
577> {
578 inner: &'b mut T,
579 token_id: Tk::Id,
580 _invariant: Invariant<Tk>,
581 _token_mut: PhantomData<&'b mut Tk>,
582}
583
584impl<'b, T: ?Sized, Tk: Token + ?Sized> RefMut<'b, T, Tk> {
585 pub fn into_mut(self) -> &'b mut T {
587 self.inner
588 }
589
590 pub fn as_ref(&self) -> Ref<T, Tk> {
592 Ref {
593 inner: self.inner,
594 token_id: self.token_id.clone(),
595 _invariant: Invariant::new(),
596 _token_ref: PhantomData,
597 }
598 }
599
600 #[inline]
606 pub fn reborrow_mut<U: ?Sized>(
607 &mut self,
608 cell: impl FnOnce(&mut T) -> &TokenRefCell<U, Tk>,
609 ) -> RefMut<U, Tk> {
610 unwrap!(self.try_reborrow_mut(cell))
611 }
612
613 #[inline]
617 pub fn try_reborrow_mut<U: ?Sized>(
618 &mut self,
619 cell: impl FnOnce(&mut T) -> &TokenRefCell<U, Tk>,
620 ) -> Result<RefMut<U, Tk>, BorrowMutError> {
621 unsafe { cell(self.inner).get_ref_mut(self.token_id.clone()) }
623 }
624
625 #[inline]
631 pub fn reborrow_opt_mut<U: ?Sized>(
632 &mut self,
633 cell: impl FnOnce(&mut T) -> Option<&TokenRefCell<U, Tk>>,
634 ) -> Option<RefMut<U, Tk>> {
635 Some(unwrap!(self.try_reborrow_opt_mut(cell)?))
636 }
637
638 #[inline]
642 pub fn try_reborrow_opt_mut<U: ?Sized>(
643 &mut self,
644 cell: impl FnOnce(&mut T) -> Option<&TokenRefCell<U, Tk>>,
645 ) -> Option<Result<RefMut<U, Tk>, BorrowMutError>> {
646 Some(unsafe { cell(self.inner)?.get_ref_mut(self.token_id.clone()) })
648 }
649
650 #[inline]
654 pub fn reborrow_stateful_mut<'a, S>(
655 &'a mut self,
656 state: impl FnOnce(&'a mut T) -> S,
657 ) -> ReborrowMut<'a, S, Tk> {
658 ReborrowMut {
659 state: state(self.inner),
660 token_id: self.token_id.clone(),
661 _invariant: Invariant::new(),
662 _phantom: PhantomData,
663 }
664 }
665
666 #[inline]
668 pub fn token_id(&self) -> Tk::Id {
669 self.token_id.clone()
670 }
671}
672
673impl<T: ?Sized, Tk: Token + ?Sized> Deref for RefMut<'_, T, Tk> {
674 type Target = T;
675
676 #[inline]
677 fn deref(&self) -> &Self::Target {
678 self.inner
679 }
680}
681
682impl<T: ?Sized, Tk: Token + ?Sized> DerefMut for RefMut<'_, T, Tk> {
683 #[inline]
684 fn deref_mut(&mut self) -> &mut Self::Target {
685 self.inner
686 }
687}
688
689impl<T: ?Sized + fmt::Debug, Tk: Token + ?Sized> fmt::Debug for RefMut<'_, T, Tk>
690where
691 Tk::Id: fmt::Debug,
692{
693 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
694 f.debug_struct("RefMut")
695 .field("inner", &self.inner)
696 .field("token_id", &self.token_id)
697 .finish()
698 }
699}
700
701impl<T: ?Sized + fmt::Display, Tk: Token + ?Sized> fmt::Display for RefMut<'_, T, Tk> {
702 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
703 write!(f, "{}", &**self)
704 }
705}
706
707pub struct ReborrowMut<'b, S: ?Sized, Tk: Token + ?Sized> {
709 token_id: Tk::Id,
710 _invariant: Invariant<Tk>,
711 _phantom: PhantomData<&'b mut Tk>,
712 state: S,
713}
714
715impl<S: ?Sized, Tk: Token + ?Sized> ReborrowMut<'_, S, Tk> {
716 pub fn reborrow_mut<U: ?Sized>(
722 &mut self,
723 cell: impl FnOnce(&mut S) -> &TokenRefCell<U, Tk>,
724 ) -> RefMut<U, Tk> {
725 unwrap!(self.try_reborrow_mut(cell))
726 }
727
728 pub fn try_reborrow_mut<U: ?Sized>(
732 &mut self,
733 cell: impl FnOnce(&mut S) -> &TokenRefCell<U, Tk>,
734 ) -> Result<RefMut<U, Tk>, BorrowMutError> {
735 unsafe { cell(&mut self.state).get_ref_mut(self.token_id.clone()) }
737 }
738
739 pub fn reborrow_opt_mut<U: ?Sized>(
745 &mut self,
746 cell: impl FnOnce(&mut S) -> Option<&TokenRefCell<U, Tk>>,
747 ) -> Option<RefMut<U, Tk>> {
748 Some(unwrap!(self.try_reborrow_opt_mut(cell)?))
749 }
750
751 pub fn try_reborrow_opt_mut<U: ?Sized>(
755 &mut self,
756 cell: impl FnOnce(&mut S) -> Option<&TokenRefCell<U, Tk>>,
757 ) -> Option<Result<RefMut<U, Tk>, BorrowMutError>> {
758 Some(unsafe { cell(&mut self.state)?.get_ref_mut(self.token_id.clone()) })
760 }
761
762 #[inline]
764 pub fn token_id(&self) -> Tk::Id {
765 self.token_id.clone()
766 }
767}
768
769impl<S: ?Sized, Tk: Token + ?Sized> Deref for ReborrowMut<'_, S, Tk> {
770 type Target = S;
771
772 #[inline]
773 fn deref(&self) -> &Self::Target {
774 &self.state
775 }
776}
777
778impl<S: ?Sized, Tk: Token + ?Sized> DerefMut for ReborrowMut<'_, S, Tk> {
779 #[inline]
780 fn deref_mut(&mut self) -> &mut Self::Target {
781 &mut self.state
782 }
783}
784
785impl<S: ?Sized + fmt::Debug, Tk: Token + ?Sized> fmt::Debug for ReborrowMut<'_, S, Tk>
786where
787 Tk::Id: fmt::Debug,
788{
789 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790 f.debug_struct("ReborrowMut")
791 .field("state", &&self.state)
792 .field("token_id", &self.token_id)
793 .finish()
794 }
795}