1#![doc=include_str!("../README.md")]
2#![cfg_attr(not(feature="std"), no_std)]
3#![warn(missing_docs)]
4
5mod decode;
6
7#[cfg(feature="maypanic")]
8mod maypanic;
9
10use core::ops::Add;
11#[cfg(feature="std")]
12use std::{error::Error, fmt::Display};
13
14use bytes::*;
15
16pub use decode::{Decode, DecodeEndian};
17
18#[cfg(feature="maypanic")]
19pub use maypanic::ReaderMayPanic;
20
21pub struct Reader {
23 index: usize,
24 inner: Bytes,
25}
26
27impl Reader {
28 pub fn new<T: Into<Bytes>>(bytes: T) -> Self {
32 Self {
33 index: 0,
34 inner: bytes.into(),
35 }
36 }
37
38 #[inline]
39 fn increment(&mut self, amt: usize) {
40 self.index = self.index.add(amt).min(self.inner.len())
41 }
42
43 #[inline]
45 pub fn remaining(&self) -> usize {
46 self.inner.len().saturating_sub(self.index)
47 }
48
49 #[inline]
51 pub fn at_least(&self, len: usize) -> bool {
52 self.remaining() >= len
53 }
54
55 #[inline]
57 pub fn consumed(&self) -> usize {
58 self.index
59 }
60
61 pub fn skip(&mut self, amt: usize) {
63 self.increment(amt)
64 }
65
66 pub fn peek(&self, val: u8) -> bool {
68 if !self.at_least(1) { return false; }
69 self.inner[self.index + 1] == val
70 }
71
72 pub fn read_to_end(self) -> Bytes {
78 if self.index == self.inner.len() {
79 return Bytes::new()
80 }
81
82 self.inner.slice(self.index..)
83 }
84
85 pub fn subreader(&mut self, len: usize) -> Result<Self, EndOfInput> {
88 if len == 0 { return Err(EndOfInput); }
89 Ok(Self::new(self.read_bytes(len)?))
90 }
91
92 pub fn read_byte(&mut self) -> Result<u8, EndOfInput> {
94 if !self.at_least(1) { return Err(EndOfInput); }
95 let r = self.inner[self.index];
96 self.increment(1);
97 return Ok(r);
98 }
99
100 pub fn read_bytes(&mut self, len: usize) -> Result<Bytes, EndOfInput> {
102 if !self.at_least(len) { return Err(EndOfInput); }
103 let old_idx = self.index;
104 self.increment(len);
105 Ok(self.inner.slice(old_idx..old_idx+len))
106 }
107
108 pub fn read_slice(&mut self, len: usize) -> Result<&[u8], EndOfInput> {
111 if !self.at_least(len) { return Err(EndOfInput); }
112 let old_idx = self.index;
113 self.increment(len);
114 Ok(&self.inner[old_idx..old_idx+len])
115 }
116
117 pub fn read_array<const N: usize>(&mut self) -> Result<[u8; N], EndOfInput> {
119 let slice = self.read_slice(N)?;
120 let mut array = [0u8; N];
121 array.copy_from_slice(slice);
122 Ok(array)
123 }
124
125 pub fn read<T: Decode>(&mut self) -> Result<T, EndOfInput> {
127 T::decode(self)
128 }
129}
130
131impl AsMut<Reader> for Reader {
132 #[inline(always)]
133 fn as_mut(&mut self) -> &mut Reader {
134 self
135 }
136}
137
138#[cfg(feature="std")]
139impl std::io::Read for Reader {
140 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
141 let amt = self.remaining().min(buf.len());
142 if amt == 0 { return Ok(0) }
143 buf[..amt].copy_from_slice(self.read_slice(amt).unwrap());
144 Ok(0)
145 }
146}
147
148impl From<Bytes> for Reader {
149 #[inline]
150 fn from(value: Bytes) -> Self {
151 Self {
152 index: 0,
153 inner: value,
154 }
155 }
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
160pub struct EndOfInput;
161
162#[cfg(feature="std")]
163impl Display for EndOfInput {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 f.write_str("end of input")
166 }
167}
168
169#[cfg(feature="std")]
170impl Error for EndOfInput {}
171
172#[test]
173fn static_slice_test() {
174 let slice: &'static [u8; 20] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
175 let bytes = Bytes::from_static(slice);
176
177 let mut reader = Reader::new(bytes.clone());
178 assert_eq!(slice, &*reader.read_bytes(20).unwrap());
179
180 let mut reader = Reader::new(bytes.clone());
181 assert_eq!(slice, reader.read_slice(20).unwrap());
182
183 let mut reader = Reader::new(bytes.clone());
184 assert_eq!(slice, &reader.read_array::<20>().unwrap());
185
186 let mut reader = Reader::new(bytes.clone());
187 assert_eq!(&[1,2,3,4,5], &*reader.read_bytes(5).unwrap());
188 assert_eq!(&[6,7,8,9,10], reader.read_slice(5).unwrap());
189 assert_eq!(&[11,12,13,14,15], &reader.read_array::<5>().unwrap());
190 assert_eq!(16, reader.read_byte().unwrap());
191
192 assert_eq!(reader.consumed(), 16);
193 assert_eq!(reader.remaining(), 4);
194 assert!(reader.at_least(4));
195}