1use std::ops::RangeBounds;
2
3fn usize_range_len<R>(range: &R, end_excl: usize) -> usize
4where
5 R: RangeBounds<usize>,
6{
7 let start = match range.start_bound() {
8 std::ops::Bound::Included(a) => *a,
9 std::ops::Bound::Excluded(_) => unreachable!(
10 "right? a..=b but there's no a=..b; \
11 could one construct this programmatically, though?"
12 ),
13 std::ops::Bound::Unbounded => 0,
14 };
15 match range.end_bound() {
16 std::ops::Bound::Included(e_incl) => {
17 e_incl
19 .checked_sub(start)
20 .expect("end must be >= start")
21 .checked_add(1)
22 .expect("range end must be < usize::max()")
23 }
24 std::ops::Bound::Excluded(e_excl) => {
25 e_excl.checked_sub(start).expect("end must be >= start")
27 }
28 std::ops::Bound::Unbounded => {
29 end_excl.checked_sub(start).expect("end must be >= start")
31 }
32 }
33}
34
35#[cfg(test)]
36fn identity<T>(v: T) -> T {
37 v
38}
39
40#[cfg(test)]
41#[test]
42fn t_usize_range_len() {
43 assert_eq!(usize_range_len(&identity(1..4), 10), 3);
44 assert_eq!(usize_range_len(&identity(1..=4), 10), 4);
45 assert_eq!(usize_range_len(&identity(1..), 10), 9);
46 assert_eq!(usize_range_len(&identity(..), 10), 10);
47 assert_eq!(usize_range_len(&identity(..4), 10), 4);
48 assert_eq!(usize_range_len(&identity(..=4), 10), 5);
49 assert_eq!(usize_range_len(&identity(4..4), 10), 0);
50 assert_eq!(usize_range_len(&identity(4..=4), 10), 1);
51 assert_eq!(usize_range_len(&identity(..4), 2), 4);
53}
54#[test]
55#[should_panic]
56fn t_usize_range_len_invalid_start() {
57 usize_range_len(&identity(5..4), 2);
58}
59#[test]
60#[should_panic]
61fn t_usize_range_len_invalid_start_2() {
62 usize_range_len(&identity(5..=4), 2);
63}
64#[test]
65#[should_panic]
66fn t_usize_range_len_invalid_start_indirect() {
67 usize_range_len(&identity(5..), 2);
68}
69
70pub trait MoreVec<T> {
71 fn push_within_capacity_(&mut self, value: T) -> Result<(), T>;
73
74 fn extend_from_within_within_capacity<R>(&mut self, src: R) -> Result<(), ()>
77 where
78 R: RangeBounds<usize>,
79 T: Clone;
80}
81
82impl<T> MoreVec<T> for Vec<T> {
83 fn push_within_capacity_(&mut self, value: T) -> Result<(), T> {
84 if self.len() < self.capacity() {
85 self.push(value);
86 Ok(())
87 } else {
88 Err(value)
89 }
90 }
91
92 fn extend_from_within_within_capacity<R>(&mut self, src: R) -> Result<(), ()>
93 where
94 R: RangeBounds<usize>,
95 T: Clone,
96 {
97 let len = self.len();
98 let additional_len = usize_range_len(&src, len);
99 let newlen = len + additional_len;
100 if newlen > self.capacity() {
101 return Err(());
102 }
103 self.extend_from_within(src);
104 Ok(())
105 }
106}
107
108#[cfg(test)]
109#[test]
110fn t_within_capacity() {
111 let mut v = Vec::with_capacity(5);
112 v.push_within_capacity_(9).unwrap();
113 v.push_within_capacity_(7).unwrap();
114 v.push_within_capacity_(1).unwrap();
115
116 assert!(v.extend_from_within_within_capacity(0..3).is_err());
117 assert!(v.extend_from_within_within_capacity(1..3).is_ok());
118 assert_eq!(v.as_slice(), &[9, 7, 1, 7, 1]);
119}