jam_std_common/util/
bytes_cursor.rs1use bytes::{Buf, Bytes};
2use codec::{Decode, Input};
3
4pub struct BytesCursor {
10 bytes: Bytes,
11 position: usize,
12}
13
14impl BytesCursor {
15 pub fn is_empty(&self) -> bool {
17 self.position == self.bytes.len()
18 }
19
20 pub fn infallible_remaining_len(&self) -> usize {
25 self.bytes.len() - self.position
26 }
27
28 fn align(&mut self) {
29 self.bytes.advance(self.position);
30 self.position = 0;
31 }
32
33 pub fn remaining(&mut self) -> &Bytes {
37 self.align();
38 &self.bytes
39 }
40
41 pub fn read_bytes(&mut self, len: usize) -> Result<Bytes, codec::Error> {
46 self.align();
47 if len > self.bytes.len() {
48 return Err("Not enough data".into())
49 }
50 Ok(self.bytes.split_to(len))
51 }
52
53 pub fn decode_all<T: Decode>(&mut self) -> Result<T, codec::Error> {
55 let value = T::decode(self)?;
56 if !self.is_empty() {
57 return Err("Extraneous bytes".into())
58 }
59 Ok(value)
60 }
61}
62
63impl Input for BytesCursor {
64 fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
65 Ok(Some(self.infallible_remaining_len()))
66 }
67
68 fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
69 if into.len() > self.infallible_remaining_len() {
70 return Err("Not enough data".into())
71 }
72 into.copy_from_slice(&self.bytes[self.position..self.position + into.len()]);
73 self.position += into.len();
74 Ok(())
75 }
76
77 fn scale_internal_decode_bytes(&mut self) -> Result<Bytes, codec::Error> {
78 let length = <codec::Compact<u32>>::decode(self)?.0 as usize;
79 self.read_bytes(length)
80 }
81}
82
83impl From<Bytes> for BytesCursor {
84 fn from(bytes: Bytes) -> Self {
85 Self { bytes, position: 0 }
86 }
87}
88
89impl From<Vec<u8>> for BytesCursor {
90 fn from(vec: Vec<u8>) -> Self {
91 Bytes::from(vec).into()
92 }
93}
94
95unsafe impl castaway::LifetimeFree for BytesCursor {}