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`] and [`WeakSrc::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  /// Returns a [`WeakSrc`] pointer to the output at this location, panicking if out of bounds.
82  fn get_weak(self, slice: WeakSrc<T>) -> WeakSrc<Self::Output>;
83  
84}
85
86impl<T> SrcIndex<[T]> for usize {
87  
88  type Output = T;
89  
90  #[inline]
91  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
92    Src::into_item(slice, self)
93  }
94  
95  #[inline]
96  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
97    WeakSrc::into_item(slice, self)
98  }
99  
100}
101
102impl<T> SrcIndex<[T]> for (Bound<usize>, Bound<usize>) {
103  
104  type Output = [T];
105  
106  #[inline]
107  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
108    let (start, end) = self;
109    Src::into_slice_from_bounds(slice, start, end)
110  }
111  
112  #[inline]
113  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
114    let (start, end) = self;
115    WeakSrc::into_slice_from_bounds(slice, start, end)
116  }
117  
118}
119
120impl<T> SrcIndex<[T]> for Range<usize> {
121  
122  type Output = [T];
123  
124  #[inline]
125  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
126    let Range { start, end } = self;
127    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
128  }
129  
130  #[inline]
131  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
132    let Range { start, end } = self;
133    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
134  }
135  
136}
137
138impl<T> SrcIndex<[T]> for RangeFrom<usize> {
139  
140  type Output = [T];
141  
142  #[inline]
143  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
144    let RangeFrom { start } = self;
145    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
146  }
147  
148  #[inline]
149  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
150    let RangeFrom { start } = self;
151    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
152  }
153  
154}
155
156impl<T> SrcIndex<[T]> for RangeFull {
157  
158  type Output = [T];
159  
160  #[inline]
161  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
162    let RangeFull = self;
163    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
164  }
165  
166  #[inline]
167  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
168    let RangeFull = self;
169    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
170  }
171  
172}
173
174impl<T> SrcIndex<[T]> for RangeInclusive<usize> {
175  
176  type Output = [T];
177  
178  #[inline]
179  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
180    let (start, end) = self.into_inner();
181    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
182  }
183  
184  #[inline]
185  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
186    let (start, end) = self.into_inner();
187    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
188  }
189  
190}
191
192impl<T> SrcIndex<[T]> for RangeTo<usize> {
193  
194  type Output = [T];
195  
196  #[inline]
197  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
198    let RangeTo { end } = self;
199    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
200  }
201  
202  #[inline]
203  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
204    let RangeTo { end } = self;
205    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
206  }
207  
208}
209
210impl<T> SrcIndex<[T]> for RangeToInclusive<usize> {
211  
212  type Output = [T];
213  
214  #[inline]
215  fn get(self, slice: Src<[T]>) -> Src<Self::Output> {
216    let RangeToInclusive { end } = self;
217    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
218  }
219  
220  #[inline]
221  fn get_weak(self, slice: WeakSrc<[T]>) -> WeakSrc<Self::Output> {
222    let RangeToInclusive { end } = self;
223    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
224  }
225  
226}
227
228impl SrcIndex<str> for (Bound<usize>, Bound<usize>) {
229  
230  type Output = str;
231  
232  #[inline]
233  fn get(self, slice: Src<str>) -> Src<Self::Output> {
234    let (start, end) = self;
235    Src::into_slice_from_bounds(slice, start, end)
236  }
237  
238  #[inline]
239  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
240    let (start, end) = self;
241    WeakSrc::into_slice_from_bounds(slice, start, end)
242  }
243  
244}
245
246impl SrcIndex<str> for Range<usize> {
247  
248  type Output = str;
249  
250  #[inline]
251  fn get(self, slice: Src<str>) -> Src<Self::Output> {
252    let Range { start, end } = self;
253    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
254  }
255  
256  #[inline]
257  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
258    let Range { start, end } = self;
259    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Excluded(end))
260  }
261  
262}
263
264impl SrcIndex<str> for RangeFrom<usize> {
265  
266  type Output = str;
267  
268  #[inline]
269  fn get(self, slice: Src<str>) -> Src<Self::Output> {
270    let RangeFrom { start } = self;
271    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
272  }
273  
274  #[inline]
275  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
276    let RangeFrom { start } = self;
277    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Unbounded)
278  }
279  
280}
281
282impl SrcIndex<str> for RangeFull {
283  
284  type Output = str;
285  
286  #[inline]
287  fn get(self, slice: Src<str>) -> Src<Self::Output> {
288    let RangeFull = self;
289    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
290  }
291  
292  #[inline]
293  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
294    let RangeFull = self;
295    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Unbounded)
296  }
297  
298}
299
300impl SrcIndex<str> for RangeInclusive<usize> {
301  
302  type Output = str;
303  
304  #[inline]
305  fn get(self, slice: Src<str>) -> Src<Self::Output> {
306    let (start, end) = self.into_inner();
307    Src::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
308  }
309  
310  #[inline]
311  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
312    let (start, end) = self.into_inner();
313    WeakSrc::into_slice_from_bounds(slice, Bound::Included(start), Bound::Included(end))
314  }
315  
316}
317
318impl SrcIndex<str> for RangeTo<usize> {
319  
320  type Output = str;
321  
322  #[inline]
323  fn get(self, slice: Src<str>) -> Src<Self::Output> {
324    let RangeTo { end } = self;
325    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
326  }
327  
328  #[inline]
329  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
330    let RangeTo { end } = self;
331    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Excluded(end))
332  }
333  
334}
335
336impl SrcIndex<str> for RangeToInclusive<usize> {
337  
338  type Output = str;
339  
340  #[inline]
341  fn get(self, slice: Src<str>) -> Src<Self::Output> {
342    let RangeToInclusive { end } = self;
343    Src::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
344  }
345  
346  #[inline]
347  fn get_weak(self, slice: WeakSrc<str>) -> WeakSrc<Self::Output> {
348    let RangeToInclusive { end } = self;
349    WeakSrc::into_slice_from_bounds(slice, Bound::Unbounded, Bound::Included(end))
350  }
351  
352}
353
354/// A sealed trait to encode types that can can be used in the `Src`-family of pointers.
355/// 
356/// Either <code>Self: [Sized]</code> or <code>Self: [SrcSlice]</code>.
357pub trait SrcTarget: private::SealedSrcTarget {
358  
359  /// The type of each element of a <code>[Src]\<Self></code>.
360  /// * Where <code>Self: [Sized]</code>: `Self::Item = Self`
361  /// * Where <code>Self = [\[T\]](prim@slice)</code>: `Self::Item = T`
362  /// * Where <code>Self = [str]</code>: <code>Self::Item = [u8]</code>
363  ///   (because a [`str`] is just a [`[u8]`](prim@slice) which must be UTF-8)
364  type Item: Sized;
365  
366}
367
368#[diagnostic::do_not_recommend]
369impl<T> SrcTarget for T {
370  
371  type Item = T;
372  
373}
374
375#[diagnostic::do_not_recommend]
376impl<T> private::SealedSrcTarget for T {
377  
378  type Len = ();
379  
380  #[inline]
381  fn len_as_usize((): Self::Len) -> usize {
382    1
383  }
384  
385  fn get(rc: &Src<Self>) -> &Self {
386    // SAFETY:
387    // all constructor fns of Src guarantee initialization of all elements
388    unsafe { rc.start.as_ref() }
389  }
390  
391  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
392    // SAFETY:
393    // all constructor fns of UniqueSrc guarantee initialization of all elements
394    unsafe { rc.start.as_ref() }
395  }
396  
397  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
398    // SAFETY:
399    // all constructor fns of UniqueSrc guarantee initialization of all elements
400    unsafe { rc.start.as_mut() }
401  }
402  
403  #[inline]
404  fn new_unique_from_clone(&self) -> UniqueSrc<Self> where <Self as SrcTarget>::Item: Clone {
405    UniqueSrc::single(T::clone(self))
406  }
407  
408}
409
410impl<T> SrcTarget for [T] {
411  
412  type Item = T;
413  
414}
415
416impl<T> private::SealedSrcTarget for [T] {
417  
418  type Len = usize;
419  
420  #[inline]
421  fn len_as_usize(len: Self::Len) -> usize {
422    len
423  }
424  
425  fn get(rc: &Src<Self>) -> &Self {
426    let start = rc.start.as_ptr().cast_const();
427    let len = rc.len;
428    // SAFETY:
429    // * 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
430    unsafe { slice::from_raw_parts(start, len) }
431  }
432  
433  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
434    let start = rc.start.as_ptr().cast_const();
435    let len = rc.len;
436    // SAFETY:
437    // * 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
438    unsafe { slice::from_raw_parts(start, len) }
439  }
440  
441  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
442    let start = rc.start.as_ptr();
443    let len = rc.len;
444    // SAFETY:
445    // * 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
446    unsafe { slice::from_raw_parts_mut(start, len) }
447  }
448  
449  #[inline]
450  fn new_unique_from_clone(&self) -> UniqueSrc<Self> where <Self as SrcTarget>::Item: Clone {
451    UniqueSrc::cloned(self)
452  }
453  
454}
455
456impl SrcTarget for str {
457  
458  type Item = u8;
459  
460}
461
462impl private::SealedSrcTarget for str {
463  
464  type Len = usize;
465  
466  #[inline]
467  fn len_as_usize(len: Self::Len) -> usize {
468    len
469  }
470  
471  fn get(rc: &Src<Self>) -> &Self {
472    let start = rc.start.as_ptr().cast_const();
473    let len = rc.len;
474    // 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
475    let slice: &[u8] = unsafe { slice::from_raw_parts(start, len) };
476    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
477    unsafe { str::from_utf8_unchecked(slice) }
478  }
479  
480  fn get_unique(rc: &UniqueSrc<Self>) -> &Self {
481    let start = rc.start.as_ptr().cast_const();
482    let len = rc.len;
483    // 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
484    let slice: &[u8] = unsafe { slice::from_raw_parts(start, len) };
485    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
486    unsafe { str::from_utf8_unchecked(slice) }
487  }
488  
489  fn get_unique_mut(rc: &mut UniqueSrc<Self>) -> &mut Self {
490    let start = rc.start.as_ptr();
491    let len = rc.len;
492    // 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
493    let slice: &mut [u8] = unsafe { slice::from_raw_parts_mut(start, len) };
494    // SAFETY: all constructor fns of Src<str> guarantee the contents are UTF8
495    unsafe { str::from_utf8_unchecked_mut(slice) }
496  }
497  
498  #[inline]
499  fn new_unique_from_clone(&self) -> UniqueSrc<Self> {
500    UniqueSrc::new(self)
501  }
502  
503}
504
505/// A sealed trait to encode the subset of [`SrcTarget`] that can contain multiple elements.
506/// 
507/// Either <code>Self = [\[T\]](prim@slice)</code> or <code>Self = [str]</code>.
508pub trait SrcSlice: SrcTarget + private::SealedSrcSlice {}
509
510impl<T> SrcSlice for [T] {}
511
512impl<T> private::SealedSrcSlice for [T] {
513  
514  #[inline]
515  fn validate_range(_this: &Src<Self>, _range: Range<usize>) {}
516  
517  #[inline]
518  unsafe fn validate_range_weak(_this: &WeakSrc<Self>, _range: Range<usize>) {}
519  
520}
521
522impl SrcSlice for str {}
523
524impl private::SealedSrcSlice for str {
525  
526  fn validate_range(this: &Src<Self>, range: Range<usize>) {
527    let s: &str = &**this;
528    let _ = s[range]; // construct the slice just to trigger the appropriate errors if these indices are not at char boundaries
529  }
530  
531  // SAFETY:
532  // requires:
533  // * that this is not dangling nor dropped
534  unsafe fn validate_range_weak(this: &crate::WeakSrc<Self>, range: Range<usize>) where Self: crate::SrcSlice {
535    // SAFETY:
536    // * safety requirements passed onto the caller
537    let s: &[u8] = unsafe { this.get_slice() };
538    // SAFETY: all constructor fns of WeakSrc<str> guarantee the contents are UTF-8
539    let s: &str = unsafe { str::from_utf8_unchecked(s) };
540    let _ = s[range];
541  }
542  
543}
544
545mod private {
546  
547  use std::ops::Range;
548  
549  pub trait SealedSrcTarget {
550    
551    type Len: Copy + Default;
552    
553    fn len_as_usize(len: Self::Len) -> usize;
554    
555    fn get(rc: &super::Src<Self>) -> &Self where Self: super::SrcTarget;
556    
557    fn get_unique(rc: &super::UniqueSrc<Self>) -> &Self where Self: super::SrcTarget;
558    
559    fn get_unique_mut(rc: &mut super::UniqueSrc<Self>) -> &mut Self where Self: super::SrcTarget;
560    
561    fn new_unique_from_clone(&self) -> super::UniqueSrc<Self> where Self: super::SrcTarget, Self::Item: Clone;
562    
563  }
564  
565  pub trait SealedSrcSlice: SealedSrcTarget<Len = usize> {
566    
567    fn validate_range(this: &super::Src<Self>, range: Range<usize>) where Self: super::SrcSlice;
568    
569    // SAFETY:
570    // requires:
571    // * that this is not dangling nor dropped
572    unsafe fn validate_range_weak(this: &super::WeakSrc<Self>, range: Range<usize>) where Self: super::SrcSlice;
573    
574  }
575  
576}