chumsky/
container.rs

1//! TODO
2
3use super::*;
4use alloc::collections::LinkedList;
5use hashbrown::HashSet;
6
7/// A utility trait for types that can be constructed from a series of items.
8pub trait Container<T>: Default {
9    /// Create a container, attempting to pre-allocate enough space for `n` items.
10    ///
11    /// Failure to do so is not a problem, the size is only a hint.
12    fn with_capacity(n: usize) -> Self {
13        let _ = n;
14        Self::default()
15    }
16    /// Add a value to the end of this container.
17    fn push(&mut self, item: T);
18}
19
20impl<T, C> Container<T> for Box<C>
21where
22    C: Container<T>,
23{
24    fn with_capacity(n: usize) -> Self {
25        Box::new(C::with_capacity(n))
26    }
27
28    fn push(&mut self, item: T) {
29        C::push(self, item)
30    }
31}
32
33impl<T, C> Container<T> for Cell<C>
34where
35    C: Container<T>,
36{
37    fn with_capacity(n: usize) -> Self {
38        Cell::new(C::with_capacity(n))
39    }
40
41    fn push(&mut self, item: T) {
42        self.get_mut().push(item)
43    }
44}
45
46impl<T, C> Container<T> for RefCell<C>
47where
48    C: Container<T>,
49{
50    fn with_capacity(n: usize) -> Self {
51        RefCell::new(C::with_capacity(n))
52    }
53
54    fn push(&mut self, item: T) {
55        self.get_mut().push(item)
56    }
57}
58
59impl<T> Container<T> for () {
60    fn push(&mut self, _: T) {}
61}
62
63/// A collection that counts items instead of containing them.
64impl<T> Container<T> for usize {
65    fn push(&mut self, _: T) {
66        *self += 1;
67    }
68}
69
70impl<T> Container<T> for Vec<T> {
71    fn with_capacity(n: usize) -> Self {
72        Self::with_capacity(n)
73    }
74    fn push(&mut self, item: T) {
75        (*self).push(item);
76    }
77}
78
79impl<T> Container<T> for LinkedList<T> {
80    fn push(&mut self, item: T) {
81        (*self).push_back(item);
82    }
83}
84
85impl Container<char> for String {
86    fn with_capacity(n: usize) -> Self {
87        // Note: we're assuming that most characters are going to be ASCII, and hence only require one byte to store.
88        Self::with_capacity(n)
89    }
90    fn push(&mut self, item: char) {
91        (*self).push(item)
92    }
93}
94
95impl<K: Eq + Hash, V> Container<(K, V)> for HashMap<K, V> {
96    fn with_capacity(n: usize) -> Self {
97        Self::with_capacity(n)
98    }
99    fn push(&mut self, (key, value): (K, V)) {
100        (*self).insert(key, value);
101    }
102}
103
104#[cfg(feature = "std")]
105impl<K: Eq + Hash, V> Container<(K, V)> for std::collections::HashMap<K, V> {
106    fn with_capacity(n: usize) -> Self {
107        Self::with_capacity(n)
108    }
109    fn push(&mut self, (key, value): (K, V)) {
110        (*self).insert(key, value);
111    }
112}
113
114impl<T: Eq + Hash> Container<T> for HashSet<T> {
115    fn with_capacity(n: usize) -> Self {
116        Self::with_capacity(n)
117    }
118    fn push(&mut self, item: T) {
119        (*self).insert(item);
120    }
121}
122
123#[cfg(feature = "std")]
124impl<T: Eq + Hash> Container<T> for std::collections::HashSet<T> {
125    fn with_capacity(n: usize) -> Self {
126        Self::with_capacity(n)
127    }
128    fn push(&mut self, item: T) {
129        (*self).insert(item);
130    }
131}
132
133#[cfg(feature = "std")]
134impl<T> Container<T> for std::collections::VecDeque<T> {
135    fn with_capacity(n: usize) -> Self {
136        Self::with_capacity(n)
137    }
138    fn push(&mut self, item: T) {
139        self.push_back(item);
140    }
141}
142
143impl<K: Ord, V> Container<(K, V)> for alloc::collections::BTreeMap<K, V> {
144    fn push(&mut self, (key, value): (K, V)) {
145        (*self).insert(key, value);
146    }
147}
148
149impl<T: Ord> Container<T> for alloc::collections::BTreeSet<T> {
150    fn push(&mut self, item: T) {
151        (*self).insert(item);
152    }
153}
154
155/// A utility trait for types that hold a specific constant number of output values.
156///
157/// # Safety
158///
159/// This trait requires that [`Uninit`](ContainerExactly::Uninit) be sound to reinterpret as `Self`
160pub unsafe trait ContainerExactly<T> {
161    /// The length of this container
162    const LEN: usize;
163
164    /// An uninitialized value of this container.
165    type Uninit;
166
167    /// Get an uninitialized form of this container.
168    fn uninit() -> Self::Uninit;
169
170    /// Write a value to a position in an uninitialized container.
171    fn write(uninit: &mut Self::Uninit, i: usize, item: T);
172
173    /// Drop all values before a provided index in this container.
174    ///
175    /// # Safety
176    ///
177    /// All values up to the provided index must be initialized.
178    unsafe fn drop_before(uninit: &mut Self::Uninit, i: usize);
179
180    /// Convert this container into its initialized form.
181    ///
182    /// # Safety
183    ///
184    /// All values in the container must be initialized.
185    unsafe fn take(uninit: Self::Uninit) -> Self;
186}
187
188// SAFETY: `[MaybeUninit<T>; N]` has the same layout as `[T; N]`
189unsafe impl<T, const N: usize> ContainerExactly<T> for [T; N] {
190    const LEN: usize = N;
191
192    type Uninit = [MaybeUninit<T>; N];
193    fn uninit() -> Self::Uninit {
194        MaybeUninitExt::uninit_array()
195    }
196    fn write(uninit: &mut Self::Uninit, i: usize, item: T) {
197        uninit[i].write(item);
198    }
199    unsafe fn drop_before(uninit: &mut Self::Uninit, i: usize) {
200        uninit[..i].iter_mut().for_each(|o| o.assume_init_drop());
201    }
202    unsafe fn take(uninit: Self::Uninit) -> Self {
203        MaybeUninitExt::array_assume_init(uninit)
204    }
205}
206
207// Safety: `Box<C::Uninit>` is sound to reinterpret assuming the inner `C` implements this trait soundly
208unsafe impl<T, C> ContainerExactly<T> for Box<C>
209where
210    C: ContainerExactly<T>,
211{
212    const LEN: usize = C::LEN;
213    type Uninit = Box<C::Uninit>;
214    fn uninit() -> Self::Uninit {
215        Box::new(C::uninit())
216    }
217    fn write(uninit: &mut Self::Uninit, i: usize, item: T) {
218        C::write(&mut *uninit, i, item)
219    }
220    unsafe fn drop_before(uninit: &mut Self::Uninit, i: usize) {
221        C::drop_before(&mut *uninit, i)
222    }
223    unsafe fn take(uninit: Self::Uninit) -> Self {
224        Box::from_raw(Box::into_raw(uninit) as *mut C)
225    }
226}
227
228/*
229// TODO: Unsound!
230// Safety: `Rc<UnsafeCell<C::Uninit>>` is sound to reinterpret assuming the inner `C` implements
231//         this trait soundly
232unsafe impl<T, C> ContainerExactly<T> for Rc<C>
233where
234    C: ContainerExactly<T>,
235{
236    const LEN: usize = C::LEN;
237    type Uninit = Rc<UnsafeCell<C::Uninit>>;
238    fn uninit() -> Self::Uninit {
239        Rc::new(UnsafeCell::new(C::uninit()))
240    }
241    fn write(uninit: &mut Self::Uninit, i: usize, item: T) {
242        // SAFETY: We're the only owners of the uninit data at this point
243        C::write(unsafe { &mut *uninit.get() }, i, item)
244    }
245    unsafe fn drop_before(uninit: &mut Self::Uninit, i: usize) {
246        // SAFETY: We're the only owners of the uninit data at this point
247        C::drop_before(unsafe { &mut *uninit.get() }, i)
248    }
249    unsafe fn take(uninit: Self::Uninit) -> Self {
250        Rc::from_raw(Rc::into_raw(uninit) as *mut C)
251    }
252}
253*/
254
255/*
256// TODO: Unsound!
257#[allow(clippy::arc_with_non_send_sync)]
258// SAFETY: `Arc<UnsafeCell<C::Uninit>>` is sound to reinterpret assuming the inner `C` implements
259//         this trait soundly
260unsafe impl<T, C> ContainerExactly<T> for Arc<C>
261where
262    C: ContainerExactly<T>,
263{
264    const LEN: usize = C::LEN;
265    type Uninit = Arc<UnsafeCell<C::Uninit>>;
266    fn uninit() -> Self::Uninit {
267        Arc::new(UnsafeCell::new(C::uninit()))
268    }
269    fn write(uninit: &mut Self::Uninit, i: usize, item: T) {
270        // SAFETY: We're the only owners of the uninit data at this point
271        C::write(unsafe { &mut *uninit.get() }, i, item)
272    }
273    unsafe fn drop_before(uninit: &mut Self::Uninit, i: usize) {
274        // SAFETY: We're the only owners of the uninit data at this point
275        C::drop_before(unsafe { &mut *uninit.get() }, i)
276    }
277    unsafe fn take(uninit: Self::Uninit) -> Self {
278        Arc::from_raw(Arc::into_raw(uninit) as *mut C)
279    }
280}
281*/
282
283/// A utility trait to abstract over container-like things.
284///
285/// This trait is likely to change in future versions of the crate, so avoid implementing it yourself.
286pub trait Seq<'p, T> {
287    /// The item yielded by the iterator.
288    type Item<'a>: Borrow<T>
289    where
290        Self: 'a;
291
292    /// An iterator over the items within this container, by reference.
293    type Iter<'a>: Iterator<Item = Self::Item<'a>>
294    where
295        Self: 'a;
296
297    /// Iterate over the elements of the container.
298    fn seq_iter(&self) -> Self::Iter<'_>;
299
300    /// Check whether an item is contained within this sequence.
301    fn contains(&self, val: &T) -> bool
302    where
303        T: PartialEq;
304
305    /// Convert an item of the sequence into a [`MaybeRef`].
306    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
307    where
308        'p: 'b;
309}
310
311impl<'p, T: Clone> Seq<'p, T> for T {
312    type Item<'a>
313        = &'a T
314    where
315        Self: 'a;
316
317    type Iter<'a>
318        = core::iter::Once<&'a T>
319    where
320        Self: 'a;
321
322    #[inline(always)]
323    fn seq_iter(&self) -> Self::Iter<'_> {
324        core::iter::once(self)
325    }
326
327    #[inline(always)]
328    fn contains(&self, val: &T) -> bool
329    where
330        T: PartialEq,
331    {
332        self == val
333    }
334
335    #[inline]
336    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
337    where
338        'p: 'b,
339    {
340        MaybeRef::Val(item.clone())
341    }
342}
343
344impl<'p, T> Seq<'p, T> for &'p T {
345    type Item<'a>
346        = &'p T
347    where
348        Self: 'a;
349
350    type Iter<'a>
351        = core::iter::Once<&'p T>
352    where
353        Self: 'a;
354
355    #[inline(always)]
356    fn seq_iter(&self) -> Self::Iter<'_> {
357        core::iter::once(*self)
358    }
359
360    #[inline(always)]
361    fn contains(&self, val: &T) -> bool
362    where
363        T: PartialEq,
364    {
365        *self == val
366    }
367
368    #[inline]
369    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
370    where
371        'p: 'b,
372    {
373        MaybeRef::Ref(item)
374    }
375}
376
377impl<'p, T> Seq<'p, T> for &'p [T] {
378    type Item<'a>
379        = &'p T
380    where
381        Self: 'a;
382
383    type Iter<'a>
384        = core::slice::Iter<'p, T>
385    where
386        Self: 'a;
387
388    #[inline(always)]
389    fn seq_iter(&self) -> Self::Iter<'_> {
390        (self as &[T]).iter()
391    }
392
393    #[inline(always)]
394    fn contains(&self, val: &T) -> bool
395    where
396        T: PartialEq,
397    {
398        <[T]>::contains(self, val)
399    }
400
401    #[inline]
402    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
403    where
404        'p: 'b,
405    {
406        MaybeRef::Ref(item)
407    }
408}
409
410impl<'p, T: Clone, const N: usize> Seq<'p, T> for [T; N] {
411    type Item<'a>
412        = &'a T
413    where
414        Self: 'a;
415
416    type Iter<'a>
417        = core::slice::Iter<'a, T>
418    where
419        Self: 'a;
420
421    #[inline(always)]
422    fn seq_iter(&self) -> Self::Iter<'_> {
423        self.iter()
424    }
425
426    #[inline(always)]
427    fn contains(&self, val: &T) -> bool
428    where
429        T: PartialEq,
430    {
431        <[T]>::contains(self, val)
432    }
433
434    #[inline]
435    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
436    where
437        'p: 'b,
438    {
439        MaybeRef::Val(item.clone())
440    }
441}
442
443impl<'p, T, const N: usize> Seq<'p, T> for &'p [T; N] {
444    type Item<'a>
445        = &'p T
446    where
447        Self: 'a;
448
449    type Iter<'a>
450        = core::slice::Iter<'p, T>
451    where
452        Self: 'a;
453
454    #[inline(always)]
455    fn seq_iter(&self) -> Self::Iter<'_> {
456        self.iter()
457    }
458
459    #[inline(always)]
460    fn contains(&self, val: &T) -> bool
461    where
462        T: PartialEq,
463    {
464        #[allow(clippy::explicit_auto_deref)] // FIXME: Clippy bug #9841
465        <[T]>::contains(*self, val)
466    }
467
468    #[inline]
469    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
470    where
471        'p: 'b,
472    {
473        MaybeRef::Ref(item)
474    }
475}
476
477impl<'p, T: Clone> Seq<'p, T> for Vec<T> {
478    type Item<'a>
479        = &'a T
480    where
481        Self: 'a;
482
483    type Iter<'a>
484        = core::slice::Iter<'a, T>
485    where
486        Self: 'a;
487
488    #[inline(always)]
489    fn seq_iter(&self) -> Self::Iter<'_> {
490        self.iter()
491    }
492
493    #[inline(always)]
494    fn contains(&self, val: &T) -> bool
495    where
496        T: PartialEq,
497    {
498        <[T]>::contains(self, val)
499    }
500
501    #[inline]
502    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
503    where
504        'p: 'b,
505    {
506        MaybeRef::Val(item.clone())
507    }
508}
509
510impl<'p, T: Clone> Seq<'p, T> for LinkedList<T> {
511    type Item<'a>
512        = &'a T
513    where
514        Self: 'a;
515
516    type Iter<'a>
517        = alloc::collections::linked_list::Iter<'a, T>
518    where
519        Self: 'a;
520
521    #[inline(always)]
522    fn seq_iter(&self) -> Self::Iter<'_> {
523        self.iter()
524    }
525
526    #[inline(always)]
527    fn contains(&self, val: &T) -> bool
528    where
529        T: PartialEq,
530    {
531        LinkedList::contains(self, val)
532    }
533
534    #[inline]
535    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
536    where
537        'p: 'b,
538    {
539        MaybeRef::Val(item.clone())
540    }
541}
542
543impl<'p, T: Clone + Eq + Hash> Seq<'p, T> for HashSet<T> {
544    type Item<'a>
545        = &'a T
546    where
547        Self: 'a;
548
549    type Iter<'a>
550        = hashbrown::hash_set::Iter<'a, T>
551    where
552        Self: 'a;
553
554    #[inline(always)]
555    fn seq_iter(&self) -> Self::Iter<'_> {
556        self.iter()
557    }
558
559    #[inline(always)]
560    fn contains(&self, val: &T) -> bool
561    where
562        T: PartialEq,
563    {
564        HashSet::contains(self, val)
565    }
566
567    #[inline]
568    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
569    where
570        'p: 'b,
571    {
572        MaybeRef::Val(item.clone())
573    }
574}
575
576#[cfg(feature = "std")]
577impl<'p, T: Clone + Eq + Hash> Seq<'p, T> for std::collections::HashSet<T> {
578    type Item<'a>
579        = &'a T
580    where
581        Self: 'a;
582
583    type Iter<'a>
584        = std::collections::hash_set::Iter<'a, T>
585    where
586        Self: 'a;
587
588    #[inline(always)]
589    fn seq_iter(&self) -> Self::Iter<'_> {
590        self.iter()
591    }
592
593    #[inline(always)]
594    fn contains(&self, val: &T) -> bool
595    where
596        T: PartialEq,
597    {
598        self.contains(val)
599    }
600
601    #[inline]
602    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
603    where
604        'p: 'b,
605    {
606        MaybeRef::Val(item.clone())
607    }
608}
609
610impl<'p, T: Clone + Ord> Seq<'p, T> for alloc::collections::BTreeSet<T> {
611    type Item<'a>
612        = &'a T
613    where
614        Self: 'a;
615
616    type Iter<'a>
617        = alloc::collections::btree_set::Iter<'a, T>
618    where
619        Self: 'a;
620
621    #[inline(always)]
622    fn seq_iter(&self) -> Self::Iter<'_> {
623        self.iter()
624    }
625
626    #[inline(always)]
627    fn contains(&self, val: &T) -> bool
628    where
629        T: PartialEq,
630    {
631        self.contains(val)
632    }
633
634    #[inline]
635    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
636    where
637        'p: 'b,
638    {
639        MaybeRef::Val(item.clone())
640    }
641}
642
643impl<'p, T> Seq<'p, T> for Range<T>
644where
645    T: Clone + PartialOrd, // Explicit declaration of an implied truth - `Step` requires these
646    Self: Iterator<Item = T>,
647{
648    type Item<'a>
649        = T
650    where
651        Self: 'a;
652
653    type Iter<'a>
654        = Range<T>
655    where
656        Self: 'a;
657
658    #[inline(always)]
659    fn seq_iter(&self) -> Self::Iter<'_> {
660        (*self).clone()
661    }
662
663    #[inline(always)]
664    fn contains(&self, val: &T) -> bool {
665        Range::contains(self, val)
666    }
667
668    #[inline]
669    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
670    where
671        'p: 'b,
672    {
673        MaybeRef::Val(item)
674    }
675}
676
677impl<'p, T> Seq<'p, T> for core::ops::RangeInclusive<T>
678where
679    T: Clone + PartialOrd,
680    Self: Iterator<Item = T>,
681{
682    type Item<'a>
683        = T
684    where
685        Self: 'a;
686
687    type Iter<'a>
688        = core::ops::RangeInclusive<T>
689    where
690        Self: 'a;
691
692    #[inline(always)]
693    fn seq_iter(&self) -> Self::Iter<'_> {
694        self.clone()
695    }
696
697    #[inline(always)]
698    fn contains(&self, val: &T) -> bool {
699        core::ops::RangeInclusive::contains(self, val)
700    }
701
702    #[inline]
703    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
704    where
705        'p: 'b,
706    {
707        MaybeRef::Val(item)
708    }
709}
710
711impl<'p, T> Seq<'p, T> for RangeFrom<T>
712where
713    T: Clone + PartialOrd,
714    Self: Iterator<Item = T>,
715{
716    type Item<'a>
717        = T
718    where
719        Self: 'a;
720
721    type Iter<'a>
722        = RangeFrom<T>
723    where
724        Self: 'a;
725
726    #[inline(always)]
727    fn seq_iter(&self) -> Self::Iter<'_> {
728        self.clone()
729    }
730
731    #[inline(always)]
732    fn contains(&self, val: &T) -> bool {
733        RangeFrom::contains(self, val)
734    }
735
736    #[inline]
737    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
738    where
739        'p: 'b,
740    {
741        MaybeRef::Val(item)
742    }
743}
744
745impl<'p> Seq<'p, char> for str {
746    type Item<'a>
747        = char
748    where
749        Self: 'a;
750
751    type Iter<'a>
752        = core::str::Chars<'a>
753    where
754        Self: 'a;
755
756    #[inline(always)]
757    fn seq_iter(&self) -> Self::Iter<'_> {
758        self.chars()
759    }
760
761    #[inline(always)]
762    fn contains(&self, val: &char) -> bool {
763        self.contains(*val)
764    }
765
766    #[inline]
767    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, char>
768    where
769        'p: 'b,
770    {
771        MaybeRef::Val(item)
772    }
773}
774
775impl<'p> Seq<'p, char> for String {
776    type Item<'a>
777        = char
778    where
779        Self: 'a;
780
781    type Iter<'a>
782        = core::str::Chars<'a>
783    where
784        Self: 'a;
785
786    #[inline(always)]
787    fn seq_iter(&self) -> Self::Iter<'_> {
788        self.chars()
789    }
790
791    #[inline(always)]
792    fn contains(&self, val: &char) -> bool {
793        str::contains(self, *val)
794    }
795
796    #[inline]
797    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, char>
798    where
799        'p: 'b,
800    {
801        MaybeRef::Val(item)
802    }
803}
804
805impl<'p> Seq<'p, char> for &'p str {
806    type Item<'a>
807        = char
808    where
809        Self: 'a;
810
811    type Iter<'a>
812        = core::str::Chars<'a>
813    where
814        Self: 'a;
815
816    #[inline(always)]
817    fn seq_iter(&self) -> Self::Iter<'_> {
818        self.chars()
819    }
820
821    #[inline(always)]
822    fn contains(&self, val: &char) -> bool {
823        str::contains(self, *val)
824    }
825
826    #[inline]
827    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, char>
828    where
829        'p: 'b,
830    {
831        MaybeRef::Val(item)
832    }
833}
834
835impl<'p> Seq<'p, &'p Grapheme> for &'p str {
836    type Item<'a>
837        = &'p Grapheme
838    where
839        Self: 'a;
840
841    type Iter<'a>
842        = GraphemesIter<'p>
843    where
844        Self: 'a;
845
846    #[inline(always)]
847    fn seq_iter(&self) -> Self::Iter<'_> {
848        Graphemes::new(self).iter()
849    }
850
851    #[inline(always)]
852    fn contains(&self, val: &&'p Grapheme) -> bool {
853        Graphemes::new(self).contains(val)
854    }
855
856    #[inline]
857    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, &'p Grapheme>
858    where
859        'p: 'b,
860    {
861        MaybeRef::Val(item)
862    }
863}
864
865impl<'p> Seq<'p, &'p Grapheme> for &'p Graphemes {
866    type Item<'a>
867        = &'p Grapheme
868    where
869        Self: 'a;
870
871    type Iter<'a>
872        = GraphemesIter<'p>
873    where
874        Self: 'a;
875
876    #[inline(always)]
877    fn seq_iter(&self) -> Self::Iter<'_> {
878        self.iter()
879    }
880
881    #[inline(always)]
882    fn contains(&self, val: &&'p Grapheme) -> bool {
883        self.iter().any(|i| i == *val)
884    }
885
886    #[inline]
887    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, &'p Grapheme>
888    where
889        'p: 'b,
890    {
891        MaybeRef::Val(item)
892    }
893}
894
895/// A utility trait to abstract over *linear* container-like things.
896///
897/// This trait is likely to change in future versions of the crate, so avoid implementing it yourself.
898pub trait OrderedSeq<'p, T>: Seq<'p, T> {}
899
900impl<T: Clone> OrderedSeq<'_, T> for T {}
901impl<'p, T> OrderedSeq<'p, T> for &'p T {}
902impl<'p, T> OrderedSeq<'p, T> for &'p [T] {}
903impl<T: Clone, const N: usize> OrderedSeq<'_, T> for [T; N] {}
904impl<'p, T, const N: usize> OrderedSeq<'p, T> for &'p [T; N] {}
905impl<T: Clone> OrderedSeq<'_, T> for Vec<T> {}
906impl<'p, T> OrderedSeq<'p, T> for Range<T> where Self: Seq<'p, T> {}
907impl<'p, T> OrderedSeq<'p, T> for core::ops::RangeInclusive<T> where Self: Seq<'p, T> {}
908impl<'p, T> OrderedSeq<'p, T> for RangeFrom<T> where Self: Seq<'p, T> {}
909
910impl OrderedSeq<'_, char> for str {}
911impl OrderedSeq<'_, char> for String {}
912impl<'p> OrderedSeq<'p, char> for &'p str {}
913impl<'p> OrderedSeq<'p, &'p Grapheme> for &'p str {}
914impl<'p> OrderedSeq<'p, &'p Grapheme> for &'p Graphemes {}
915
916#[cfg(test)]
917mod test {
918    use super::*;
919
920    fn init_container<C: ContainerExactly<usize>>() -> C {
921        let mut uninit = C::uninit();
922        for idx in 0..C::LEN {
923            C::write(&mut uninit, idx, idx);
924        }
925        // SAFETY: All elements were initialized.
926        unsafe { C::take(uninit) }
927    }
928
929    fn drop_container<C: ContainerExactly<usize>>() {
930        let mut uninit = C::uninit();
931        for idx in 0..(C::LEN / 2) {
932            C::write(&mut uninit, idx, idx);
933        }
934        // SAFETY: All elements up to this point were initialized.
935        unsafe { C::drop_before(&mut uninit, C::LEN / 2) };
936    }
937
938    #[test]
939    fn exact_array() {
940        let c = init_container::<[usize; 4]>();
941        assert_eq!(&c, &[0, 1, 2, 3]);
942        drop_container::<[usize; 4]>();
943    }
944
945    // #[test]
946    // fn exact_rc_array() {
947    //     let c = init_container::<Rc<[usize; 4]>>();
948    //     assert_eq!(&*c, &[0, 1, 2, 3]);
949    //     drop_container::<Rc<[usize; 4]>>();
950    // }
951
952    // #[test]
953    // fn exact_rc_box_array() {
954    //     let c = init_container::<Rc<Box<[usize; 4]>>>();
955    //     assert_eq!(&**c, &[0, 1, 2, 3]);
956    //     drop_container::<Rc<Box<[usize; 4]>>>();
957    // }
958
959    // #[test]
960    // fn exact_box_rc_array() {
961    //     let c = init_container::<Box<Rc<[usize; 4]>>>();
962    //     assert_eq!(&**c, &[0, 1, 2, 3]);
963    //     drop_container::<Box<Rc<[usize; 4]>>>();
964    // }
965}