@@ -3,13 +3,33 @@ use std::{
33 ptr:: NonNull ,
44} ;
55
6+ /// The stack of mutable references and their holders.
7+ ///
8+ /// It allows to simulate recursion where each level holds a mutable reference to the one held by
9+ /// the caller with an iteration.
10+ ///
11+ /// It is made in such a way that the rules enforced by the borrow checker during the theoretical
12+ /// recursion are still enforced during iterations. On that purpose, each object holding a mutable
13+ /// reference becomes unreachable when the recursion is similated: it is stacked until it becomes
14+ /// usable again.
15+ ///
16+ /// In order to use it:
17+ ///
18+ /// * create a new stack with the root mutable reference using [`RefMutStack::new`]
19+ /// * call [`RefMutStack::borrow_mut`] to create the root holder of type `T`
20+ /// * enable recursion in `T` itself by calling [`ParkableRefMut::parker`] and park the holder with
21+ /// [`Parker::park`]
22+ /// * finish recursion by calling [`ParkableRefMut::unpark`]
23+ ///
24+ /// See builder examples in `tests` for more details.
625pub struct RefMutStack < ' a , R , T > {
726 root_ref : NonNull < R > ,
827 stack : SafeDropVec < ( T , NonNull < R > ) > ,
928 _a : std:: marker:: PhantomData < & ' a ( ) > ,
1029}
1130
1231impl < ' a , R , T > RefMutStack < ' a , R , T > {
32+ /// Creates a new stack with the root mutable reference.
1333 pub fn new ( r : & ' a mut R ) -> Self {
1434 Self {
1535 root_ref : NonNull :: from_mut ( r) ,
@@ -18,6 +38,7 @@ impl<'a, R, T> RefMutStack<'a, R, T> {
1838 }
1939 }
2040
41+ /// Borrows the current mutable reference at the top of the stack in order to use it.
2142 pub fn borrow_mut ( & ' a mut self ) -> ParkableRefMut < ' a , R , T > {
2243 let r = self . stack . last_mut ( ) . map_or ( self . root_ref , |( _, r) | * r) ;
2344 ParkableRefMut {
@@ -67,19 +88,28 @@ impl<T> DerefMut for SafeDropVec<T> {
6788 }
6889}
6990
91+ /// Holder of one mutable reference.
92+ ///
93+ /// It can park itself and its holder of type `T` via [`ParkableRefMut::parker`] and [`Parker::park`].
94+ ///
95+ /// It can unpark itself via [`ParkableRefMut::unpark`] which returns the previously parked holder of type `T` if
96+ /// any, `None` if everything has been unparked.
7097pub struct ParkableRefMut < ' a , R , T > {
7198 r : NonNull < R > ,
7299 stack : NonNull < RefMutStack < ' a , R , T > > ,
73100}
74101
75102impl < ' a , R , T > ParkableRefMut < ' a , R , T > {
103+ /// Creates a new parker to park the mutable reference holder and derive a new one.
76104 pub fn parker ( & mut self ) -> Parker < ' a , R , T > {
77105 Parker {
78106 r : self . r ,
79107 stack : self . stack ,
80108 }
81109 }
82110
111+ /// Unparks the reference and returns the previously parked holder of type `T` if any, `None`
112+ /// if everything has been unparked.
83113 pub fn unpark ( mut self ) -> Option < T > {
84114 let stack = unsafe { self . stack . as_mut ( ) } ;
85115 stack. stack . pop ( ) . map ( |( v, _) | v)
@@ -99,13 +129,20 @@ impl<'a, R, T> DerefMut for ParkableRefMut<'a, R, T> {
99129 }
100130}
101131
132+ /// The parker helper.
133+ ///
134+ /// It must be used by calling [`Parker::park`], passing the reference holder of type `T` which
135+ /// becomes unreachable until it is unparked.
102136#[ must_use]
103137pub struct Parker < ' a , R , T > {
104138 r : NonNull < R > ,
105139 stack : NonNull < RefMutStack < ' a , R , T > > ,
106140}
107141
108142impl < ' a , R , T > Parker < ' a , R , T > {
143+ /// Parks the reference holder which becomes unreachable until it is unparked.
144+ ///
145+ /// The callback is used to derive a new mutable reference from the current one in the stack.
109146 pub fn park < F > ( mut self , holder : T , f : F ) -> ParkableRefMut < ' a , R , T >
110147 where
111148 R : ' a ,
0 commit comments