async_borrow/
slice.rs

1use std::ptr;
2
3use futures::{stream::FusedStream, FutureExt, Stream};
4
5use crate::{Ref, RefMut, RefForward, RefMutForward};
6
7impl<T, B> RefForward<T, [B]> {
8    pub fn map_by_index(this: Self, index: usize) -> Result<RefForward<T, B>, Self> {
9        if index < this.borrow.len() {
10            Ok(RefForward {
11                ptr: this.ptr,
12                borrow: unsafe { (this.borrow as *mut B).add(index) },
13            })
14        } else {
15            Err(this)
16        }
17    }
18
19    pub fn map_by_range(this: Self, range: std::ops::Range<usize>) -> Result<RefForward<T, [B]>, Self> {
20        if range.end <= this.borrow.len() && range.start < this.borrow.len() {
21            Ok(RefForward {
22                ptr: this.ptr,
23                borrow: unsafe { ptr::slice_from_raw_parts_mut((this.borrow as *mut B).add(range.start), range.len()) }
24            })
25        } else {
26            Err(this)
27        }
28    }
29
30    pub fn map_first(this: Self) -> Result<RefForward<T, B>, Self> {
31        RefForward::map_by_index(this, 0)
32    }
33
34    pub fn map_skip_first(this: Self) -> Result<RefForward<T, [B]>, Self> {
35        let len = this.borrow.len();
36        RefForward::map_by_range(this, 1..len)
37    }
38}
39
40impl<T, B> RefMutForward<T, [B]> {
41    pub fn map_by_index_mut(this: Self, index: usize) -> Result<RefMutForward<T, B>, Self> {
42        if index < this.borrow.len() {
43            Ok(RefMutForward {
44                ptr: this.ptr,
45                borrow: unsafe { (this.borrow as *mut B).add(index) },
46            })
47        } else {
48            Err(this)
49        }
50    }
51
52    pub fn map_by_range_mut(this: Self, range: std::ops::Range<usize>) -> Result<RefMutForward<T, [B]>, Self> {
53        if range.end <= this.borrow.len() && range.start < this.borrow.len() {
54            Ok(RefMutForward {
55                ptr: this.ptr,
56                borrow: unsafe { ptr::slice_from_raw_parts_mut((this.borrow as *mut B).add(range.start), range.len()) }
57            })
58        } else {
59            Err(this)
60        }
61    }
62
63    pub fn map_first_mut(this: Self) -> Result<RefMutForward<T, B>, Self> {
64        RefMutForward::map_by_index_mut(this, 0)
65    }
66
67    pub fn map_skip_first_mut(this: Self) -> Result<RefMutForward<T, [B]>, Self> {
68        let len = this.borrow.len();
69        RefMutForward::map_by_range_mut(this, 1..len)
70    }
71}
72
73impl<T, B> Ref<T, [B]> {
74    pub fn get(this: Self, index: usize) -> Option<Ref<T, B>> {
75        this.context(move |this, ctx| {
76            this.get(index).map(|x| ctx.contextualise_ref(x))
77        })
78    }
79
80    pub fn range(this: Self, range: std::ops::Range<usize>) -> Option<Ref<T, [B]>> {
81        this.context(move |this, ctx| {
82            this.get(range).map(|x| ctx.contextualise_ref(x))
83        })
84    }
85
86    pub fn first(this: Self) -> Option<Ref<T, B>> {
87        Ref::get(this, 0)
88    }
89
90    pub fn skip_first(this: Self) -> Option<Ref<T, [B]>> {
91        let len = this.len();
92        Ref::range(this, 1..len)
93    }
94
95    pub fn split_first(this: Self) -> Option<(Ref<T, B>, Ref<T, [B]>)> {
96        this.context(move |this, ctx| {
97            let (x, xs) = this.split_first()?;
98            Some((ctx.lift_ref(x), ctx.contextualise_ref(xs)))
99        })
100    }
101
102    pub fn split_at(this: Self, mid: usize) -> (Ref<T, [B]>, Ref<T, [B]>) {
103        this.context(move |this, ctx| {
104            let (x, y) = this.split_at(mid);
105            (ctx.lift_ref(x), ctx.contextualise_ref(y))
106        })
107    }
108
109    pub fn split_at_checked(this: Self, mid: usize) -> Result<(Ref<T, [B]>, Ref<T, [B]>), Self> {
110        if mid <= this.len() {
111            this.context(move |this, ctx| unsafe {
112                let (x, y) = this.split_at_unchecked(mid);
113                Ok((ctx.lift_ref(x), ctx.contextualise_ref(y)))
114            })
115        } else {
116            Err(this)
117        }
118    }
119
120    pub fn chunk_by<F: for<'a> FnMut(&'a B, &'a B) -> bool>(this: Self, f: F) -> ChunkBy<T, B, F> {
121        ChunkBy { rf: Some(this), f }
122    }
123
124    pub fn chunks(this: Self, size: usize) -> Chunks<T, B> {
125        Chunks { rf: Some(this), n: size }
126    }
127
128    pub fn split<F: for<'a> FnMut(&'a B) -> bool>(this: Self, f: F) -> Split<T, B, F> {
129        Split { rf: Some(this), f }
130    }
131
132    pub fn split_inclusive<F: for<'a> FnMut(&'a B) -> bool>(this: Self, f: F) -> SplitInclusive<T, B, F> {
133        SplitInclusive { rf: Some(this), f }
134    }
135
136    pub fn windows(this: Self, size: usize) -> Windows<T, B> {
137        Windows { rf: Some(this), n: size }
138    }
139}
140
141impl<T, B> IntoIterator for Ref<T, [B]> {
142    type Item = Ref<T, B>;
143
144    type IntoIter = Iter<T, B>;
145
146    fn into_iter(self) -> Self::IntoIter {
147        Iter { rf: Some(self) }
148    }
149}
150
151#[derive(Clone)]
152pub struct Iter<T, B> {
153    rf: Option<Ref<T, [B]>>
154}
155
156impl<T, B> Iterator for Iter<T, B> {
157    type Item = Ref<T, B>;
158
159    fn next(&mut self) -> Option<Self::Item> {
160        let (x, xs) = Ref::split_first(self.rf.take()?)?;
161        self.rf = Some(xs);
162        Some(x)
163    }
164}
165
166#[derive(Clone)]
167pub struct ChunkBy<T, B, F: for<'a> FnMut(&'a B, &'a B) -> bool> {
168    rf: Option<Ref<T, [B]>>,
169    f: F
170}
171
172impl<T, B, F: for<'a> FnMut(&'a B, &'a B) -> bool> Iterator for ChunkBy<T, B, F> {
173    type Item = Ref<T, [B]>;
174
175    fn next(&mut self) -> Option<Self::Item> {
176        let rf = self.rf.take()?;
177        let mut next_pair_start = 0;
178        while let Some([x, y]) = rf[next_pair_start..].first_chunk::<2>() {
179            next_pair_start += 1;
180            if !(self.f)(x, y) {
181                let (rf_lft, rf_rgh) = Ref::split_at(rf, next_pair_start);
182                self.rf = Some(rf_rgh);
183                return Some(rf_lft)
184            }
185        };
186        Some(rf)
187    }
188}
189
190#[derive(Clone)]
191pub struct Chunks<T, B> {
192    rf: Option<Ref<T, [B]>>,
193    n: usize,
194}
195
196impl<T, B> Iterator for Chunks<T, B> {
197    type Item = Ref<T, [B]>;
198
199    fn next(&mut self) -> Option<Self::Item> {
200        let rf = self.rf.take()?;
201        if self.n >= rf.len() {
202            return Some(rf)
203        }
204        let (rf_lft, rf_rgh) = Ref::split_at(rf, self.n);
205        self.rf = Some(rf_rgh);
206        Some(rf_lft)
207    }
208}
209
210#[derive(Clone)]
211pub struct SplitInclusive<T, B, F: for<'a> FnMut(&'a B) -> bool> {
212    rf: Option<Ref<T, [B]>>,
213    f: F,
214}
215
216impl<T, B, F: for<'a> FnMut(&'a B) -> bool> Iterator for SplitInclusive<T, B, F> {
217    type Item = Ref<T, [B]>;
218
219    fn next(&mut self) -> Option<Self::Item> {
220        let rf = self.rf.take()?;
221        let mut n = 0;
222        while let Some(x) = rf.get(n) {
223            n += 1;
224            if (self.f)(x) {
225                let (rf_lft, rf_rgh) = Ref::split_at(rf, n);
226                self.rf = Some(rf_rgh);
227                return Some(rf_lft)
228            }
229        }
230        return Some(rf)
231    }
232}
233
234#[derive(Clone)]
235pub struct Split<T, B, F: for<'a> FnMut(&'a B) -> bool> {
236    rf: Option<Ref<T, [B]>>,
237    f: F
238}
239
240impl<T, B, F: for<'a> FnMut(&'a B) -> bool> Iterator for Split<T, B, F> {
241    type Item = Ref<T, [B]>;
242
243    fn next(&mut self) -> Option<Self::Item> {
244        let rf = self.rf.take()?;
245        let mut n = 0;
246        while let Some(x) = rf.get(n) {
247            if (self.f)(x) {
248                let (rf_lft, rf_rgh) = Ref::split_at(rf, n);
249                self.rf = Ref::skip_first(rf_rgh);
250                return Some(rf_lft)
251            }
252            n += 1;
253        }
254        return Some(rf)
255    }
256}
257
258#[derive(Clone)]
259pub struct Windows<T, B> {
260    rf: Option<Ref<T, [B]>>,
261    n: usize,
262}
263
264impl<T, B> Iterator for Windows<T, B> {
265    type Item = Ref<T, [B]>;
266
267    fn next(&mut self) -> Option<Self::Item> {
268        let rf = self.rf.take()?;
269        let xs = Ref::range(rf.clone(), 0..self.n)?;
270        self.rf = Ref::skip_first(rf);
271        Some(xs)
272    }
273}
274
275impl<T, B> RefMut<T, [B]> {
276    pub fn get_mut(this: Self, index: usize) -> Option<RefMut<T, B>> {
277        this.context(move |this, ctx| {
278            this.get_mut(index).map(|x| ctx.contextualise_mut(x))
279        })
280    }
281
282    pub fn range_mut(this: Self, range: std::ops::Range<usize>) -> Option<RefMut<T, [B]>> {
283        this.context(move |this, ctx| {
284            this.get_mut(range).map(|x| ctx.contextualise_mut(x))
285        })
286    }
287
288    pub fn first_mut(this: Self) -> Option<RefMut<T, B>> {
289        RefMut::get_mut(this, 0)
290    }
291
292    pub fn skip_first_mut(this: Self) -> Option<RefMut<T, [B]>> {
293        let len = this.len();
294        RefMut::range_mut(this, 1..len)
295    }
296
297    pub fn split_first_mut(this: Self) -> Option<(RefMut<T, B>, RefMut<T, [B]>)> {
298        this.context(move |this, ctx| {
299            let (x, xs) = this.split_first_mut()?;
300            Some((ctx.lift_mut(x), ctx.contextualise_mut(xs)))
301        })
302    }
303
304    pub fn split_at_mut(this: Self, mid: usize) -> (RefMut<T, [B]>, RefMut<T, [B]>) {
305        this.context(move |this, ctx| {
306            let (x, y) = this.split_at_mut(mid);
307            (ctx.lift_mut(x), ctx.contextualise_mut(y))
308        })
309    }
310
311    pub fn split_at_mut_checked(this: Self, mid: usize) -> Result<(RefMut<T, [B]>, RefMut<T, [B]>), Self> {
312        if mid <= this.len() {
313            this.context(move |this, ctx| unsafe {
314                let (x, y) = this.split_at_mut_unchecked(mid);
315                Ok((ctx.lift_mut(x), ctx.contextualise_mut(y)))
316            })
317        } else {
318            Err(this)
319        }
320    }
321
322    pub fn chunk_by_mut<F: for<'a> FnMut(&'a mut B, &'a mut B) -> bool>(this: Self, f: F) -> ChunkByMut<T, B, F> {
323        ChunkByMut { rf_mut: Some(this), f }
324    }
325
326    pub fn chunks_mut(this: Self, size: usize) -> ChunksMut<T, B> {
327        ChunksMut { rf_mut: Some(this), n: size }
328    }
329
330    pub fn split_mut<F: for<'a> FnMut(&'a mut B) -> bool>(this: Self, f: F) -> SplitMut<T, B, F> {
331        SplitMut { rf_mut: Some(this), f }
332    }
333
334    pub fn split_inclusive_mut<F: for<'a> FnMut(&'a mut B) -> bool>(this: Self, f: F) -> SplitInclusiveMut<T, B, F> {
335        SplitInclusiveMut { rf_mut: Some(this), f }
336    }
337
338    pub fn windows_mut(this: Self, size: usize) -> WindowsMut<T, B> {
339        WindowsMut { fut: Some(this.into_mut_forward()), size }
340    }
341
342    pub fn window_clusters_mut(this: Self, size: usize) -> WindowClustersMut<T, B> {
343        WindowClustersMut { fut: Some(this.into_mut_forward()), size, n: 0 }
344    }
345}
346
347pub struct ChunkByMut<T, B, F: for<'a> FnMut(&'a mut B, &'a mut B) -> bool> {
348    rf_mut: Option<RefMut<T, [B]>>,
349    f: F
350}
351
352impl<T, B, F: for<'a> FnMut(&'a mut B, &'a mut B) -> bool> Iterator for ChunkByMut<T, B, F> {
353    type Item = RefMut<T, [B]>;
354
355    fn next(&mut self) -> Option<Self::Item> {
356        let mut rf_mut = self.rf_mut.take()?;
357        let mut next_pair_start = 0;
358        while let Some([x, y]) = rf_mut[next_pair_start..].first_chunk_mut::<2>() {
359            next_pair_start += 1;
360            if !(self.f)(x, y) {
361                let (rf_mut_lft, rf_mut_rgh) = RefMut::split_at_mut(rf_mut, next_pair_start);
362                self.rf_mut = Some(rf_mut_rgh);
363                return Some(rf_mut_lft)
364            }
365        };
366        Some(rf_mut)
367    }
368}
369
370impl<T, B> IntoIterator for RefMut<T, [B]> {
371    type Item = RefMut<T, B>;
372
373    type IntoIter = IterMut<T, B>;
374
375    fn into_iter(self) -> Self::IntoIter {
376        IterMut { rf: Some(self) }
377    }
378}
379
380pub struct IterMut<T, B> {
381    rf: Option<RefMut<T, [B]>>
382}
383
384impl<T, B> Iterator for IterMut<T, B> {
385    type Item = RefMut<T, B>;
386
387    fn next(&mut self) -> Option<Self::Item> {
388        let (x, xs) = RefMut::split_first_mut(self.rf.take()?)?;
389        self.rf = Some(xs);
390        Some(x)
391    }
392}
393
394pub struct ChunksMut<T, B> {
395    rf_mut: Option<RefMut<T, [B]>>,
396    n: usize,
397}
398
399impl<T, B> Iterator for ChunksMut<T, B> {
400    type Item = RefMut<T, [B]>;
401
402    fn next(&mut self) -> Option<Self::Item> {
403        let rf_mut = self.rf_mut.take()?;
404        if self.n >= rf_mut.len() {
405            return Some(rf_mut)
406        }
407        let (rf_mut_lft, rf_mut_rgh) = RefMut::split_at_mut(rf_mut, self.n);
408        self.rf_mut = Some(rf_mut_rgh);
409        Some(rf_mut_lft)
410    }
411}
412
413pub struct SplitInclusiveMut<T, B, F: for<'a> FnMut(&'a mut B) -> bool> {
414    rf_mut: Option<RefMut<T, [B]>>,
415    f: F,
416}
417
418impl<T, B, F: for<'a> FnMut(&'a mut B) -> bool> Iterator for SplitInclusiveMut<T, B, F> {
419    type Item = RefMut<T, [B]>;
420
421    fn next(&mut self) -> Option<Self::Item> {
422        let mut rf_mut = self.rf_mut.take()?;
423        let mut n = 0;
424        while let Some(x) = rf_mut.get_mut(n) {
425            n += 1;
426            if (self.f)(x) {
427                let (rf_mut_lft, rf_mut_rgh) = RefMut::split_at_mut(rf_mut, n);
428                self.rf_mut = Some(rf_mut_rgh);
429                return Some(rf_mut_lft)
430            }
431        }
432        return Some(rf_mut)   
433    }
434}
435
436pub struct SplitMut<T, B, F: for<'a> FnMut(&'a mut B) -> bool> {
437    rf_mut: Option<RefMut<T, [B]>>,
438    f: F
439}
440
441impl<T, B, F: for<'a> FnMut(&'a mut B) -> bool> Iterator for SplitMut<T, B, F> {
442    type Item = RefMut<T, [B]>;
443
444    fn next(&mut self) -> Option<Self::Item> {
445        let mut rf_mut = self.rf_mut.take()?;
446        let mut n = 0;
447        while let Some(x) = rf_mut.get_mut(n) {
448            if (self.f)(x) {
449                let (rf_mut_lft, rf_mut_rgh) = RefMut::split_at_mut(rf_mut, n);
450                self.rf_mut = RefMut::skip_first_mut(rf_mut_rgh);
451                return Some(rf_mut_lft)
452            }
453            n += 1;
454        }
455        return Some(rf_mut)
456    }
457}
458
459pub struct WindowsMut<T, B> {
460    fut: Option<RefMutForward<T, [B]>>,
461    size: usize,
462}
463
464impl<T, B> Stream for WindowsMut<T, B> {
465    type Item = RefMut<T, [B]>;
466
467    fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
468        use std::task::Poll;
469        let Some(mut fut) = self.fut.take() else { return Poll::Ready(None) };
470        match fut.poll_unpin(cx) {
471            Poll::Ready(rf_mut) => {
472                let (fut, rf_mut) = rf_mut.forward_mut();
473                let Some(xs) = RefMut::range_mut(rf_mut, 0..self.size) else {
474                    return Poll::Ready(None)
475                };
476                self.fut = RefMutForward::map_skip_first_mut(fut).ok();
477                Poll::Ready(Some(xs))
478            },
479            Poll::Pending => {
480                self.fut = Some(fut);
481                Poll::Pending
482            },
483        }
484    }
485}
486
487impl<T, B> FusedStream for WindowsMut<T, B> {
488    fn is_terminated(&self) -> bool {
489        self.fut.is_none()
490    }
491}
492
493pub struct WindowClustersMut<T, B> {
494    fut: Option<RefMutForward<T, [B]>>,
495    size: usize,
496    n: usize
497}
498
499impl<T, B> Stream for WindowClustersMut<T, B> {
500    type Item = ChunksMut<T, B>;
501
502    fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
503        use std::task::Poll;
504        let Some(mut fut) = self.fut.take() else { return Poll::Ready(None) };
505        if self.n == self.size {
506            return Poll::Ready(None)
507        }
508        match fut.poll_unpin(cx) {
509            Poll::Ready(rf_mut) => {
510                self.n += 1;
511                let (fut, rf_mut) = rf_mut.forward_mut();
512                self.fut = RefMutForward::map_skip_first_mut(fut).ok();
513                Poll::Ready(Some(RefMut::chunks_mut(rf_mut, self.size)))
514            },
515            Poll::Pending => {
516                self.fut = Some(fut);
517                Poll::Pending
518            },
519        }
520    }
521}
522
523impl<T, B> FusedStream for WindowClustersMut<T, B> {
524    fn is_terminated(&self) -> bool {
525        self.fut.is_none()
526    }
527}
528
529#[cfg(test)]
530mod test {
531    use futures::StreamExt;
532
533    use crate::{RefMut, ShareBox};
534
535    #[tokio::test]
536    async fn test_split() {
537        ShareBox::<Vec<u8>>::new(vec![0, 1, 2, 3])
538            .spawn_mut(|xs| tokio::spawn(async move {
539                let xs: RefMut<Vec<u8>, [u8]> = xs.into_deref_mut();
540                let (lft, rgh) = RefMut::split_at_mut(xs, 2);
541                drop(lft);
542                drop(rgh);
543            }))
544            .await;
545    }
546
547    #[tokio::test]
548    async fn test_windows_mut() {
549        ShareBox::<Vec<u8>>::new(vec![0, 1, 2, 3])
550            .spawn_mut(|xs| tokio::spawn(async move {
551                let xs: RefMut<Vec<u8>, [u8]> = xs.into_deref_mut();
552                let mut stream = RefMut::windows_mut(xs, 2);
553                let mut ys = Vec::new();
554                while let Some(xs) = stream.next().await {
555                    ys.push(xs.iter().sum::<u8>())
556                }
557                assert_eq!(&*ys, &[1, 3, 5])
558            }))
559            .await;
560    }
561
562    #[tokio::test]
563    async fn test_window_clusters_mut() {
564        ShareBox::<Vec<u8>>::new(vec![0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0])
565            .spawn_mut(|xs| tokio::spawn(async move {
566                let xs = xs.into_deref_mut();
567                let mut stream = RefMut::window_clusters_mut(xs, 4).enumerate();
568                while let Some((i, cluster)) = stream.next().await {
569                    cluster.for_each(|xs| {
570                        assert_eq!(xs.get(0), Some(&(i as u8)));
571                    });
572                }
573            }))
574            .await;
575    }
576}