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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::{Buffer, BufferError};
impl Buffer {
/// Appends a single byte to the buffer, automatically resizing if necessary.
///
/// This method adds a `u8` value to the end of the buffer.
/// If the buffer is at capacity, it attempts to reserve additional space
/// before inserting the value.
///
/// # Arguments
///
/// * `value` - A value that can be converted into a `u8`
///
/// # Errors
///
/// * `BufferError::Overflow` - If incrementing the length would overflow `usize`
/// * `BufferError` - If memory allocation fails during resize
///
/// # Examples
///
/// ```
/// # use ps_buffer::{Buffer, BufferError};
/// let mut buffer = Buffer::new();
/// buffer.push(42)?;
/// assert_eq!(buffer.slice(..), &[42]);
/// buffer.push(65)?;
/// assert_eq!(buffer.slice(..), &[42, 65]);
/// # Ok::<(), BufferError>(())
/// ```
pub fn push(&mut self, value: impl Into<u8>) -> Result<&mut Self, BufferError> {
if self.len() >= self.capacity() {
self.reserve(1)?;
}
let index = self.len();
let value = value.into();
self.length += 1;
self[index] = value;
Ok(self)
}
}
#[cfg(test)]
mod tests {
use ps_alloc::AllocationError;
use crate::{Buffer, BufferError};
#[test]
fn push_digits() -> Result<(), BufferError> {
let mut buffer = Buffer::new();
for i in 0..10 {
buffer.push(b'0' + i)?;
}
assert_eq!(buffer.slice(..), b"0123456789");
assert_eq!(buffer.len(), 10);
assert!(buffer.capacity() >= 10);
Ok(())
}
#[test]
fn push_values() -> Result<(), BufferError> {
let mut buffer = Buffer::new();
buffer.push(65)?;
buffer.push(66)?;
assert_eq!(buffer.slice(..), &[65, 66]);
assert_eq!(buffer.len(), 2);
Ok(())
}
#[test]
fn push_at_capacity() -> Result<(), BufferError> {
// Create a buffer with exact capacity
let mut buffer = Buffer::with_capacity(2)?;
buffer.push(1)?;
buffer.push(2)?;
// Push one more to trigger resize
buffer.push(3)?;
assert_eq!(buffer.slice(..), &[1, 2, 3]);
assert_eq!(buffer.len(), 3);
assert!(buffer.capacity() >= 3);
Ok(())
}
#[test]
fn push_empty() -> Result<(), BufferError> {
let mut buffer = Buffer::new();
buffer.push(0)?;
assert_eq!(buffer.slice(..), &[0]);
assert_eq!(buffer.len(), 1);
Ok(())
}
#[test]
fn push_overflow() {
let mut buffer = Buffer::new();
buffer.length = usize::MAX;
let result = buffer.push(0);
assert!(
matches!(
result,
Err(BufferError::AllocationError(AllocationError::OutOfMemory))
),
"Overflowing the Buffer did not return AllocationError::OutOfMemory."
);
}
}