oxihuman_core/
output_buffer.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
7pub struct OutputBuffer {
8 data: Vec<u8>,
9 flush_count: u32,
10}
11
12#[allow(dead_code)]
13impl OutputBuffer {
14 pub fn new() -> Self {
15 Self {
16 data: Vec::new(),
17 flush_count: 0,
18 }
19 }
20 pub fn with_capacity(cap: usize) -> Self {
21 Self {
22 data: Vec::with_capacity(cap),
23 flush_count: 0,
24 }
25 }
26 pub fn write_bytes(&mut self, bytes: &[u8]) {
27 self.data.extend_from_slice(bytes);
28 }
29 pub fn write_str(&mut self, s: &str) {
30 self.data.extend_from_slice(s.as_bytes());
31 }
32 pub fn write_u8(&mut self, v: u8) {
33 self.data.push(v);
34 }
35 pub fn write_u32_le(&mut self, v: u32) {
36 self.data.extend_from_slice(&v.to_le_bytes());
37 }
38 pub fn flush(&mut self) -> Vec<u8> {
39 self.flush_count += 1;
40 std::mem::take(&mut self.data)
41 }
42 pub fn peek(&self) -> &[u8] {
43 &self.data
44 }
45 pub fn len(&self) -> usize {
46 self.data.len()
47 }
48 pub fn is_empty(&self) -> bool {
49 self.data.is_empty()
50 }
51 pub fn flush_count(&self) -> u32 {
52 self.flush_count
53 }
54 pub fn clear(&mut self) {
55 self.data.clear();
56 }
57 pub fn capacity(&self) -> usize {
58 self.data.capacity()
59 }
60 pub fn as_str_lossy(&self) -> std::borrow::Cow<'_, str> {
61 String::from_utf8_lossy(&self.data)
62 }
63}
64
65impl Default for OutputBuffer {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71#[allow(dead_code)]
72pub fn new_output_buffer() -> OutputBuffer {
73 OutputBuffer::new()
74}
75#[allow(dead_code)]
76pub fn ob_write_bytes(b: &mut OutputBuffer, bytes: &[u8]) {
77 b.write_bytes(bytes);
78}
79#[allow(dead_code)]
80pub fn ob_write_str(b: &mut OutputBuffer, s: &str) {
81 b.write_str(s);
82}
83#[allow(dead_code)]
84pub fn ob_write_u8(b: &mut OutputBuffer, v: u8) {
85 b.write_u8(v);
86}
87#[allow(dead_code)]
88pub fn ob_flush(b: &mut OutputBuffer) -> Vec<u8> {
89 b.flush()
90}
91#[allow(dead_code)]
92pub fn ob_peek(b: &OutputBuffer) -> &[u8] {
93 b.peek()
94}
95#[allow(dead_code)]
96pub fn ob_len(b: &OutputBuffer) -> usize {
97 b.len()
98}
99#[allow(dead_code)]
100pub fn ob_is_empty(b: &OutputBuffer) -> bool {
101 b.is_empty()
102}
103#[allow(dead_code)]
104pub fn ob_clear(b: &mut OutputBuffer) {
105 b.clear();
106}
107#[allow(dead_code)]
108pub fn ob_flush_count(b: &OutputBuffer) -> u32 {
109 b.flush_count()
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 #[test]
116 fn test_write_str_peek() {
117 let mut b = new_output_buffer();
118 ob_write_str(&mut b, "hello");
119 assert_eq!(ob_peek(&b), b"hello");
120 }
121 #[test]
122 fn test_write_bytes() {
123 let mut b = new_output_buffer();
124 ob_write_bytes(&mut b, &[1, 2, 3]);
125 assert_eq!(ob_len(&b), 3);
126 }
127 #[test]
128 fn test_flush_clears() {
129 let mut b = new_output_buffer();
130 ob_write_str(&mut b, "abc");
131 let out = ob_flush(&mut b);
132 assert_eq!(out, b"abc");
133 assert!(ob_is_empty(&b));
134 }
135 #[test]
136 fn test_flush_count() {
137 let mut b = new_output_buffer();
138 ob_flush(&mut b);
139 ob_flush(&mut b);
140 assert_eq!(ob_flush_count(&b), 2);
141 }
142 #[test]
143 fn test_write_u8() {
144 let mut b = new_output_buffer();
145 ob_write_u8(&mut b, 42);
146 assert_eq!(ob_peek(&b), &[42u8]);
147 }
148 #[test]
149 fn test_write_u32_le() {
150 let mut b = new_output_buffer();
151 b.write_u32_le(0x01020304);
152 assert_eq!(b.len(), 4);
153 assert_eq!(b.peek()[0], 0x04);
154 }
155 #[test]
156 fn test_clear() {
157 let mut b = new_output_buffer();
158 ob_write_str(&mut b, "data");
159 ob_clear(&mut b);
160 assert!(ob_is_empty(&b));
161 }
162 #[test]
163 fn test_is_empty_initially() {
164 let b = new_output_buffer();
165 assert!(ob_is_empty(&b));
166 }
167 #[test]
168 fn test_len_accumulates() {
169 let mut b = new_output_buffer();
170 ob_write_str(&mut b, "abc");
171 ob_write_str(&mut b, "de");
172 assert_eq!(ob_len(&b), 5);
173 }
174 #[test]
175 fn test_as_str_lossy() {
176 let mut b = new_output_buffer();
177 ob_write_str(&mut b, "rust");
178 let s = b.as_str_lossy();
179 assert_eq!(s.as_ref(), "rust");
180 }
181}