1use super::{
7 Bounded, Capped, Capping, DuplicateKey, Empty, ForeignRosterReference, KeyedRoster,
8 KeyedRosterAssignment, KeyedRosterAssignmentError, KeyedRosterError, NonEmpty, NonEmptyError,
9 Overflow, UnassignedRosterMember,
10};
11use core::borrow::Borrow;
12
13impl<T, const N: usize> Bounded<T, N> {
14 #[must_use]
16 pub const fn empty() -> Self {
17 Self(Vec::new())
18 }
19
20 pub fn new(items: Vec<T>) -> Result<Self, Overflow> {
26 if items.len() <= N {
27 Ok(Self(items))
28 } else {
29 Err(Overflow {
30 capacity: N,
31 offered: items.len(),
32 })
33 }
34 }
35
36 #[must_use]
38 pub fn from_array<const M: usize>(items: [T; M]) -> Self {
39 const {
40 assert!(
41 M <= N,
42 "a fixed list longer than the ceiling it is declared under"
43 );
44 }
45 Self(Vec::from(items))
46 }
47
48 #[must_use]
50 pub fn as_slice(&self) -> &[T] {
51 self.0.as_slice()
52 }
53
54 pub fn iter(&self) -> impl Iterator<Item = &T> {
56 self.0.iter()
57 }
58
59 #[must_use]
61 pub fn len(&self) -> usize {
62 self.0.len()
63 }
64
65 #[must_use]
67 pub fn is_empty(&self) -> bool {
68 self.0.is_empty()
69 }
70
71 pub(crate) fn into_vec(self) -> Vec<T> {
72 self.0
73 }
74
75 pub(crate) fn mapped<U>(&self, operation: impl FnMut(&T) -> U) -> Bounded<U, N> {
76 Bounded(self.iter().map(operation).collect())
77 }
78
79 pub fn try_push(&mut self, item: T) -> Result<(), Overflow> {
85 let offered = self.0.len().saturating_add(1);
86 if offered > N {
87 return Err(Overflow {
88 capacity: N,
89 offered,
90 });
91 }
92 self.0.push(item);
93 Ok(())
94 }
95}
96
97impl<T, const N: usize> NonEmpty<T, N> {
98 #[must_use]
100 pub const fn one(value: T) -> Self {
101 const {
102 assert!(
103 N >= 1,
104 "a non-empty list under a ceiling that admits no item"
105 );
106 }
107 Self {
108 head: value,
109 tail: Vec::new(),
110 }
111 }
112
113 pub fn new(items: Vec<T>) -> Result<Self, NonEmptyError> {
119 let offered = items.len();
120 let mut rest = items.into_iter();
121 let Some(head) = rest.next() else {
122 return Err(NonEmptyError::Empty(Empty));
123 };
124 if offered <= N {
125 Ok(Self {
126 head,
127 tail: rest.collect(),
128 })
129 } else {
130 Err(NonEmptyError::Overflow(Overflow {
131 capacity: N,
132 offered,
133 }))
134 }
135 }
136
137 pub(crate) fn from_bounded(items: Bounded<T, N>) -> Result<Self, Empty> {
138 let mut items = items.into_vec().into_iter();
139 let Some(head) = items.next() else {
140 return Err(Empty);
141 };
142 Ok(Self {
143 head,
144 tail: items.collect(),
145 })
146 }
147
148 #[must_use]
150 pub const fn first(&self) -> &T {
151 &self.head
152 }
153
154 #[must_use]
156 pub fn split(&self) -> (&T, &[T]) {
157 (&self.head, self.tail.as_slice())
158 }
159
160 pub fn iter(&self) -> impl Iterator<Item = &T> {
162 self.into_iter()
163 }
164
165 #[must_use]
167 pub fn count(&self) -> usize {
168 self.tail.len().saturating_add(1)
169 }
170
171 pub(crate) fn mapped<U>(self, mut operation: impl FnMut(T) -> U) -> NonEmpty<U, N> {
172 NonEmpty {
173 head: operation(self.head),
174 tail: self.tail.into_iter().map(operation).collect(),
175 }
176 }
177}
178
179impl<'held, T, const N: usize> IntoIterator for &'held NonEmpty<T, N> {
180 type Item = &'held T;
181 type IntoIter = core::iter::Chain<core::iter::Once<&'held T>, core::slice::Iter<'held, T>>;
182
183 fn into_iter(self) -> Self::IntoIter {
184 core::iter::once(&self.head).chain(self.tail.iter())
185 }
186}
187
188impl<T, K, const N: usize> KeyedRoster<T, K, N> {
189 #[must_use]
191 pub const fn one(member: T, key: K) -> Self {
192 Self {
193 members: NonEmpty::one(member),
194 keys: NonEmpty::one(key),
195 }
196 }
197
198 #[must_use]
200 pub const fn first(&self) -> &T {
201 self.members.first()
202 }
203
204 #[must_use]
206 pub const fn first_key(&self) -> &K {
207 self.keys.first()
208 }
209
210 #[must_use]
212 pub fn count(&self) -> usize {
213 self.members.count()
214 }
215
216 pub(crate) fn positions_where(
217 &self,
218 mut predicate: impl FnMut(usize, &K, &T) -> bool,
219 ) -> Bounded<usize, N> {
220 Bounded(
221 self.indexed()
222 .filter_map(|(index, key, member)| predicate(index, key, member).then_some(index))
223 .collect(),
224 )
225 }
226
227 pub fn members(&self) -> impl Iterator<Item = &T> {
229 self.members.iter()
230 }
231
232 pub fn keys(&self) -> impl Iterator<Item = &K> {
234 self.keys.iter()
235 }
236
237 pub fn indexed(&self) -> impl Iterator<Item = (usize, &K, &T)> {
239 self.keys()
240 .zip(self.members())
241 .enumerate()
242 .map(|(index, (key, member))| (index, key, member))
243 }
244
245 #[must_use]
247 pub fn at(&self, index: usize) -> Option<(&K, &T)> {
248 self.keys().zip(self.members()).nth(index)
249 }
250
251 #[must_use]
253 pub fn index_of<Q>(&self, sought: &Q) -> Option<usize>
254 where
255 K: Borrow<Q>,
256 Q: Eq + ?Sized,
257 {
258 self.keys().position(|key| key.borrow() == sought)
259 }
260
261 #[must_use]
263 pub fn get<Q>(&self, sought: &Q) -> Option<&T>
264 where
265 K: Borrow<Q>,
266 Q: Eq + ?Sized,
267 {
268 self.keys()
269 .zip(self.members())
270 .find_map(|(key, member)| (key.borrow() == sought).then_some(member))
271 }
272
273 #[must_use]
275 pub fn indexed_get<Q>(&self, sought: &Q) -> Option<(usize, &K, &T)>
276 where
277 K: Borrow<Q>,
278 Q: Eq + ?Sized,
279 {
280 self.indexed()
281 .find(|(_index, key, _member)| (*key).borrow() == sought)
282 }
283}
284
285impl<T, K: Eq, const N: usize> KeyedRoster<T, K, N> {
286 pub fn new(
294 members: Vec<T>,
295 key_of: impl FnMut(&T) -> K,
296 ) -> Result<Self, KeyedRosterError<K, N>> {
297 let members = NonEmpty::new(members).map_err(keyed_magnitude_refusal)?;
298 let keys = project_keys(&members, key_of);
299 match admit_keys(keys) {
300 KeyAdmission::Unique(keys) => Ok(Self { members, keys }),
301 KeyAdmission::Duplicated(duplicates) => {
302 Err(KeyedRosterError::DuplicateKeys(duplicates))
303 }
304 }
305 }
306}
307
308impl<K: Eq, const N: usize> NonEmpty<K, N> {
309 pub(crate) fn duplicate_keys(self) -> Option<NonEmpty<DuplicateKey<K, N>, N>> {
310 match admit_keys(self) {
311 KeyAdmission::Unique(_) => None,
312 KeyAdmission::Duplicated(duplicates) => Some(duplicates),
313 }
314 }
315}
316
317impl<K, const N: usize> DuplicateKey<K, N> {
318 #[must_use]
320 pub const fn key(&self) -> &K {
321 &self.key
322 }
323
324 #[must_use]
326 pub const fn first_position(&self) -> usize {
327 self.first
328 }
329
330 #[must_use]
332 pub const fn repeated_positions(&self) -> &NonEmpty<usize, N> {
333 &self.repeated
334 }
335}
336
337pub(crate) fn first_duplicate_position<T>(
338 items: &[T],
339 equivalent: impl Fn(&T, &T) -> bool,
340) -> Option<usize> {
341 items.iter().enumerate().find_map(|(position, item)| {
342 items
343 .iter()
344 .take(position)
345 .any(|earlier| equivalent(earlier, item))
346 .then_some(position)
347 })
348}
349
350fn keyed_magnitude_refusal<K, const N: usize>(error: NonEmptyError) -> KeyedRosterError<K, N> {
351 match error {
352 NonEmptyError::Empty(empty) => KeyedRosterError::Empty(empty),
353 NonEmptyError::Overflow(overflow) => KeyedRosterError::Overflow(overflow),
354 }
355}
356
357fn project_keys<T, K, const N: usize>(
358 members: &NonEmpty<T, N>,
359 mut key_of: impl FnMut(&T) -> K,
360) -> NonEmpty<K, N> {
361 let (head, tail) = members.split();
362 NonEmpty {
363 head: key_of(head),
364 tail: tail.iter().map(key_of).collect(),
365 }
366}
367
368fn admit_keys<K: Eq, const N: usize>(keys: NonEmpty<K, N>) -> KeyAdmission<K, N> {
369 let NonEmpty { head, tail } = keys;
370 let mut groups = KeyGroups {
371 head: KeyGroup {
372 key: head,
373 first: 0,
374 repeated: Vec::new(),
375 },
376 tail: Vec::new(),
377 };
378 for (index, key) in tail.into_iter().enumerate() {
379 groups.insert(key, index.saturating_add(1));
380 }
381 groups.admit()
382}
383
384struct KeyGroup<K> {
385 key: K,
386 first: usize,
387 repeated: Vec<usize>,
388}
389
390struct KeyGroups<K> {
391 head: KeyGroup<K>,
392 tail: Vec<KeyGroup<K>>,
393}
394
395enum KeyAdmission<K, const N: usize> {
396 Unique(NonEmpty<K, N>),
397 Duplicated(NonEmpty<DuplicateKey<K, N>, N>),
398}
399
400impl<K: Eq> KeyGroups<K> {
401 fn insert(&mut self, key: K, index: usize) {
402 if self.head.key == key {
403 self.head.repeated.push(index);
404 return;
405 }
406 if let Some(group) = self.tail.iter_mut().find(|group| group.key == key) {
407 group.repeated.push(index);
408 return;
409 }
410 self.tail.push(KeyGroup {
411 key,
412 first: index,
413 repeated: Vec::new(),
414 });
415 }
416
417 fn admit<const N: usize>(self) -> KeyAdmission<K, N> {
418 let mut tail = self.tail.into_iter();
419 let head = match admitted_group(self.head) {
420 Ok(key) => key,
421 Err(duplicate) => {
422 return KeyAdmission::Duplicated(NonEmpty {
423 head: duplicate,
424 tail: tail
425 .filter_map(|group| admitted_group(group).err())
426 .collect(),
427 });
428 }
429 };
430 let mut unique = Vec::new();
431 while let Some(group) = tail.next() {
432 match admitted_group(group) {
433 Ok(key) => unique.push(key),
434 Err(duplicate) => {
435 return KeyAdmission::Duplicated(NonEmpty {
436 head: duplicate,
437 tail: tail
438 .filter_map(|remaining| admitted_group(remaining).err())
439 .collect(),
440 });
441 }
442 }
443 }
444 KeyAdmission::Unique(NonEmpty { head, tail: unique })
445 }
446}
447
448fn admitted_group<K, const N: usize>(group: KeyGroup<K>) -> Result<K, DuplicateKey<K, N>> {
449 let KeyGroup {
450 key,
451 first,
452 repeated,
453 } = group;
454 let mut repeated = repeated.into_iter();
455 if let Some(repeated_head) = repeated.next() {
456 return Err(DuplicateKey {
457 key,
458 first,
459 repeated: NonEmpty {
460 head: repeated_head,
461 tail: repeated.collect(),
462 },
463 });
464 }
465 Ok(key)
466}
467
468impl<D, K, P, S, const N: usize> KeyedRosterAssignment<D, K, P, S, N> {
469 #[must_use]
471 pub const fn denominator(&self) -> &KeyedRoster<D, K, N> {
472 &self.denominator
473 }
474
475 #[must_use]
477 pub const fn payloads(&self) -> &KeyedRoster<P, S, N> {
478 &self.payloads
479 }
480
481 #[must_use]
483 pub fn count(&self) -> usize {
484 self.denominator.count()
485 }
486
487 #[must_use]
489 pub const fn first(&self) -> (&K, &D, &S, &P) {
490 (
491 self.denominator.first_key(),
492 self.denominator.first(),
493 self.payloads.first_key(),
494 self.payloads.first(),
495 )
496 }
497
498 pub fn indexed(&self) -> impl Iterator<Item = (usize, &K, &D, &S, &P)> {
500 self.denominator
501 .indexed()
502 .zip(self.payloads.keys().zip(self.payloads.members()))
503 .map(|((index, key, member), (seat, payload))| (index, key, member, seat, payload))
504 }
505
506 #[must_use]
508 pub fn at(&self, index: usize) -> Option<(&K, &D, &S, &P)> {
509 self.denominator
510 .at(index)
511 .zip(self.payloads.at(index))
512 .map(|((key, member), (seat, payload))| (key, member, seat, payload))
513 }
514
515 #[must_use]
517 pub fn get<Q>(&self, sought: &Q) -> Option<(&D, &S, &P)>
518 where
519 K: Borrow<Q>,
520 Q: Eq + ?Sized,
521 {
522 let index = self.denominator.index_of(sought)?;
523 self.at(index)
524 .map(|(_key, member, seat, payload)| (member, seat, payload))
525 }
526}
527
528impl<D, K: Eq, P, S: Eq, const N: usize> KeyedRosterAssignment<D, K, P, S, N> {
529 pub fn complete(
538 denominator: KeyedRoster<D, K, N>,
539 payloads: Vec<P>,
540 reference_of: impl FnMut(&P) -> K,
541 seat_of: impl FnMut(&P) -> S,
542 ) -> Result<Self, KeyedRosterAssignmentError<K, S, N>> {
543 let payloads = NonEmpty::new(payloads).map_err(assignment_magnitude_refusal::<K, S, N>)?;
544 let references = project_keys(&payloads, reference_of);
545 let (references, positions) = match admit_references(&denominator, references) {
546 ReferenceAdmission::Lawful { keys, positions } => (keys, positions),
547 ReferenceAdmission::Foreign(foreign) => {
548 return Err(KeyedRosterAssignmentError::ForeignReferences(foreign));
549 }
550 };
551 if let KeyAdmission::Duplicated(duplicates) = admit_keys(references) {
552 return Err(KeyedRosterAssignmentError::DuplicateReferences(duplicates));
553 }
554 let seats = project_keys(&payloads, seat_of);
555 let seats = match admit_keys(seats) {
556 KeyAdmission::Unique(seats) => seats,
557 KeyAdmission::Duplicated(duplicates) => {
558 return Err(KeyedRosterAssignmentError::ReusedPayloadSeats(duplicates));
559 }
560 };
561 let denominator = match settle_completeness(denominator, &positions) {
562 AssignmentCompleteness::Complete(denominator) => denominator,
563 AssignmentCompleteness::Missing(missing) => {
564 return Err(KeyedRosterAssignmentError::MissingMembers(missing));
565 }
566 };
567 let payloads = align_payloads(payloads, seats, positions);
568 Ok(Self {
569 denominator,
570 payloads,
571 })
572 }
573}
574
575impl<K> ForeignRosterReference<K> {
576 pub(crate) const fn at(key: K, offered_position: usize) -> Self {
577 Self {
578 key,
579 offered_position,
580 }
581 }
582
583 #[must_use]
585 pub const fn key(&self) -> &K {
586 &self.key
587 }
588
589 #[must_use]
591 pub const fn offered_position(&self) -> usize {
592 self.offered_position
593 }
594}
595
596impl<K> UnassignedRosterMember<K> {
597 #[must_use]
599 pub const fn key(&self) -> &K {
600 &self.key
601 }
602
603 #[must_use]
605 pub const fn denominator_position(&self) -> usize {
606 self.denominator_position
607 }
608}
609
610enum ReferenceAdmission<K, const N: usize> {
611 Lawful {
612 keys: NonEmpty<K, N>,
613 positions: NonEmpty<usize, N>,
614 },
615 Foreign(NonEmpty<ForeignRosterReference<K>, N>),
616}
617
618fn admit_references<D, K: Eq, const N: usize>(
619 denominator: &KeyedRoster<D, K, N>,
620 references: NonEmpty<K, N>,
621) -> ReferenceAdmission<K, N> {
622 let NonEmpty { head, tail } = references;
623 let Some(head_position) = denominator.index_of(&head) else {
624 let foreign_tail = tail
625 .into_iter()
626 .enumerate()
627 .filter_map(|(offset, key)| {
628 denominator
629 .index_of(&key)
630 .is_none()
631 .then_some(ForeignRosterReference {
632 key,
633 offered_position: offset.saturating_add(1),
634 })
635 })
636 .collect();
637 return ReferenceAdmission::Foreign(NonEmpty {
638 head: ForeignRosterReference {
639 key: head,
640 offered_position: 0,
641 },
642 tail: foreign_tail,
643 });
644 };
645 admit_references_after_lawful_head(denominator, head, head_position, tail)
646}
647
648fn admit_references_after_lawful_head<D, K: Eq, const N: usize>(
649 denominator: &KeyedRoster<D, K, N>,
650 head: K,
651 head_position: usize,
652 tail: Vec<K>,
653) -> ReferenceAdmission<K, N> {
654 let mut lawful_keys = Vec::new();
655 let mut lawful_positions = Vec::new();
656 let mut foreign_head = None;
657 let mut foreign_tail = Vec::new();
658 for (offset, key) in tail.into_iter().enumerate() {
659 let offered_position = offset.saturating_add(1);
660 if let Some(position) = denominator.index_of(&key) {
661 lawful_keys.push(key);
662 lawful_positions.push(position);
663 } else {
664 let foreign = ForeignRosterReference {
665 key,
666 offered_position,
667 };
668 if foreign_head.is_none() {
669 foreign_head = Some(foreign);
670 } else {
671 foreign_tail.push(foreign);
672 }
673 }
674 }
675 if let Some(foreign) = foreign_head {
676 ReferenceAdmission::Foreign(NonEmpty {
677 head: foreign,
678 tail: foreign_tail,
679 })
680 } else {
681 ReferenceAdmission::Lawful {
682 keys: NonEmpty {
683 head,
684 tail: lawful_keys,
685 },
686 positions: NonEmpty {
687 head: head_position,
688 tail: lawful_positions,
689 },
690 }
691 }
692}
693
694enum AssignmentCompleteness<D, K, const N: usize> {
695 Complete(KeyedRoster<D, K, N>),
696 Missing(NonEmpty<UnassignedRosterMember<K>, N>),
697}
698
699enum KeyCompleteness<K, const N: usize> {
700 Complete(NonEmpty<K, N>),
701 Missing(NonEmpty<UnassignedRosterMember<K>, N>),
702}
703
704enum AssignmentStanding {
705 Assigned,
706 Missing,
707}
708
709fn settle_completeness<D, K, const N: usize>(
710 denominator: KeyedRoster<D, K, N>,
711 positions: &NonEmpty<usize, N>,
712) -> AssignmentCompleteness<D, K, N> {
713 let KeyedRoster { members, keys } = denominator;
714 let NonEmpty { head, tail } = keys;
715 let first_assigned = positions.iter().any(|position| *position == 0);
716 let mut completeness = if first_assigned {
717 KeyCompleteness::Complete(NonEmpty {
718 head,
719 tail: Vec::new(),
720 })
721 } else {
722 KeyCompleteness::Missing(NonEmpty {
723 head: UnassignedRosterMember {
724 key: head,
725 denominator_position: 0,
726 },
727 tail: Vec::new(),
728 })
729 };
730 for (offset, key) in tail.into_iter().enumerate() {
731 let denominator_position = offset.saturating_add(1);
732 let standing = if positions
733 .iter()
734 .any(|position| *position == denominator_position)
735 {
736 AssignmentStanding::Assigned
737 } else {
738 AssignmentStanding::Missing
739 };
740 completeness = completeness.push(key, denominator_position, standing);
741 }
742 match completeness {
743 KeyCompleteness::Complete(complete_keys) => AssignmentCompleteness::Complete(KeyedRoster {
744 members,
745 keys: complete_keys,
746 }),
747 KeyCompleteness::Missing(missing) => AssignmentCompleteness::Missing(missing),
748 }
749}
750
751impl<K, const N: usize> KeyCompleteness<K, N> {
752 fn push(self, key: K, denominator_position: usize, standing: AssignmentStanding) -> Self {
753 match (self, standing) {
754 (Self::Complete(mut keys), AssignmentStanding::Assigned) => {
755 keys.tail.push(key);
756 Self::Complete(keys)
757 }
758 (Self::Complete(_keys), AssignmentStanding::Missing) => Self::Missing(NonEmpty {
759 head: UnassignedRosterMember {
760 key,
761 denominator_position,
762 },
763 tail: Vec::new(),
764 }),
765 (Self::Missing(missing), AssignmentStanding::Assigned) => Self::Missing(missing),
766 (Self::Missing(mut missing), AssignmentStanding::Missing) => {
767 missing.tail.push(UnassignedRosterMember {
768 key,
769 denominator_position,
770 });
771 Self::Missing(missing)
772 }
773 }
774 }
775}
776
777struct PendingAssignment<P, S> {
778 denominator_position: usize,
779 payload: P,
780 seat: S,
781}
782
783fn align_payloads<P, S, const N: usize>(
784 payloads: NonEmpty<P, N>,
785 seats: NonEmpty<S, N>,
786 positions: NonEmpty<usize, N>,
787) -> KeyedRoster<P, S, N> {
788 let NonEmpty {
789 head: payload_head,
790 tail: payload_tail,
791 } = payloads;
792 let NonEmpty {
793 head: seat_head,
794 tail: seat_tail,
795 } = seats;
796 let NonEmpty {
797 head: position_head,
798 tail: position_tail,
799 } = positions;
800 let mut head = PendingAssignment {
801 denominator_position: position_head,
802 payload: payload_head,
803 seat: seat_head,
804 };
805 let mut tail = position_tail
806 .into_iter()
807 .zip(payload_tail)
808 .zip(seat_tail)
809 .map(
810 |((denominator_position, payload), seat)| PendingAssignment {
811 denominator_position,
812 payload,
813 seat,
814 },
815 )
816 .collect::<Vec<_>>();
817 for assignment in &mut tail {
818 if assignment.denominator_position < head.denominator_position {
819 core::mem::swap(&mut head, assignment);
820 }
821 }
822 tail.sort_by_key(|assignment| assignment.denominator_position);
823 let mut ordered_payload_tail = Vec::with_capacity(tail.len());
824 let mut ordered_seat_tail = Vec::with_capacity(tail.len());
825 for assignment in tail {
826 ordered_payload_tail.push(assignment.payload);
827 ordered_seat_tail.push(assignment.seat);
828 }
829 KeyedRoster {
830 members: NonEmpty {
831 head: head.payload,
832 tail: ordered_payload_tail,
833 },
834 keys: NonEmpty {
835 head: head.seat,
836 tail: ordered_seat_tail,
837 },
838 }
839}
840
841fn assignment_magnitude_refusal<K, S, const N: usize>(
842 error: NonEmptyError,
843) -> KeyedRosterAssignmentError<K, S, N> {
844 match error {
845 NonEmptyError::Empty(empty) => KeyedRosterAssignmentError::Empty(empty),
846 NonEmptyError::Overflow(overflow) => KeyedRosterAssignmentError::Overflow(overflow),
847 }
848}
849
850impl<T, const N: usize> Capped<T, N> {
851 #[must_use]
853 pub const fn all(items: NonEmpty<T, N>) -> Self {
854 Self {
855 items,
856 capping: Capping::Complete,
857 }
858 }
859
860 #[must_use]
862 pub fn first_n(first: T, rest: impl Iterator<Item = T>) -> Self {
863 const {
864 assert!(N >= 1, "a capped list under a ceiling that admits no item");
865 }
866 let mut tail = Vec::new();
867 let mut omitted = 0_usize;
868 for item in rest {
869 if tail.len() < N.saturating_sub(1) {
870 tail.push(item);
871 } else {
872 omitted = omitted.saturating_add(1);
873 }
874 }
875 Self {
876 items: NonEmpty { head: first, tail },
877 capping: capping_over(omitted),
878 }
879 }
880
881 #[must_use]
883 pub const fn items(&self) -> &NonEmpty<T, N> {
884 &self.items
885 }
886
887 #[must_use]
889 pub const fn capping(&self) -> Capping {
890 self.capping
891 }
892}
893
894const fn capping_over(omitted: usize) -> Capping {
896 if omitted == 0 {
897 Capping::Complete
898 } else {
899 Capping::Truncated { omitted }
900 }
901}