rg_formats 0.1.2

Parsers and Serializers for various rhythm game formats.
Documentation
/// A struct for easier iteration over a series of bytes.
///
/// This provides general methods -- peek, prev, etc.
pub struct ByteIterator<'a> {
	buf: &'a [u8],
	index: usize,
}

impl ByteIterator<'_> {
	pub fn new(buf: &[u8]) -> ByteIterator {
		ByteIterator { buf, index: 0 }
	}

	/// Rewind the index by one.
	pub fn rewind(&mut self) {
		self.index -= 1;
	}

	#[allow(unused)]
	pub fn set_index(&mut self, new_index: usize) {
		self.index = new_index;
	}

	#[allow(unused)]
	pub fn is_eof(&self) -> bool {
		self.index >= self.buf.len()
	}

	/// Peek at the previous byte.
	pub fn prev(&self) -> Option<&u8> {
		self.buf.get(self.index - 1)
	}

	/// Read the byte at the current index. Increments the index.
	/// Returns none if at EOF.
	pub fn read(&mut self) -> Option<&u8> {
		let byte = self.buf.get(self.index);

		self.index += 1;

		byte
	}

	/// Looks at the current character under the cursor without incrementing the index.
	pub fn peek(&self) -> Option<&u8> {
		self.buf.get(self.index)
	}
}

/// Convenience macro for reading a value and breaking out of the loop
/// if we're at eof.
#[macro_export]
#[doc(hidden)]
// TODO: (BLOCKED) make this macro `pub(crate)` when supported.
// See <https://github.com/rust-lang/rust/issues/39412>
macro_rules! read {
	($b_iter: expr) => {{
		let v = *match $b_iter.read() {
			Some(byte) => byte,
			None => break,
		};

		v
	}};
}

/// We're in a scenario where we can't guarantee that this input is valid utf8, and
/// therefore cannot use a [`String`] here.
pub type ByteString = Box<[u8]>;