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    #[doc(hidden)]
311    #[cfg(feature = "debug")]
312    fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
313        let ty = core::any::type_name::<Self>();
314        debug::SeqInfo::Unknown(ty.split_once('<').map_or(ty, |(ty, _)| ty).to_string())
315    }
316}
317
318impl<'p, T: Clone> Seq<'p, T> for T {
319    type Item<'a>
320        = &'a T
321    where
322        Self: 'a;
323
324    type Iter<'a>
325        = core::iter::Once<&'a T>
326    where
327        Self: 'a;
328
329    #[inline(always)]
330    fn seq_iter(&self) -> Self::Iter<'_> {
331        core::iter::once(self)
332    }
333
334    #[inline(always)]
335    fn contains(&self, val: &T) -> bool
336    where
337        T: PartialEq,
338    {
339        self == val
340    }
341
342    #[inline]
343    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
344    where
345        'p: 'b,
346    {
347        MaybeRef::Val(item.clone())
348    }
349
350    #[doc(hidden)]
351    #[cfg(feature = "debug")]
352    default fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
353        let ty = core::any::type_name::<Self>();
354        debug::SeqInfo::Unknown(ty.split_once('<').map_or(ty, |(ty, _)| ty).to_string())
355    }
356}
357
358#[doc(hidden)]
359#[cfg(feature = "debug")]
360impl<'p, T: Clone + core::fmt::Debug> Seq<'p, T> for T {
361    default fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
362        debug::SeqInfo::Opaque(format!("{self:?}"))
363    }
364}
365
366#[doc(hidden)]
367#[cfg(feature = "debug")]
368impl Seq<'_, char> for char {
369    fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
370        debug::SeqInfo::Char(*self)
371    }
372}
373
374impl<'p, T> Seq<'p, T> for &'p T {
375    type Item<'a>
376        = &'p T
377    where
378        Self: 'a;
379
380    type Iter<'a>
381        = core::iter::Once<&'p T>
382    where
383        Self: 'a;
384
385    #[inline(always)]
386    fn seq_iter(&self) -> Self::Iter<'_> {
387        core::iter::once(*self)
388    }
389
390    #[inline(always)]
391    fn contains(&self, val: &T) -> bool
392    where
393        T: PartialEq,
394    {
395        *self == val
396    }
397
398    #[inline]
399    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
400    where
401        'p: 'b,
402    {
403        MaybeRef::Ref(item)
404    }
405}
406
407impl<'p, T> Seq<'p, T> for &'p [T] {
408    type Item<'a>
409        = &'p T
410    where
411        Self: 'a;
412
413    type Iter<'a>
414        = core::slice::Iter<'p, T>
415    where
416        Self: 'a;
417
418    #[inline(always)]
419    fn seq_iter(&self) -> Self::Iter<'_> {
420        (self as &[T]).iter()
421    }
422
423    #[inline(always)]
424    fn contains(&self, val: &T) -> bool
425    where
426        T: PartialEq,
427    {
428        <[T]>::contains(self, val)
429    }
430
431    #[inline]
432    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
433    where
434        'p: 'b,
435    {
436        MaybeRef::Ref(item)
437    }
438}
439
440impl<'p, T: Clone, const N: usize> Seq<'p, T> for [T; N] {
441    type Item<'a>
442        = &'a T
443    where
444        Self: 'a;
445
446    type Iter<'a>
447        = core::slice::Iter<'a, T>
448    where
449        Self: 'a;
450
451    #[inline(always)]
452    fn seq_iter(&self) -> Self::Iter<'_> {
453        self.iter()
454    }
455
456    #[inline(always)]
457    fn contains(&self, val: &T) -> bool
458    where
459        T: PartialEq,
460    {
461        <[T]>::contains(self, val)
462    }
463
464    #[inline]
465    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
466    where
467        'p: 'b,
468    {
469        MaybeRef::Val(item.clone())
470    }
471}
472
473impl<'p, T, const N: usize> Seq<'p, T> for &'p [T; N] {
474    type Item<'a>
475        = &'p T
476    where
477        Self: 'a;
478
479    type Iter<'a>
480        = core::slice::Iter<'p, T>
481    where
482        Self: 'a;
483
484    #[inline(always)]
485    fn seq_iter(&self) -> Self::Iter<'_> {
486        self.iter()
487    }
488
489    #[inline(always)]
490    fn contains(&self, val: &T) -> bool
491    where
492        T: PartialEq,
493    {
494        #[allow(clippy::explicit_auto_deref)] // FIXME: Clippy bug #9841
495        <[T]>::contains(*self, val)
496    }
497
498    #[inline]
499    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
500    where
501        'p: 'b,
502    {
503        MaybeRef::Ref(item)
504    }
505}
506
507impl<'p, T: Clone> Seq<'p, T> for Vec<T> {
508    type Item<'a>
509        = &'a T
510    where
511        Self: 'a;
512
513    type Iter<'a>
514        = core::slice::Iter<'a, T>
515    where
516        Self: 'a;
517
518    #[inline(always)]
519    fn seq_iter(&self) -> Self::Iter<'_> {
520        self.iter()
521    }
522
523    #[inline(always)]
524    fn contains(&self, val: &T) -> bool
525    where
526        T: PartialEq,
527    {
528        <[T]>::contains(self, val)
529    }
530
531    #[inline]
532    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
533    where
534        'p: 'b,
535    {
536        MaybeRef::Val(item.clone())
537    }
538}
539
540impl<'p, T: Clone> Seq<'p, T> for LinkedList<T> {
541    type Item<'a>
542        = &'a T
543    where
544        Self: 'a;
545
546    type Iter<'a>
547        = alloc::collections::linked_list::Iter<'a, T>
548    where
549        Self: 'a;
550
551    #[inline(always)]
552    fn seq_iter(&self) -> Self::Iter<'_> {
553        self.iter()
554    }
555
556    #[inline(always)]
557    fn contains(&self, val: &T) -> bool
558    where
559        T: PartialEq,
560    {
561        LinkedList::contains(self, val)
562    }
563
564    #[inline]
565    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
566    where
567        'p: 'b,
568    {
569        MaybeRef::Val(item.clone())
570    }
571}
572
573impl<'p, T: Clone + Eq + Hash> Seq<'p, T> for HashSet<T> {
574    type Item<'a>
575        = &'a T
576    where
577        Self: 'a;
578
579    type Iter<'a>
580        = hashbrown::hash_set::Iter<'a, T>
581    where
582        Self: 'a;
583
584    #[inline(always)]
585    fn seq_iter(&self) -> Self::Iter<'_> {
586        self.iter()
587    }
588
589    #[inline(always)]
590    fn contains(&self, val: &T) -> bool
591    where
592        T: PartialEq,
593    {
594        HashSet::contains(self, val)
595    }
596
597    #[inline]
598    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
599    where
600        'p: 'b,
601    {
602        MaybeRef::Val(item.clone())
603    }
604}
605
606#[cfg(feature = "std")]
607impl<'p, T: Clone + Eq + Hash> Seq<'p, T> for std::collections::HashSet<T> {
608    type Item<'a>
609        = &'a T
610    where
611        Self: 'a;
612
613    type Iter<'a>
614        = std::collections::hash_set::Iter<'a, T>
615    where
616        Self: 'a;
617
618    #[inline(always)]
619    fn seq_iter(&self) -> Self::Iter<'_> {
620        self.iter()
621    }
622
623    #[inline(always)]
624    fn contains(&self, val: &T) -> bool
625    where
626        T: PartialEq,
627    {
628        self.contains(val)
629    }
630
631    #[inline]
632    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
633    where
634        'p: 'b,
635    {
636        MaybeRef::Val(item.clone())
637    }
638}
639
640impl<'p, T: Clone + Ord> Seq<'p, T> for alloc::collections::BTreeSet<T> {
641    type Item<'a>
642        = &'a T
643    where
644        Self: 'a;
645
646    type Iter<'a>
647        = alloc::collections::btree_set::Iter<'a, T>
648    where
649        Self: 'a;
650
651    #[inline(always)]
652    fn seq_iter(&self) -> Self::Iter<'_> {
653        self.iter()
654    }
655
656    #[inline(always)]
657    fn contains(&self, val: &T) -> bool
658    where
659        T: PartialEq,
660    {
661        self.contains(val)
662    }
663
664    #[inline]
665    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
666    where
667        'p: 'b,
668    {
669        MaybeRef::Val(item.clone())
670    }
671}
672
673impl<'p, T> Seq<'p, T> for Range<T>
674where
675    T: Clone + PartialOrd, // Explicit declaration of an implied truth - `Step` requires these
676    Self: Iterator<Item = T>,
677{
678    type Item<'a>
679        = T
680    where
681        Self: 'a;
682
683    type Iter<'a>
684        = Range<T>
685    where
686        Self: 'a;
687
688    #[inline(always)]
689    fn seq_iter(&self) -> Self::Iter<'_> {
690        (*self).clone()
691    }
692
693    #[inline(always)]
694    fn contains(&self, val: &T) -> bool {
695        Range::contains(self, val)
696    }
697
698    #[inline]
699    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
700    where
701        'p: 'b,
702    {
703        MaybeRef::Val(item)
704    }
705}
706
707impl<'p, T> Seq<'p, T> for core::ops::RangeInclusive<T>
708where
709    T: Clone + PartialOrd,
710    Self: Iterator<Item = T>,
711{
712    type Item<'a>
713        = T
714    where
715        Self: 'a;
716
717    type Iter<'a>
718        = core::ops::RangeInclusive<T>
719    where
720        Self: 'a;
721
722    #[inline(always)]
723    fn seq_iter(&self) -> Self::Iter<'_> {
724        self.clone()
725    }
726
727    #[inline(always)]
728    fn contains(&self, val: &T) -> bool {
729        core::ops::RangeInclusive::contains(self, val)
730    }
731
732    #[inline]
733    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
734    where
735        'p: 'b,
736    {
737        MaybeRef::Val(item)
738    }
739}
740
741impl<'p, T> Seq<'p, T> for RangeFrom<T>
742where
743    T: Clone + PartialOrd,
744    Self: Iterator<Item = T>,
745{
746    type Item<'a>
747        = T
748    where
749        Self: 'a;
750
751    type Iter<'a>
752        = RangeFrom<T>
753    where
754        Self: 'a;
755
756    #[inline(always)]
757    fn seq_iter(&self) -> Self::Iter<'_> {
758        self.clone()
759    }
760
761    #[inline(always)]
762    fn contains(&self, val: &T) -> bool {
763        RangeFrom::contains(self, val)
764    }
765
766    #[inline]
767    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, T>
768    where
769        'p: 'b,
770    {
771        MaybeRef::Val(item)
772    }
773}
774
775impl<'p> Seq<'p, char> for str {
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        self.contains(*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 String {
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, char> for &'p str {
836    type Item<'a>
837        = char
838    where
839        Self: 'a;
840
841    type Iter<'a>
842        = core::str::Chars<'a>
843    where
844        Self: 'a;
845
846    #[inline(always)]
847    fn seq_iter(&self) -> Self::Iter<'_> {
848        self.chars()
849    }
850
851    #[inline(always)]
852    fn contains(&self, val: &char) -> bool {
853        str::contains(self, *val)
854    }
855
856    #[inline]
857    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, char>
858    where
859        'p: 'b,
860    {
861        MaybeRef::Val(item)
862    }
863
864    #[doc(hidden)]
865    #[cfg(feature = "debug")]
866    fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
867        debug::SeqInfo::String(self.to_string())
868    }
869}
870
871impl<'p> Seq<'p, &'p Grapheme> for &'p str {
872    type Item<'a>
873        = &'p Grapheme
874    where
875        Self: 'a;
876
877    type Iter<'a>
878        = GraphemesIter<'p>
879    where
880        Self: 'a;
881
882    #[inline(always)]
883    fn seq_iter(&self) -> Self::Iter<'_> {
884        Graphemes::new(self).iter()
885    }
886
887    #[inline(always)]
888    fn contains(&self, val: &&'p Grapheme) -> bool {
889        Graphemes::new(self).contains(val)
890    }
891
892    #[inline]
893    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, &'p Grapheme>
894    where
895        'p: 'b,
896    {
897        MaybeRef::Val(item)
898    }
899
900    #[doc(hidden)]
901    #[cfg(feature = "debug")]
902    fn seq_info(&self, _scope: &mut debug::NodeScope) -> debug::SeqInfo {
903        debug::SeqInfo::String(self.to_string())
904    }
905}
906
907impl<'p> Seq<'p, &'p Grapheme> for &'p Graphemes {
908    type Item<'a>
909        = &'p Grapheme
910    where
911        Self: 'a;
912
913    type Iter<'a>
914        = GraphemesIter<'p>
915    where
916        Self: 'a;
917
918    #[inline(always)]
919    fn seq_iter(&self) -> Self::Iter<'_> {
920        self.iter()
921    }
922
923    #[inline(always)]
924    fn contains(&self, val: &&'p Grapheme) -> bool {
925        self.iter().any(|i| i == *val)
926    }
927
928    #[inline]
929    fn to_maybe_ref<'b>(item: Self::Item<'b>) -> MaybeRef<'p, &'p Grapheme>
930    where
931        'p: 'b,
932    {
933        MaybeRef::Val(item)
934    }
935}
936
937/// A utility trait to abstract over *linear* container-like things.
938///
939/// This trait is likely to change in future versions of the crate, so avoid implementing it yourself.
940pub trait OrderedSeq<'p, T>: Seq<'p, T> {}
941
942impl<T: Clone> OrderedSeq<'_, T> for T {}
943
944impl<'p, T> OrderedSeq<'p, T> for &'p T {}
945impl<'p, T> OrderedSeq<'p, T> for &'p [T] {}
946impl<T: Clone, const N: usize> OrderedSeq<'_, T> for [T; N] {}
947impl<'p, T, const N: usize> OrderedSeq<'p, T> for &'p [T; N] {}
948impl<T: Clone> OrderedSeq<'_, T> for Vec<T> {}
949impl<'p, T> OrderedSeq<'p, T> for Range<T> where Self: Seq<'p, T> {}
950impl<'p, T> OrderedSeq<'p, T> for core::ops::RangeInclusive<T> where Self: Seq<'p, T> {}
951impl<'p, T> OrderedSeq<'p, T> for RangeFrom<T> where Self: Seq<'p, T> {}
952
953impl OrderedSeq<'_, char> for str {}
954impl OrderedSeq<'_, char> for String {}
955impl<'p> OrderedSeq<'p, char> for &'p str {}
956impl<'p> OrderedSeq<'p, &'p Grapheme> for &'p str {}
957impl<'p> OrderedSeq<'p, &'p Grapheme> for &'p Graphemes {}
958
959#[cfg(test)]
960mod test {
961    use super::*;
962
963    fn init_container<C: ContainerExactly<usize>>() -> C {
964        let mut uninit = C::uninit();
965        for idx in 0..C::LEN {
966            C::write(&mut uninit, idx, idx);
967        }
968        // SAFETY: All elements were initialized.
969        unsafe { C::take(uninit) }
970    }
971
972    fn drop_container<C: ContainerExactly<usize>>() {
973        let mut uninit = C::uninit();
974        for idx in 0..(C::LEN / 2) {
975            C::write(&mut uninit, idx, idx);
976        }
977        // SAFETY: All elements up to this point were initialized.
978        unsafe { C::drop_before(&mut uninit, C::LEN / 2) };
979    }
980
981    #[test]
982    fn exact_array() {
983        let c = init_container::<[usize; 4]>();
984        assert_eq!(&c, &[0, 1, 2, 3]);
985        drop_container::<[usize; 4]>();
986    }
987
988    // #[test]
989    // fn exact_rc_array() {
990    //     let c = init_container::<Rc<[usize; 4]>>();
991    //     assert_eq!(&*c, &[0, 1, 2, 3]);
992    //     drop_container::<Rc<[usize; 4]>>();
993    // }
994
995    // #[test]
996    // fn exact_rc_box_array() {
997    //     let c = init_container::<Rc<Box<[usize; 4]>>>();
998    //     assert_eq!(&**c, &[0, 1, 2, 3]);
999    //     drop_container::<Rc<Box<[usize; 4]>>>();
1000    // }
1001
1002    // #[test]
1003    // fn exact_box_rc_array() {
1004    //     let c = init_container::<Box<Rc<[usize; 4]>>>();
1005    //     assert_eq!(&**c, &[0, 1, 2, 3]);
1006    //     drop_container::<Box<Rc<[usize; 4]>>>();
1007    // }
1008}