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}