slice_rc/
lib.rs

1#![warn(missing_docs)]
2
3//! `slice-rc` provides a variant of the `std`'s [`Rc`](std::rc::Rc) type, and more generally the contents of the module [`std::rc`].
4//! 
5//! If you are not familiar with those, you should read their documentation before trying to use this crate.
6//! 
7//! * [`Src<T>`] (which, as the crate name suggests, stands for 'Slice Reference Counted') is a variant of [`std::rc::Rc<T>`]
8//! * [`WeakSrc<T>`] is a variant of [`std::rc::Weak<T>`]
9//! * [`UniqueSrc<T>`] is a variant of the currently-unstable [`std::rc::UniqueRc<T>`]
10//! * [`UninitSrc<T>`] is a variant of the as-yet-only-hypothetical `std::rc::UninitRc<T>`
11//! 
12//! ### How do this crate's types differ from the [`std::rc`] ones?
13//! 
14//! Notably, <code>[Rc](std::rc::Rc)\<[\[T\]](prim@slice)></code> is already a valid, usable type; why do we need a special slice [`Rc`](std::rc::Rc) when [`Rc`](std::rc::Rc) already supports slices?
15//! 
16//! The answer can be found in one method (well, two: one on [`Src`](Src::slice), and its analog on [`WeakSrc`](WeakSrc::slice)):
17//! [`Src::slice`] allows us to acquire a sub-slice of the contents of the [`Src`] which still uses the reference-counting mechanism rather than using lifetime-style references;
18//! e.g.:
19//! 
20//! ```rust
21//! use slice_rc::Src;
22//! 
23//! let whole: Src<str> = Src::new("Hello World!");
24//! let world: Src<str> = whole.slice(6..=10);
25//! assert_eq!(&*world, "World");
26//! ```
27//! 
28//! This is useful because:
29//! * <code>[Src]\<T>: \'static where T: \'static</code>, and therefore this is useful where lifetimes are difficult or impossible to accomodate.
30//! * Via [`WeakSrc`] and constructor functions like [`Src::cyclic_from_fn`], it allows constructing collections of self-referential objects,
31//!   and unlike e.g. <code>[Vec]\<[Rc](std::rc::Rc)\<T>></code>, in a <code>[Src]\<[\[T\]](prim@slice)></code>, the actual `T`'s are contiguous, which makes it possible to obtain a [`&[T]`](prim@slice).
32//! 
33//! ### Root
34//! 
35//! Many methods in this crate refer to a "root" pointer (e.g., root `Src`).
36//! This refers to any `Src`-family pointer that refers to the whole allocation;
37//! its [`len`](Src::len) is the number of elements in the whole allocation,
38//! and every non-root pointer to the allocation references either an element or a subslice of if.
39//! 
40//! Note that it is not just the "original" `Src` that can be root:
41//! 
42//! ```rust
43//! # use slice_rc::Src;
44//! let root = Src::from_array([1, 2, 3]);
45//! 
46//! assert!(Src::is_root(&root));
47//! 
48//! let slice = root.slice(1..);
49//! 
50//! assert!(!Src::is_root(&slice));
51//! 
52//! let also_root = Src::root(&slice);
53//! 
54//! assert!(Src::is_root(&also_root));
55//! ```
56
57mod inner;
58mod strong;
59mod uninit;
60mod unique;
61mod weak;
62
63use std::{ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}, slice, usize};
64
65use inner::*;
66pub use strong::*;
67pub use uninit::*;
68pub use unique::*;
69pub use weak::*;
70
71/// A helper trait for [`Src::slice`].
72/// Analagous to [`SliceIndex`](std::slice::SliceIndex).
73pub trait SrcIndex<T: SrcSlice + ?Sized> {
74  
75  /// The output type returned by methods.
76  type Output: SrcTarget + ?Sized;
77  
78  /// Returns an [`Src`] pointer to the output at this location, panicking if out of bounds.
79  fn get(self, slice: Src<T>) -> Src<Self::Output>;
80  
81}
82
83impl<T> SrcIndex<[T]> for usize {
84  
85  type Output = T;
86  
87  #[inline]
88  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
89    Src::into_item(slice, self)
90  }
91  
92}
93
94impl<T> SrcIndex<[T]> for (Bound<usize>, Bound<usize>) {
95  
96  type Output = [T];
97  
98  #[inline]
99  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
100    let (start, end) = self;
101    Src::into_slice_from_bounds(slice, start, end)
102  }
103  
104}
105
106impl<T> SrcIndex<[T]> for Range<usize> {
107  
108  type Output = [T];
109  
110  #[inline]
111  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
112    let Range { start, end } = self;
113    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
114  }
115  
116}
117
118impl<T> SrcIndex<[T]> for RangeFrom<usize> {
119  
120  type Output = [T];
121  
122  #[inline]
123  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
124    let RangeFrom { start } = self;
125    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
126  }
127  
128}
129
130impl<T> SrcIndex<[T]> for RangeFull {
131  
132  type Output = [T];
133  
134  #[inline]
135  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
136    let RangeFull = self;
137    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
138  }
139  
140}
141
142impl<T> SrcIndex<[T]> for RangeInclusive<usize> {
143  
144  type Output = [T];
145  
146  #[inline]
147  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
148    let (start, end) = self.into_inner();
149    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
150  }
151  
152}
153
154impl<T> SrcIndex<[T]> for RangeTo<usize> {
155  
156  type Output = [T];
157  
158  #[inline]
159  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
160    let RangeTo { end } = self;
161    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
162  }
163  
164}
165
166impl<T> SrcIndex<[T]> for RangeToInclusive<usize> {
167  
168  type Output = [T];
169  
170  #[inline]
171  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
172    let RangeToInclusive { end } = self;
173    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
174  }
175  
176}
177
178impl SrcIndex<str> for (Bound<usize>, Bound<usize>) {
179  
180  type Output = str;
181  
182  #[inline]
183  fn get(self, slice: Src<str>) -> Src<Self::Output> {
184    let (start, end) = self;
185    Src::into_slice_from_bounds(slice, start, end)
186  }
187  
188}
189
190impl SrcIndex<str> for Range<usize> {
191  
192  type Output = str;
193  
194  #[inline]
195  fn get(self, slice: Src<str>) -> Src<Self::Output> {
196    let Range { start, end } = self;
197    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
198  }
199  
200}
201
202impl SrcIndex<str> for RangeFrom<usize> {
203  
204  type Output = str;
205  
206  #[inline]
207  fn get(self, slice: Src<str>) -> Src<Self::Output> {
208    let RangeFrom { start } = self;
209    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
210  }
211  
212}
213
214impl SrcIndex<str> for RangeFull {
215  
216  type Output = str;
217  
218  #[inline]
219  fn get(self, slice: Src<str>) -> Src<Self::Output> {
220    let RangeFull = self;
221    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
222  }
223  
224}
225
226impl SrcIndex<str> for RangeInclusive<usize> {
227  
228  type Output = str;
229  
230  #[inline]
231  fn get(self, slice: Src<str>) -> Src<Self::Output> {
232    let (start, end) = self.into_inner();
233    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
234  }
235  
236}
237
238impl SrcIndex<str> for RangeTo<usize> {
239  
240  type Output = str;
241  
242  #[inline]
243  fn get(self, slice: Src<str>) -> Src<Self::Output> {
244    let RangeTo { end } = self;
245    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
246  }
247  
248}
249
250impl SrcIndex<str> for RangeToInclusive<usize> {
251  
252  type Output = str;
253  
254  #[inline]
255  fn get(self, slice: Src<str>) -> Src<Self::Output> {
256    let RangeToInclusive { end } = self;
257    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
258  }
259  
260}
261
262/// A helper trait for [`WeakSrc::slice`].
263pub trait WeakSrcIndex<T: SrcSlice + ?Sized>: SrcIndex<T> {
264  
265  /// Returns a [`WeakSrc`] pointer to the output at this location, panicking if out of bounds.
266  fn get_weak(self, slice: WeakSrc<T>) -> WeakSrc<Self::Output>;
267  
268}
269
270impl<T> WeakSrcIndex<[T]> for usize {
271  
272  #[inline]
273  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
274    WeakSrc::into_item(slice, self)
275  }
276  
277}
278
279impl<T> WeakSrcIndex<[T]> for (Bound<usize>, Bound<usize>) {
280  
281  #[inline]
282  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
283    let (start, end) = self;
284    WeakSrc::into_slice_from_bounds(slice, start, end)
285  }
286  
287}
288
289impl<T> WeakSrcIndex<[T]> for Range<usize> {
290  
291  #[inline]
292  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
293    let Range { start, end } = self;
294    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
295  }
296  
297}
298
299impl<T> WeakSrcIndex<[T]> for RangeFrom<usize> {
300  
301  #[inline]
302  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
303    let RangeFrom { start } = self;
304    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
305  }
306  
307}
308
309impl<T> WeakSrcIndex<[T]> for RangeFull {
310  
311  #[inline]
312  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
313    let RangeFull = self;
314    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
315  }
316  
317}
318
319impl<T> WeakSrcIndex<[T]> for RangeInclusive<usize> {
320  
321  #[inline]
322  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
323    let (start, end) = self.into_inner();
324    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
325  }
326  
327}
328
329impl<T> WeakSrcIndex<[T]> for RangeTo<usize> {
330  
331  #[inline]
332  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
333    let RangeTo { end } = self;
334    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
335  }
336  
337}
338
339impl<T> WeakSrcIndex<[T]> for RangeToInclusive<usize> {
340  
341  #[inline]
342  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
343    let RangeToInclusive { end } = self;
344    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
345  }
346  
347}
348
349/// A sealed trait to encode types that can can be used in the `Src`-family of pointers.
350/// 
351/// Either <code>Self: [Sized]</code> or <code>Self: [SrcSlice]</code>.
352pub trait SrcTarget: private::SealedSrcTarget {
353  
354  /// The type of each element of a <code>[Src]\<Self></code>.
355  /// * Where <code>Self: [Sized]</code>: `Self::Item = Self`
356  /// * Where <code>Self = [\[T\]](prim@slice)</code>: `Self::Item = T`
357  /// * Where <code>Self = [str]</code>: <code>Self::Item = [u8]</code>
358  ///   (because a [`str`] is just a [`[u8]`](prim@slice) which must be UTF-8)
359  type Item: Sized;
360  
361}
362
363#[diagnostic::do_not_recommend]
364impl<T> SrcTarget for T {
365  
366  type Item = T;
367  
368}
369
370#[diagnostic::do_not_recommend]
371impl<T> private::SealedSrcTarget for T {
372  
373  type Len = ();
374  
375  #[inline]
376  fn len_as_usize((): Self::Len) -> usize {
377    1
378  }
379  
380  fn get(rc: &Src<Self>) -> &Self {
381    // SAFETY:
382    // all constructor fns of Src guarantee initialization of all elements
383    unsafe { rc.start.as_ref() }
384  }
385  
386  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
387    // SAFETY:
388    // all constructor fns of UniqueSrc guarantee initialization of all elements
389    unsafe { rc.start.as_ref() }
390  }
391  
392  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
393    // SAFETY:
394    // all constructor fns of UniqueSrc guarantee initialization of all elements
395    unsafe { rc.start.as_mut() }
396  }
397  
398  #[inline]
399  fn new_unique_from_clone(&self) -> UniqueSrc<Self> where <Self as SrcTarget>::Item: Clone {
400    UniqueSrc::single(T::clone(self))
401  }
402  
403}
404
405impl<T> SrcTarget for [T] {
406  
407  type Item = T;
408  
409}
410
411impl<T> private::SealedSrcTarget for [T] {
412  
413  type Len = usize;
414  
415  #[inline]
416  fn len_as_usize(len: Self::Len) -> usize {
417    len
418  }
419  
420  fn get(rc: &Src<Self>) -> &Self {
421    let start = rc.start.as_ptr().cast_const();
422    let len = rc.len;
423    // SAFETY:
424    // * all constructor fns of Src guarantee initialization of all elements; if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
425    unsafe { slice::from_raw_parts(start, len) }
426  }
427  
428  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
429    let start = rc.start.as_ptr().cast_const();
430    let len = rc.len;
431    // SAFETY:
432    // * all constructor fns of Src guarantee initialization of all elements; if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
433    unsafe { slice::from_raw_parts(start, len) }
434  }
435  
436  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
437    let start = rc.start.as_ptr();
438    let len = rc.len;
439    // SAFETY:
440    // * all constructor fns of Src guarantee initialization of all elements; if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
441    unsafe { slice::from_raw_parts_mut(start, len) }
442  }
443  
444  #[inline]
445  fn new_unique_from_clone(&self) -> UniqueSrc<Self> where <Self as SrcTarget>::Item: Clone {
446    UniqueSrc::cloned(self)
447  }
448  
449}
450
451impl SrcTarget for str {
452  
453  type Item = u8;
454  
455}
456
457impl private::SealedSrcTarget for str {
458  
459  type Len = usize;
460  
461  #[inline]
462  fn len_as_usize(len: Self::Len) -> usize {
463    len
464  }
465  
466  fn get(rc: &Src<Self>) -> &Self {
467    let start = rc.start.as_ptr().cast_const();
468    let len = rc.len;
469    // SAFETY: all constructor fns of Src guarantee initialization of all elements (well, one of them unsafely passes that requirement on to the caller); if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
470    let slice: &[u8] = unsafe { slice::from_raw_parts(start, len) };
471    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
472    unsafe { str::from_utf8_unchecked(slice) }
473  }
474  
475  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
476    let start = rc.start.as_ptr().cast_const();
477    let len = rc.len;
478    // SAFETY: all constructor fns of Src guarantee initialization of all elements (well, one of them unsafely passes that requirement on to the caller); if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
479    let slice: &[u8] = unsafe { slice::from_raw_parts(start, len) };
480    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
481    unsafe { str::from_utf8_unchecked(slice) }
482  }
483  
484  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
485    let start = rc.start.as_ptr();
486    let len = rc.len;
487    // SAFETY: all constructor fns of Src guarantee initialization of all elements (well, one of them unsafely passes that requirement on to the caller); if this is a sliced clone, Src::clone_from_bounds guarantees that start and len will still be valid
488    let slice: &mut [u8] = unsafe { slice::from_raw_parts_mut(start, len) };
489    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
490    unsafe { str::from_utf8_unchecked_mut(slice) }
491  }
492  
493  #[inline]
494  fn new_unique_from_clone(&self) -> UniqueSrc<Self> {
495    UniqueSrc::new(self)
496  }
497  
498}
499
500/// A sealed trait to encode the subset of [`SrcTarget`] that can contain multiple elements.
501/// 
502/// Either <code>Self = [\[T\]](prim@slice)</code> or <code>Self = [str]</code>.
503pub trait SrcSlice: SrcTarget + private::SealedSrcSlice {}
504
505impl<T> SrcSlice for [T] {}
506
507impl<T> private::SealedSrcSlice for [T] {
508  
509  #[inline]
510  fn validate_range(_this: &Src<Self>, _range: Range<usize>) {}
511  
512}
513
514impl SrcSlice for str {}
515
516impl private::SealedSrcSlice for str {
517  
518  fn validate_range(this: &Src<Self>, range: Range<usize>) {
519    let s: &str = &**this;
520    let _ = s[range]; // construct the slice just to trigger the appropriate errors if these indices are not at char boundaries
521  }
522  
523}
524
525mod private {
526  
527  use std::ops::Range;
528  
529  pub trait SealedSrcTarget {
530    
531    type Len: Copy + Default;
532    
533    fn len_as_usize(len: Self::Len) -> usize;
534    
535    fn get(rc: &super::Src<Self>) -> &Self where Self: super::SrcTarget;
536    
537    fn get_unique(rc: &super::UniqueSrc<Self>) -> &Self where Self: super::SrcTarget;
538    
539    fn get_unique_mut(rc: &mut super::UniqueSrc<Self>) -> &mut Self where Self: super::SrcTarget;
540    
541    fn new_unique_from_clone(&self) -> super::UniqueSrc<Self> where Self: super::SrcTarget, Self::Item: Clone;
542    
543  }
544  
545  pub trait SealedSrcSlice: SealedSrcTarget<Len = usize> {
546    
547    fn validate_range(this: &super::Src<Self>, range: Range<usize>) where Self: super::SrcSlice;
548    
549  }
550  
551}