1use std::ops::Deref;
4use std::ops::DerefMut;
5
6use bytes::Buf;
7use bytes::BytesMut;
8use serde_v8::JsBuffer;
9use serde_v8::V8Slice;
10
11#[derive(Debug)]
20pub struct BufView {
21 inner: BufViewInner,
22 cursor: usize,
23}
24
25#[derive(Debug)]
26enum BufViewInner {
27 Empty,
28 Bytes(bytes::Bytes),
29 JsBuffer(V8Slice<u8>),
30}
31
32impl BufView {
33 const fn from_inner(inner: BufViewInner) -> Self {
34 Self { inner, cursor: 0 }
35 }
36
37 pub const fn empty() -> Self {
38 Self::from_inner(BufViewInner::Empty)
39 }
40
41 pub fn len(&self) -> usize {
44 match &self.inner {
45 BufViewInner::Empty => 0,
46 BufViewInner::Bytes(bytes) => bytes.len() - self.cursor,
47 BufViewInner::JsBuffer(js_buf) => js_buf.len() - self.cursor,
48 }
49 }
50
51 pub fn is_empty(&self) -> bool {
53 self.len() == 0
54 }
55
56 pub fn advance_cursor(&mut self, n: usize) {
58 assert!(self.len() >= n);
59 self.cursor += n;
60 }
61
62 pub fn reset_cursor(&mut self) -> usize {
65 let old = self.cursor;
66 self.cursor = 0;
67 old
68 }
69
70 pub fn truncate(&mut self, size: usize) {
73 match &mut self.inner {
74 BufViewInner::Empty => {}
75 BufViewInner::Bytes(bytes) => bytes.truncate(size + self.cursor),
76 BufViewInner::JsBuffer(buffer) => buffer.truncate(size + self.cursor),
77 }
78 }
79
80 pub fn split_off(&mut self, at: usize) -> Self {
83 let at = at + self.cursor;
84 assert!(at <= self.len());
85 let other = match &mut self.inner {
86 BufViewInner::Empty => BufViewInner::Empty,
87 BufViewInner::Bytes(bytes) => BufViewInner::Bytes(bytes.split_off(at)),
88 BufViewInner::JsBuffer(buffer) => {
89 BufViewInner::JsBuffer(buffer.split_off(at))
90 }
91 };
92 Self {
93 inner: other,
94 cursor: 0,
95 }
96 }
97
98 pub fn split_to(&mut self, at: usize) -> Self {
101 assert!(at <= self.len());
102 let at = at + self.cursor;
103 let other = match &mut self.inner {
104 BufViewInner::Empty => BufViewInner::Empty,
105 BufViewInner::Bytes(bytes) => BufViewInner::Bytes(bytes.split_to(at)),
106 BufViewInner::JsBuffer(buffer) => {
107 BufViewInner::JsBuffer(buffer.split_to(at))
108 }
109 };
110 let cursor = std::mem::take(&mut self.cursor);
111 Self {
112 inner: other,
113 cursor,
114 }
115 }
116}
117
118impl Buf for BufView {
119 fn remaining(&self) -> usize {
120 self.len()
121 }
122
123 fn chunk(&self) -> &[u8] {
124 self.deref()
125 }
126
127 fn advance(&mut self, cnt: usize) {
128 self.advance_cursor(cnt)
129 }
130}
131
132impl Deref for BufView {
133 type Target = [u8];
134
135 fn deref(&self) -> &[u8] {
136 let buf = match &self.inner {
137 BufViewInner::Empty => &[],
138 BufViewInner::Bytes(bytes) => bytes.deref(),
139 BufViewInner::JsBuffer(js_buf) => js_buf.deref(),
140 };
141 &buf[self.cursor..]
142 }
143}
144
145impl AsRef<[u8]> for BufView {
146 fn as_ref(&self) -> &[u8] {
147 self.deref()
148 }
149}
150
151impl From<JsBuffer> for BufView {
152 fn from(buf: JsBuffer) -> Self {
153 Self::from_inner(BufViewInner::JsBuffer(buf.into_parts()))
154 }
155}
156
157impl From<Vec<u8>> for BufView {
158 fn from(vec: Vec<u8>) -> Self {
159 Self::from_inner(BufViewInner::Bytes(vec.into()))
160 }
161}
162
163impl From<Box<[u8]>> for BufView {
164 fn from(data: Box<[u8]>) -> Self {
165 Self::from_inner(BufViewInner::Bytes(data.into()))
166 }
167}
168
169impl From<bytes::Bytes> for BufView {
170 fn from(buf: bytes::Bytes) -> Self {
171 Self::from_inner(BufViewInner::Bytes(buf))
172 }
173}
174
175#[derive(Debug)]
186pub struct BufMutView {
187 inner: BufMutViewInner,
188 cursor: usize,
189}
190
191#[derive(Debug)]
192enum BufMutViewInner {
193 JsBuffer(V8Slice<u8>),
194 Bytes(BytesMut),
195}
196
197impl Default for BufMutView {
198 fn default() -> Self {
199 BufMutView {
200 inner: BufMutViewInner::Bytes(BytesMut::default()),
201 cursor: 0,
202 }
203 }
204}
205
206impl BufMutView {
207 fn from_inner(inner: BufMutViewInner) -> Self {
208 Self { inner, cursor: 0 }
209 }
210
211 pub fn new(len: usize) -> Self {
212 let bytes = BytesMut::zeroed(len);
213 Self::from_inner(BufMutViewInner::Bytes(bytes))
214 }
215
216 pub fn len(&self) -> usize {
219 match &self.inner {
220 BufMutViewInner::JsBuffer(js_buf) => js_buf.len() - self.cursor,
221 BufMutViewInner::Bytes(bytes) => bytes.len() - self.cursor,
222 }
223 }
224
225 pub fn is_empty(&self) -> bool {
227 self.len() == 0
228 }
229
230 pub fn advance_cursor(&mut self, n: usize) {
232 assert!(self.len() >= n);
233 self.cursor += n;
234 }
235
236 pub fn reset_cursor(&mut self) -> usize {
239 let old = self.cursor;
240 self.cursor = 0;
241 old
242 }
243
244 pub fn into_view(self) -> BufView {
246 let inner = match self.inner {
247 BufMutViewInner::JsBuffer(js_buf) => BufViewInner::JsBuffer(js_buf),
248 BufMutViewInner::Bytes(bytes) => BufViewInner::Bytes(bytes.into()),
249 };
250 BufView {
251 inner,
252 cursor: self.cursor,
253 }
254 }
255
256 pub fn maybe_unwrap_bytes(self) -> Result<BytesMut, Self> {
259 match self.inner {
260 BufMutViewInner::JsBuffer(_) => Err(self),
261 BufMutViewInner::Bytes(bytes) => Ok(bytes),
262 }
263 }
264
265 #[must_use = "The result of this method should be tested"]
268 #[deprecated = "API will be replaced in the future"]
269 #[doc(hidden)]
270 pub fn maybe_resize(
271 &mut self,
272 target_size: usize,
273 maximum_increment: usize,
274 ) -> Option<usize> {
275 match &mut self.inner {
276 BufMutViewInner::Bytes(bytes) => {
277 use std::cmp::Ordering::*;
278 let len = bytes.len();
279 let target_size = target_size + self.cursor;
280 match target_size.cmp(&len) {
281 Greater => {
282 bytes
283 .resize(std::cmp::min(target_size, len + maximum_increment), 0);
284 }
285 Less => {
286 bytes.truncate(target_size);
287 }
288 Equal => {}
289 }
290 Some(bytes.len())
291 }
292 _ => None,
293 }
294 }
295
296 #[must_use = "The result of this method should be tested"]
299 #[deprecated = "API will be replaced in the future"]
300 #[doc(hidden)]
301 pub fn maybe_grow(&mut self, target_size: usize) -> Option<usize> {
302 match &mut self.inner {
303 BufMutViewInner::Bytes(bytes) => {
304 let len = bytes.len();
305 let target_size = target_size + self.cursor;
306 if target_size > len {
307 bytes.resize(target_size, 0);
308 }
309 Some(bytes.len())
310 }
311 _ => None,
312 }
313 }
314
315 pub fn truncate(&mut self, size: usize) {
318 match &mut self.inner {
319 BufMutViewInner::Bytes(bytes) => bytes.truncate(size + self.cursor),
320 BufMutViewInner::JsBuffer(buffer) => buffer.truncate(size + self.cursor),
321 }
322 self.cursor = std::cmp::min(self.cursor, self.len());
323 }
324
325 pub fn split_off(&mut self, at: usize) -> Self {
328 let at = at + self.cursor;
329 assert!(at <= self.len());
330 let other = match &mut self.inner {
331 BufMutViewInner::Bytes(bytes) => {
332 BufMutViewInner::Bytes(bytes.split_off(at))
333 }
334 BufMutViewInner::JsBuffer(buffer) => {
335 BufMutViewInner::JsBuffer(buffer.split_off(at))
336 }
337 };
338 Self {
339 inner: other,
340 cursor: 0,
341 }
342 }
343
344 pub fn split_to(&mut self, at: usize) -> Self {
347 assert!(at <= self.len());
348 let at = at + self.cursor;
349 let other = match &mut self.inner {
350 BufMutViewInner::Bytes(bytes) => {
351 BufMutViewInner::Bytes(bytes.split_to(at))
352 }
353 BufMutViewInner::JsBuffer(buffer) => {
354 BufMutViewInner::JsBuffer(buffer.split_to(at))
355 }
356 };
357 let cursor = std::mem::take(&mut self.cursor);
358 Self {
359 inner: other,
360 cursor,
361 }
362 }
363}
364
365impl Buf for BufMutView {
366 fn remaining(&self) -> usize {
367 self.len()
368 }
369
370 fn chunk(&self) -> &[u8] {
371 self.deref()
372 }
373
374 fn advance(&mut self, cnt: usize) {
375 self.advance_cursor(cnt)
376 }
377}
378
379impl Deref for BufMutView {
380 type Target = [u8];
381
382 fn deref(&self) -> &[u8] {
383 let buf = match &self.inner {
384 BufMutViewInner::JsBuffer(js_buf) => js_buf.deref(),
385 BufMutViewInner::Bytes(vec) => vec.deref(),
386 };
387 &buf[self.cursor..]
388 }
389}
390
391impl DerefMut for BufMutView {
392 fn deref_mut(&mut self) -> &mut [u8] {
393 let buf = match &mut self.inner {
394 BufMutViewInner::JsBuffer(js_buf) => js_buf.deref_mut(),
395 BufMutViewInner::Bytes(vec) => vec.deref_mut(),
396 };
397 &mut buf[self.cursor..]
398 }
399}
400
401impl AsRef<[u8]> for BufMutView {
402 fn as_ref(&self) -> &[u8] {
403 self.deref()
404 }
405}
406
407impl AsMut<[u8]> for BufMutView {
408 fn as_mut(&mut self) -> &mut [u8] {
409 self.deref_mut()
410 }
411}
412
413impl From<JsBuffer> for BufMutView {
414 fn from(buf: JsBuffer) -> Self {
415 Self::from_inner(BufMutViewInner::JsBuffer(buf.into_parts()))
416 }
417}
418
419impl From<BytesMut> for BufMutView {
420 fn from(buf: BytesMut) -> Self {
421 Self::from_inner(BufMutViewInner::Bytes(buf))
422 }
423}
424
425#[cfg(test)]
426mod tests {
427 use super::*;
428
429 #[test]
430 pub fn bufview_read_and_truncate() {
431 let mut buf = BufView::from(vec![1, 2, 3, 4]);
432 assert_eq!(4, buf.len());
433 assert_eq!(0, buf.cursor);
434 assert_eq!(1, buf.get_u8());
435 assert_eq!(3, buf.len());
436 buf.truncate(2);
438 assert_eq!(2, buf.len());
439 assert_eq!(2, buf.get_u8());
440 assert_eq!(1, buf.len());
441
442 buf.reset_cursor();
443 assert_eq!(3, buf.len());
444 }
445
446 #[test]
447 pub fn bufview_split() {
448 let mut buf = BufView::from(Vec::from_iter(0..100));
449 assert_eq!(100, buf.len());
450 buf.advance_cursor(25);
451 assert_eq!(75, buf.len());
452 let mut other = buf.split_off(10);
453 assert_eq!(25, buf.cursor);
454 assert_eq!(10, buf.len());
455 assert_eq!(65, other.len());
456
457 let other2 = other.split_to(20);
458 assert_eq!(20, other2.len());
459 assert_eq!(45, other.len());
460
461 assert_eq!(100, buf.cursor + buf.len() + other.len() + other2.len());
462 buf.reset_cursor();
463 assert_eq!(100, buf.cursor + buf.len() + other.len() + other2.len());
464 }
465
466 #[test]
467 pub fn bufmutview_read_and_truncate() {
468 let mut buf = BufMutView::from(BytesMut::from([1, 2, 3, 4].as_slice()));
469 assert_eq!(4, buf.len());
470 assert_eq!(0, buf.cursor);
471 assert_eq!(1, buf.get_u8());
472 assert_eq!(3, buf.len());
473 buf.truncate(2);
475 assert_eq!(2, buf.len());
476 assert_eq!(2, buf.get_u8());
477 assert_eq!(1, buf.len());
478
479 buf.reset_cursor();
480 assert_eq!(3, buf.len());
481 }
482
483 #[test]
484 pub fn bufmutview_split() {
485 let mut buf =
486 BufMutView::from(BytesMut::from(Vec::from_iter(0..100).as_slice()));
487 assert_eq!(100, buf.len());
488 buf.advance_cursor(25);
489 assert_eq!(75, buf.len());
490 let mut other = buf.split_off(10);
491 assert_eq!(25, buf.cursor);
492 assert_eq!(10, buf.len());
493 assert_eq!(65, other.len());
494
495 let other2 = other.split_to(20);
496 assert_eq!(20, other2.len());
497 assert_eq!(45, other.len());
498
499 assert_eq!(100, buf.cursor + buf.len() + other.len() + other2.len());
500 buf.reset_cursor();
501 assert_eq!(100, buf.cursor + buf.len() + other.len() + other2.len());
502 }
503
504 #[test]
505 #[allow(deprecated, reason = "test code")]
506 fn bufmutview_resize() {
507 let new =
508 || BufMutView::from(BytesMut::from(Vec::from_iter(0..100).as_slice()));
509 let mut buf = new();
510 assert_eq!(100, buf.len());
511 buf.maybe_resize(200, 10).unwrap();
512 assert_eq!(110, buf.len());
513
514 let mut buf = new();
515 assert_eq!(100, buf.len());
516 buf.maybe_resize(200, 100).unwrap();
517 assert_eq!(200, buf.len());
518
519 let mut buf = new();
520 assert_eq!(100, buf.len());
521 buf.maybe_resize(200, 1000).unwrap();
522 assert_eq!(200, buf.len());
523
524 let mut buf = new();
525 buf.advance_cursor(50);
526 assert_eq!(50, buf.len());
527 buf.maybe_resize(100, 100).unwrap();
528 assert_eq!(100, buf.len());
529 buf.reset_cursor();
530 assert_eq!(150, buf.len());
531 }
532
533 #[test]
534 #[allow(deprecated, reason = "test code")]
535 fn bufmutview_grow() {
536 let new =
537 || BufMutView::from(BytesMut::from(Vec::from_iter(0..100).as_slice()));
538 let mut buf = new();
539 assert_eq!(100, buf.len());
540 buf.maybe_grow(200).unwrap();
541 assert_eq!(200, buf.len());
542
543 let mut buf = new();
544 buf.advance_cursor(50);
545 assert_eq!(50, buf.len());
546 buf.maybe_grow(100).unwrap();
547 assert_eq!(100, buf.len());
548 buf.reset_cursor();
549 assert_eq!(150, buf.len());
550 }
551}