oxihuman_core/
cursor_writer.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
7#[derive(Debug, Clone)]
8pub struct CursorWriter {
9 buffer: Vec<u8>,
10 position: usize,
11}
12
13impl Default for CursorWriter {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19#[allow(dead_code)]
20impl CursorWriter {
21 pub fn new() -> Self {
22 Self {
23 buffer: Vec::new(),
24 position: 0,
25 }
26 }
27
28 pub fn with_capacity(cap: usize) -> Self {
29 Self {
30 buffer: Vec::with_capacity(cap),
31 position: 0,
32 }
33 }
34
35 pub fn write_u8(&mut self, v: u8) {
36 self.ensure_capacity(1);
37 self.buffer[self.position] = v;
38 self.position += 1;
39 }
40
41 pub fn write_u16_le(&mut self, v: u16) {
42 let bytes = v.to_le_bytes();
43 self.ensure_capacity(2);
44 self.buffer[self.position] = bytes[0];
45 self.buffer[self.position + 1] = bytes[1];
46 self.position += 2;
47 }
48
49 pub fn write_u32_le(&mut self, v: u32) {
50 let bytes = v.to_le_bytes();
51 self.ensure_capacity(4);
52 self.buffer[self.position..self.position + 4].copy_from_slice(&bytes);
53 self.position += 4;
54 }
55
56 pub fn write_f32_le(&mut self, v: f32) {
57 self.write_u32_le(v.to_bits());
58 }
59
60 pub fn write_bytes(&mut self, data: &[u8]) {
61 self.ensure_capacity(data.len());
62 self.buffer[self.position..self.position + data.len()].copy_from_slice(data);
63 self.position += data.len();
64 }
65
66 fn ensure_capacity(&mut self, additional: usize) {
67 let needed = self.position + additional;
68 if needed > self.buffer.len() {
69 self.buffer.resize(needed, 0);
70 }
71 }
72
73 pub fn position(&self) -> usize {
74 self.position
75 }
76
77 pub fn set_position(&mut self, pos: usize) {
78 self.position = pos;
79 }
80
81 pub fn seek_start(&mut self) {
82 self.position = 0;
83 }
84
85 pub fn seek_end(&mut self) {
86 self.position = self.buffer.len();
87 }
88
89 pub fn len(&self) -> usize {
90 self.buffer.len()
91 }
92
93 pub fn is_empty(&self) -> bool {
94 self.buffer.is_empty()
95 }
96
97 pub fn as_bytes(&self) -> &[u8] {
98 &self.buffer
99 }
100
101 pub fn into_bytes(self) -> Vec<u8> {
102 self.buffer
103 }
104
105 pub fn clear(&mut self) {
106 self.buffer.clear();
107 self.position = 0;
108 }
109
110 pub fn remaining(&self) -> usize {
111 self.buffer.len().saturating_sub(self.position)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_new_empty() {
121 let cw = CursorWriter::new();
122 assert!(cw.is_empty());
123 assert_eq!(cw.position(), 0);
124 }
125
126 #[test]
127 fn test_write_u8() {
128 let mut cw = CursorWriter::new();
129 cw.write_u8(0xAB);
130 assert_eq!(cw.as_bytes(), &[0xAB]);
131 assert_eq!(cw.position(), 1);
132 }
133
134 #[test]
135 fn test_write_u16_le() {
136 let mut cw = CursorWriter::new();
137 cw.write_u16_le(0x0102);
138 assert_eq!(cw.as_bytes(), &[0x02, 0x01]);
139 }
140
141 #[test]
142 fn test_write_u32_le() {
143 let mut cw = CursorWriter::new();
144 cw.write_u32_le(1);
145 assert_eq!(cw.as_bytes(), &[1, 0, 0, 0]);
146 }
147
148 #[test]
149 fn test_write_f32_le() {
150 let mut cw = CursorWriter::new();
151 let val: f32 = 1.0;
152 cw.write_f32_le(val);
153 let bits = u32::from_le_bytes([
154 cw.as_bytes()[0],
155 cw.as_bytes()[1],
156 cw.as_bytes()[2],
157 cw.as_bytes()[3],
158 ]);
159 assert!((f32::from_bits(bits) - val).abs() < f32::EPSILON);
160 }
161
162 #[test]
163 fn test_write_bytes() {
164 let mut cw = CursorWriter::new();
165 cw.write_bytes(&[1, 2, 3]);
166 assert_eq!(cw.as_bytes(), &[1, 2, 3]);
167 }
168
169 #[test]
170 fn test_seek() {
171 let mut cw = CursorWriter::new();
172 cw.write_bytes(&[1, 2, 3]);
173 cw.seek_start();
174 assert_eq!(cw.position(), 0);
175 cw.seek_end();
176 assert_eq!(cw.position(), 3);
177 }
178
179 #[test]
180 fn test_overwrite() {
181 let mut cw = CursorWriter::new();
182 cw.write_bytes(&[0, 0, 0]);
183 cw.set_position(1);
184 cw.write_u8(0xFF);
185 assert_eq!(cw.as_bytes(), &[0, 0xFF, 0]);
186 }
187
188 #[test]
189 fn test_clear() {
190 let mut cw = CursorWriter::new();
191 cw.write_u8(1);
192 cw.clear();
193 assert!(cw.is_empty());
194 assert_eq!(cw.position(), 0);
195 }
196
197 #[test]
198 fn test_remaining() {
199 let mut cw = CursorWriter::new();
200 cw.write_bytes(&[1, 2, 3, 4]);
201 cw.set_position(1);
202 assert_eq!(cw.remaining(), 3);
203 }
204}