1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// This file is part of copy-stack-vec.
// SPDX-License-Identifier: MIT OR Apache-2.0
// Crate imports
use crate::{error::Error, vec::CopyStackVec};
impl<T: Copy, const N: usize> Extend<T> for CopyStackVec<T, N> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let remaining = N - self.len;
if remaining == 0 {
return;
}
for item in iter.into_iter().take(remaining) {
self.buf[self.len] = item;
self.len += 1;
}
}
}
impl<T: Copy, const N: usize> CopyStackVec<T, N> {
/// Extends from `src` if it fits; otherwise no-op and returns [`Error::Full`].
#[inline]
pub fn extend_from_slice(&mut self, src: &[T]) -> Result<(), Error> {
let avail = N - self.len;
if src.len() > avail {
return Err(Error::Full);
}
let len = self.len;
self.buf[len..len + src.len()].copy_from_slice(src);
self.len = len + src.len();
Ok(())
}
/// Copies as many elements from `src` as will fit and returns the count copied.
#[inline]
#[must_use]
pub fn extend_from_slice_truncated(&mut self, src: &[T]) -> usize {
let len = self.len;
let avail = N - len;
let take = avail.min(src.len());
self.buf[len..len + take].copy_from_slice(&src[..take]);
self.len = len + take;
take
}
}
impl<T: Copy + Default, const N: usize> CopyStackVec<T, N> {
/// Tries to extend `self` from an iterator **without truncation**.
///
/// Semantics:
/// - All-or-nothing:
/// - If the iterator yields at most `spare_capacity()` items, they are
/// appended in order and `Ok(())` is returned.
/// - If it yields more than `spare_capacity()`, this returns `Err(Error::Full)`
/// and `self` is left unchanged.
/// - The source iterator may be partially consumed on error; no elements
/// are written into `self` unless the whole extend succeeds.
#[inline]
pub fn try_extend_from_iter<I: IntoIterator<Item = T>>(
&mut self,
iter: I,
) -> Result<(), Error> {
let spare = N - self.len;
// Temporary buffer to ensure `self` is unchanged on error.
let mut tmp: CopyStackVec<T, N> = CopyStackVec::default();
for item in iter {
if tmp.len() == spare {
return Err(Error::Full);
}
// tmp.len() < spare <= N so this cannot overflow tmp; but if it ever
// did, we just propagate the error instead of panicking.
tmp.push(item)?;
}
// Now we know everything fits into `self`.
self.extend_from_slice(tmp.as_slice())
}
}