tz/utils/
types.rs
1use std::io::{Error, ErrorKind};
4
5#[derive(Debug, Eq, PartialEq)]
7pub struct Cursor<'a> {
8 remaining: &'a [u8],
10 read_count: usize,
12}
13
14impl<'a> Cursor<'a> {
15 pub fn new(remaining: &'a [u8]) -> Self {
17 Self { remaining, read_count: 0 }
18 }
19
20 pub fn remaining(&self) -> &'a [u8] {
22 self.remaining
23 }
24
25 pub fn is_empty(&self) -> bool {
27 self.remaining.is_empty()
28 }
29
30 pub fn read_exact(&mut self, count: usize) -> Result<&'a [u8], Error> {
32 match (self.remaining.get(..count), self.remaining.get(count..)) {
33 (Some(result), Some(remaining)) => {
34 self.remaining = remaining;
35 self.read_count += count;
36 Ok(result)
37 }
38 _ => Err(Error::from(ErrorKind::UnexpectedEof)),
39 }
40 }
41
42 pub fn read_tag(&mut self, tag: &[u8]) -> Result<(), Error> {
44 if self.read_exact(tag.len())? == tag {
45 Ok(())
46 } else {
47 Err(Error::from(ErrorKind::InvalidData))
48 }
49 }
50
51 pub fn read_optional_tag(&mut self, tag: &[u8]) -> Result<bool, Error> {
53 if self.remaining.starts_with(tag) {
54 self.read_exact(tag.len())?;
55 Ok(true)
56 } else {
57 Ok(false)
58 }
59 }
60
61 pub fn read_while<F: Fn(&u8) -> bool>(&mut self, f: F) -> Result<&'a [u8], Error> {
63 match self.remaining.iter().position(|x| !f(x)) {
64 None => self.read_exact(self.remaining.len()),
65 Some(position) => self.read_exact(position),
66 }
67 }
68
69 pub fn read_until<F: Fn(&u8) -> bool>(&mut self, f: F) -> Result<&'a [u8], Error> {
71 match self.remaining.iter().position(f) {
72 None => self.read_exact(self.remaining.len()),
73 Some(position) => self.read_exact(position),
74 }
75 }
76}